3 * implementation of safety algorithm's decisions
9 /*---------- polarity ----------*/
11 static PicInsn polarityinsn= { { 0x90 }, 0 };
13 #define OPONBIT_BYTE (polarityinsn.d[bytenum])
14 #define OPONBIT(body) do{ \
16 int bytenum, bitnum; \
21 bytenum= (bo + 3) / 7; \
22 bitnum= bytenum ? 6 - (bo + 3) % 7 : 3 - bo; \
28 int picinsn_polarity_testbit(const PicInsn *pi, const SegmentInfo *segi) {
30 return !!(OPONBIT_BYTE & bitv);
34 void actual_inversions_start(void) {
36 polarityinsn.l= (info_maxreverse + 4 + 6) / 7;
37 for (i=1; i<polarityinsn.l-1; i++)
38 polarityinsn.d[i] |= 0x80;
41 void actual_inversions_segment(Segment *seg) {
42 const SegmentInfo *segi= seg->i;
45 Byte *insnbyte= &OPONBIT_BYTE;
46 if (seg->seg_inverted) *insnbyte |= bitv;
47 else *insnbyte &= ~bitv;
51 void actual_inversions_done(void) {
52 serial_transmit(&polarityinsn);
55 /*---------- features ----------*/
57 static void feat_updated_cmd(FeaturesAddr *a, int ix, Nmra *n /*destroyed*/) {
58 assert(a->rn[ix].pi.l);
59 retransmit_relaxed_cancel(&a->rn[ix]);
60 retransmit_relaxed_queue(&a->rn[ix], n);
63 static void feat_updated_funcs(FeaturesAddr *a, int ix,
64 void (*enco)(Nmra *n, int addr, unsigned map),
67 if (!(a->all & thiscmd)) return;
68 enco(&n,a->addr,a->current);
69 feat_updated_cmd(a,ix,&n);
72 void features_updated(FeaturesAddr *a) {
73 /* idempotent; call this after updating a->current */
75 feat_updated_funcs(a,0, enco_nmra_funcs0to4, 0x0001f);
76 feat_updated_funcs(a,1, enco_nmra_funcs5to8, 0x001e0);
77 feat_updated_funcs(a,2, enco_nmra_funcs9to12, 0x01e00);
79 if (a->all & FEATS_SPEEDSTEP_BIT) {
81 enco_nmra_speed126(&n, a->addr,
82 a->current & FEATS_SPEEDSTEP_BIT
84 !!(a->all & FEATS_SPEEDSTEP_REVERSE));
85 feat_updated_cmd(a,3, &n);
89 void features_start_xmit(void) {
94 for (ai=0,ap=feataddrs; ai<n_feataddrs; ai++,ap++) {
96 for (ix=0; ix<FEATURESADDR_TRANSMITS; ix++) {
97 RetransmitRelaxedNode *rn= &a->rn[ix];
100 retransmit_relaxed_queue(rn,&n);