2 #ifndef _SOFT_ISO14543_3_6_
3 #define _SOFT_ISO14543_3_6_
5 //I kind of hate the person concocting this control field. On the other hand, it is probably the result of the work (I won't say collaboration) of a number of persons equal to the population of a small country.
6 typedef struct { //Control field, always the first byte
7 unsigned char ft:1; //Frame type: 0 - extended/poll; 1 - standard
8 unsigned char poll: 1; //Poll frame - 1; otherwise 0
9 //ft/poll are used in ack frames as follows: ack/busy 11, nack/nack+busy 00
10 unsigned char r: 1; //Repeat flag: 0 - repeated frame/ack frame; 1 - not repeated frame/poll frame
11 unsigned char ack: 1; //Ack frame - 0; otherwise 1
12 unsigned char priority: 2; //Priority: system/poll 0, urgent 2, normal 1, low 3
13 // if this is an ack frame: ack/nack 3, busy/nack+busy 0
14 unsigned char _: 2; //Padding, always 00
15 } iso14543_3_6_frame_ctrl; //1 byte
18 unsigned char at:1; //Destination address type: physical/individual - 0; group - 1
19 unsigned char hops:3; //Hop count
20 unsigned char eff:4; //Extended frame format: default 0, LTE-HEE extended address type 01xx
21 } iso14543_3_6_frame_ctrle; //1 byte
25 struct { //Physical address
26 unsigned char area:4; //Area
27 unsigned char line:4; //Line
28 unsigned char device; //Device
30 } iso14543_3_6_frame_address; //1 word
32 //XXX The following frame definitions are missing the checksum because that is generated and checked on the fly during rx/tx.
33 //"unsigned char checksum;" //xor all bytes of the frame, invert.
34 //Also, please note that where I'm talking about bytes, the iso norm talks about "octets".
36 //Structure of a iso14543-3-6 TP1 standard frame
38 iso14543_3_6_frame_address sa; //Source address
39 iso14543_3_6_frame_address da; //Destination address
40 struct aux { //Various flags
41 unsigned char at:1; //Destination address type: physical/individual - 0; group - 1
42 unsigned char hops:3; //Hop count
43 unsigned char len:4; //Payload length
45 unsigned char payload[15];
46 } iso14543_3_6_std_frame;
48 //Structure of a iso14543-3-6 TP1 extended frame
50 iso14543_3_6_frame_ctrle; //Extended control field (only present in -- you guessed it, extended frames)
51 iso14543_3_6_frame_address sa; //Source address
52 iso14543_3_6_frame_address da; //Destination address
53 unsigned char len; //Payload length (0xFF is an escape code)
54 unsigned char payload[255];
55 } iso14543_3_6_ext_frame;
57 //Structure of a iso14543-3-6 TP1 poll frame
59 iso14543_3_6_frame_address sa; //Source address
60 uint16_t da; //Poll group address
61 struct aux { //strange aux byte
62 unsigned char _:4; //Padding (0000)
63 unsigned char len:4; //Number of poll responses expected
65 } iso14543_3_6_poll_frame;
67 //Structure of a generic iso14543-3-6 TP1 frame
69 iso14543_3_6_frame_ctrl ctrl; //1 byte (if it's an ack sent w/o checksum)
71 iso14543_3_6_std_frame std; //5-20 byte (+1 checksum)
72 iso14543_3_6_ext_frame ext; //6-261 byte (+1 checksum)
73 iso14543_3_6_poll_frame poll; //5 byte (+1 checksum)
75 unsigned char checksum;
78 #endif//_SOFT_ISO14543_3_6_
80 ${modulevar("frame", "iso14543_3_6_frame", "BHHB255sB", set_action=modulevar("frame")+"_set_action")};
81 ${modulevar("extende_frame", None, "BBHHB255sB")};
83 void callback_set_${modulevar("extended_frame")}(uint16_t payload_offset, uint16_t alen, uint8_t* argbuf){
84 callback_set_${modulevar("frame")}(payload_offset, alen, argbuf);
87 void callback_get_${modulevar("extended_frame")}(uint16_t payload_offset, uint16_t alen, uint8_t* argbuf){
88 callback_set_${modulevar("frame")}(payload_offset, alen, argbuf);
91 volatile unsigned char ${modulevar("status")} = 0;
92 unsigned char* ${modulevar("endptr")} = 0;
94 void ${init_function()} (void){
95 DDR${member["tx"]["port"]} |= (1<<${member["tx"]["pin"]});
96 //set up pin change interrupt
99 //XXX This module uses pin change interrupts since the pulses it tries to detect are only 34µs long (@16MHz ~= 512 cycles)
100 //XXX This module uses one 16-bit timer
101 //The timer is clocked with a 16934400Hz system clock overflows every 588 cycles. A bit is over every 1764 cycles.
102 //The error of this timing is less than 1% compared to a 9600Bd reference.
104 //Returns 0 on success, other stuff when an error occurs.
105 char ${modulevar("frame")_send_next_bit(){
106 static unsigned char bit = 0;
107 static unsigned char data = 0;
108 static unsigned char *pos = 0;
115 ${modulevar("frame")}.checksum ^= data;
118 if(pos > ${modulevar("endptr")}){
119 if(pos > &(${modulevar("frame")}.checksum)){ //End of frame, checksum sent
120 pos = &(${modulevar("frame")}.ctrl);
123 }else{ //End of frame, send checksum
124 ${modulevar("frame")}.checksum ^= 0xFF; //Invert
125 pos = &(${modulevar("frame")}.checksum);
132 unsigned char nd = data << 1;
133 if(nd < data){ //msb set
134 // i.e. (data * 2) mod 256 < data
135 // unsigned char => 0 < data < 256
137 // data * 2 < data => false
139 // data * 2 - 256 == data + data - 256 < data - 1 < data
140 //send logic 1: leave the bus alone
143 //send logic 0: short the bus
144 port${member["tx"]["port"]} |= (1<<${member["tx"]["pin"]});
152 ISR(/*FIXME*/){ //Timer overflow @ 1/3 cycle
153 static unsigned char cnt = 0;
158 unsigned char state = ${modulevar("state")};
159 if(state >= 0){ //Data transfer in progress
160 ${modulevar("state")} = ${modulevar("frame")}_send_next_bit();
161 }else if(state < -33){
162 state--; //Decrement timeout before initiation of new bus action
165 PORT${member["tx"]["port"]} &= ~(1<<${member["tx"]["pin"]});
169 ISR(/*FIXME*/){ //PCInt
171 if(${modulevar("state") >= 0){ //Currently transmitting
172 if(!(${modulevar("state")}&1) && !!(/*input pin state*/)){ //If a 1 is on the wire although none was sent
173 //Collision! Idle for 50 cycles, retry.
174 ${modulevar("state")} = -33-50; //Prevent the transmission of any further bits
177 if(modulevar("state") == -33){ //Idle
178 //Somebody else is sending. Set a timeout for 53 cycles.
179 ${modulevar("state")} = -33-53; //Prevent the transmission a frame
185 //add pin change interrupt vector
187 void ${modulevar("frame")}_set_action (void){
188 iso14543_3_6_frame* f = &${modulevar("frame")};
192 if( !f->ctrl.ft ){ //Extended frame
193 ${modulevar("endptr")} = &(f->ext.len) + f->ext.len;
194 }else{ //Standard frame
195 ${modulevar("endptr")} = &(f->std.aux) + f->std.len;
198 ${modulevar("endptr")} = &(f->poll.aux);
201 ${modulevar("state")} = 2;