From 43a6184ab17d14620956d302e855cafa7332da7d Mon Sep 17 00:00:00 2001 From: ian Date: Tue, 11 Jan 2005 22:16:43 +0000 Subject: [PATCH] sort of before mangle things into nmra-packets.h --- hostside/encode.c | 116 ++++++++++++++++++++++++++++++++++++++++ hostside/hostside.h | 24 ++++++++- hostside/nmra-packets.h | 29 ++++++++++ hostside/nmra.c | 3 +- 4 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 hostside/encode.c create mode 100644 hostside/nmra-packets.h diff --git a/hostside/encode.c b/hostside/encode.c new file mode 100644 index 0000000..eb417bc --- /dev/null +++ b/hostside/encode.c @@ -0,0 +1,116 @@ +/**/ + +#include + +#include "hostside.h" + +#define XCONST(d) const Byte c[2]= { d }; XMIT; + +static Byte *addr(int addr, Byte *ap) { + /* encodes decoder address */ + assert(addr>0 && addr<=0x3ff); + if (addr < 0x3f) { + /* Short addresses: S9.2 B l.41 which is the same as RP9.2.1 C l.65 + * first sentence. */ + *--ap= addr; + } else { + /* Long addresses: RP9.2.1 C l.65-69. */ + *--ap= addr; + *--ap= (addr >> 8) | 0xc0; + } + return ap; +} + +#define ADDR Byte *c= addr(addr, p->d); +#define ENCD p->l= c - p->d; assert(p->l <= sizeof(p->d)); + +void enco_nmra_speed28(Nmra *p, int addr, int speed, int reverse) { + /* Baseline Speed and Direction, S9.2 B (for short addresses + * only), which is also identical to Multi-Function Decoder + * Speed and Direction RP9.2.1 C l.215- (defined for both + * addresses), so actually the address format and instruction + * format are independent. + */ + int adj; + ADDR; + + assert(speed>=0 && speed<=28); + *c++= 0x40 | (reverse ? 0 : 0x20); + if (speed) { + adj= speed + 3; + *c |= adj & 1 ? 0x10 : 0; + *c |= adj >> 1; + } + c++; + ENCD; +} + +void enco_nmra_estop1(Nmra *p, int addr) { + /* Baseline Speed and direction Forwards E-Stop(I) S9.2 B table l.56 */ + ADDR; + *c++= 0x71; + ENCD; +} + +void enco_nmra_estop(void) { + /* Baseline Broadcast stop Forwards(I) Emergency S9.2 B l.98- */ + XCONST(0x00, 0x71); +} +void enco_nmra_reset(void) { + /* Baseline Decoder Reset S9.2 B l.77- */ + XCONST(0x00, 0x00); +} +void enco_nmra_idle(void) { + /* Baseline Idle S9.2 B l.87- */ + XCONST(0xff, 0x00); +} + +void enco_nmra_speed126(int addr, int speed, int reverse) { + /* Advanced Operations 128 Speed Step Control + * (actually speeds 0..126) RP9.2.1 C l.200- */ + CMD(2); + ADDR; + assert(speed>=0 && speed<=126); + c[0]= 0x3f; + c[1]= (speed ? speed + 1 : 0) | (reverse ? 0 : 0x80); + ENCD; +} + +void enco_nmra_funcs0to4(unsigned bitmap) { + /* Function Group One RP9.2.1 C l.234- */ + CMD(1); + ADDR; + FUNCS; + c[0]= 0x80 | ((bitmap >> 1) & 0x0f) | ((bitmap << 4 & 0x10)); + ENCD; +} +void enco_nmra_funcs5to9(unsigned bitmap) { + /* Function Group Two RP9.2.1 C l.246- */ + CMD(1); + ADDR; + FUNCS; + c[0]= 0xa0 | ((bitmap >> 5) & 0x0f); + ENCD; +} +void enco_nmra_funcs9to12(unsigned bitmap) { + /* Function Group Two RP9.2.1 C l.246- */ + CMD(1); + ADDR; + FUNCS; + c[0]= 0xb0 | ((bitmap >> 9) & 0x0f); + ENCD; +} + +void enco_nmra_cv_write(int addr, int cv, Byte value) { + /* Configuration Variable Access Long Form RP9.2.1 C l.286- */ + int adj; + CMD(3); + ADDR; + assert(cv>=1 && cv<=1024); + adj= cv - 1; + c[0]= 0xec | (adj >> 8); + c[1]= adj; + c[2]= value; + ENCD; +} + diff --git a/hostside/hostside.h b/hostside/hostside.h index f3659bc..31a0775 100644 --- a/hostside/hostside.h +++ b/hostside/hostside.h @@ -8,10 +8,32 @@ typedef unsigned char Byte; #define COMMAND_ENCODED_MAX 16 #define NMRA_PACKET_MAX ((COMMAND_ENCODED_MAX*7 - 14) / 8) +typedef struct Nmra { + Byte d[NMRA_PACKET_MAX]; + int l; +} Nmra; + void xmit_nmra_raw(const Byte *with_csum, int length); -void xmit_nmra(const Byte *without_csum, int length); +void xmit_nmra_bytes(const Byte *without_csum, int length); +void xmit_nmra(const Nmra*); void xmit_command(const Byte *command, int length); +void enco_nmra_speed28(Nmra *p, int train, int speed, int reverse); +void enco_nmra_speed126(Nmra *p, int addr, int speed, int reverse); + /* 0<=speed<=28 or <=126; reverse: 0 forwards, non-0 backwards */ +void enco_nmra_funcs0to4(Nmra *p, unsigned bitmap); +void enco_nmra_funcs5to8(Nmra *p, unsigned bitmap); +void enco_nmra_funcs9to12(Nmra *p, unsigned bitmap); + /* bit 0 is FL aka F0; bits 1-12 are F1-F12; do not call with bits + * outside 0-12 set; bits in 0-12 but not relevant for the relevant + * command are ignored. */ +void enco_nmra_cv_write(Nmra *p, int addr, int cv, Byte value); + +void enco_nmra_idle(Nmra *p); +void enco_nmra_reset(Nmra *p); +void enco_nmra_estop(Nmra *p); +void enco_nmra_estop1(Nmra *p); + extern FILE *dump_stream; void dump(const char *what, const Byte *data, int length); void sysfatal(const char *m); diff --git a/hostside/nmra-packets.h b/hostside/nmra-packets.h new file mode 100644 index 0000000..42bf03f --- /dev/null +++ b/hostside/nmra-packets.h @@ -0,0 +1,29 @@ + + +NMRA(speed28, Aint(addr) Aint(speed) Aint(reverse), { + int adj; + + assert(speed>=0 && speed<=28); + *c++= 0x40 | (reverse ? 0 : 0x20); + if (speed) { + adj= speed + 3; + *c |= adj & 1 ? 0x10 : 0; + *c |= adj >> 1; + } + c++; +}); + +NMRA( + + + + /* Baseline Speed and Direction, S9.2 B (for short addresses + * only), which is also identical to Multi-Function Decoder + * Speed and Direction RP9.2.1 C l.215- (defined for both + * addresses), so actually the address format and instruction + * format are independent. + */ + ADDR; + + ENCD; +} diff --git a/hostside/nmra.c b/hostside/nmra.c index 51bd88f..606d715 100644 --- a/hostside/nmra.c +++ b/hostside/nmra.c @@ -48,7 +48,8 @@ void xmit_nmra_raw(const Byte *nmra_packet, int length) { xmit_command(encoded, encp - encoded); } -void xmit_nmra(const Byte *without_csum, int length) { +void xmit_nmra_bytes(const Byte *without_csum, int length) { + /* calculates checksum, S9.2 B l.63 */ Byte with_csum[NMRA_PACKET_MAX]; const Byte *in; Byte *out; -- 2.30.2