00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00059 #include <avr/io.h>
00060 #include <avr/signal.h>
00061 #include <avr/interrupt.h>
00062 #include <avr/pgmspace.h>
00063 #include <inttypes.h>
00064 #include <stdlib.h>
00065 #include <string.h>
00066 #include "net/link.h"
00067 #include "net/buffers.h"
00068 #include "net.h"
00069
00070
00071 #ifdef EIMSK
00072 # define ext_init() sbi(EICR, LNK_EXT_ISCx1)
00073 # define ext_enable() {EIFR = _BV(LNK_EXT_INT); sbi(EIMSK, LNK_EXT_INT);}
00074 # define ext_disable() cbi(EIMSK, LNK_EXT_INT)
00075 #else
00076 # define ext_init() sbi(MCUCR, LNK_EXT_ISCx1)
00077 # define ext_enable() {GIFR = _BV(LNK_EXT_INT); sbi(GIMSK, LNK_EXT_INT);}
00078 # define ext_disable() cbi(GIMSK, LNK_EXT_INT)
00079 #endif
00080
00081
00082 #ifndef UDR
00083 # define UDR UDR0
00084 # define USR UCSR0A
00085 # define UCR UCSR0B
00086 # define UBRR UBRR0
00087 # define RENAME_ISR
00088 #endif
00089
00091 enum recv_stat_e {
00092 RECV_STAT_FREE,
00093 RECV_STAT_RECEIVING,
00094 RECV_STAT_EXAMINE
00095 };
00096
00098 enum send_stat_e {
00099 SEND_STAT_IDLE,
00100 SEND_STAT_WAIT,
00101 SEND_STAT_SEND_DATA,
00102 SEND_STAT_INFORM
00103 };
00104
00106 struct receive_info_t {
00107 enum recv_stat_e status;
00108 uint16_t slots;
00109 uint16_t crc16;
00110 uint8_t pos;
00111 uint8_t buf[LNK_BUFFER_SIZE];
00112 };
00113
00115 struct send_info_t {
00116 enum send_stat_e status;
00117 uint16_t slot;
00118 uint8_t backlog;
00119 uint8_t backlog_add;
00120 net_buf_t data;
00121 };
00122
00123
00124 static struct send_info_t send;
00125 static struct receive_info_t receive;
00126 static struct lnk_err_t err;
00127
00129 #define POLY_CRC16 0x1021
00130
00137 #ifdef RENAME_ISR
00138 SIGNAL(SIG_UART0_RECV)
00139 #else
00140 SIGNAL(SIG_UART_RECV)
00141 #endif
00142 {
00143 uint8_t i, value;
00144
00145
00146 TCNT0 = LNK_ALPHA_TIME;
00147 receive.slots = 0;
00148
00149
00150 if ((USR & _BV(FE)) != 0) err.rx_fe++;
00151 value = UDR;
00152 if ((USR & _BV(DOR)) != 0) err.rx_ovr++;
00153
00154
00155
00156
00157
00158
00159 if (receive.status > RECV_STAT_RECEIVING) {
00160 err.rx_ovr++;
00161 return;
00162 }
00163 receive.status = RECV_STAT_RECEIVING;
00164
00165
00166 sei();
00167
00168
00169
00170 if (receive.pos < LNK_BUFFER_SIZE) receive.buf[receive.pos++] = value;
00171
00172
00173 if ((uint8_t)(receive.buf[0]+2) >= receive.pos) {
00174 receive.crc16 ^= ((uint16_t)value << 8);
00175 for (i=0; i<8; i++) {
00176 if (receive.crc16 & 0x8000)
00177 receive.crc16 = (receive.crc16 << 1) ^ POLY_CRC16;
00178 else
00179 receive.crc16 <<= 1;
00180 }
00181 }
00182 }
00183
00190 SIGNAL(SIG_OVERFLOW0)
00191 {
00192 TCNT0 += LNK_ALPHA_TIME;
00193 receive.slots++;
00194
00195
00196
00197 if (receive.slots == LNK_BETA_1) {
00198 if (receive.status == RECV_STAT_RECEIVING) {
00199 receive.status = RECV_STAT_EXAMINE;
00200 ext_enable();
00201 }
00202 }
00203
00204
00205 if (receive.slots >= send.slot) {
00206 cbi(TIMSK, TOIE0);
00207 ext_disable();
00208 cbi(UCR, RXEN);
00209 sbi(UCR, TXEN);
00210 cbi(LNK_SEND_PORT, LNK_SEND_PIN);
00211
00212 UDR = *send.data.data++;
00213 send.data.len--;
00214 send.status = SEND_STAT_SEND_DATA;
00215 send.slot = 0xffff;
00216 sbi(UCR, UDRIE);
00217 }
00218 }
00219
00226 SIGNAL(LNK_EXT_SIG)
00227 {
00228 ext_disable();
00229 TCNT0 = LNK_ALPHA_TIME;
00230 receive.slots = 0;
00231 send.slot = 0xffff;
00232 }
00233
00241 #ifdef RENAME_ISR
00242 SIGNAL(SIG_UART0_DATA)
00243 #else
00244 SIGNA(SIG_UART_DATA)
00245 #endif
00246 {
00247 if (send.data.len > 0) {
00248 UDR = *send.data.data++;
00249 send.data.len--;
00250 } else {
00251 cbi(UCR, UDRIE);
00252 }
00253 }
00254
00261 #ifdef RENAME_ISR
00262 SIGNAL(SIG_UART0_TRANS)
00263 #else
00264 SIGNAL(SIG_UART_TRANS)
00265 #endif
00266 {
00267 sbi(LNK_SEND_PORT, LNK_SEND_PIN);
00268 cbi(UCR, TXEN);
00269 sbi(UCR, RXEN);
00270 TCNT0 = LNK_ALPHA_TIME;
00271 receive.slots = 0;
00272 sbi(TIMSK, TOIE0);
00273 ext_enable();
00274 send.status = SEND_STAT_INFORM;
00275 }
00276
00277
00278
00279
00280
00281 extern uint8_t lnk_ind(uint8_t *buf, uint8_t len);
00282 extern void lnk_con(void);
00283
00289 void lnk_init(void)
00290 {
00291 UBRR = LNK_F_CLK/(LNK_BAUD_RATE*16l) - 1;
00292 sbi(LNK_SEND_PORT, LNK_SEND_PIN);
00293 sbi(LNK_SEND_DDR, LNK_SEND_PIN);
00294 UCR = _BV(RXCIE)|_BV(TXCIE)|_BV(RXEN);
00295
00296 send.slot = 0xffff;
00297 receive.crc16 = 0;
00298
00299 receive.slots = 0x8000;
00300 TCCR0 = LNK_ALPHA_PRESC;
00301 sbi(TIMSK, TOIE0);
00302
00303 ext_init();
00304 ext_enable();
00305 }
00306
00317 void lnk_process(void)
00318 {
00319
00320 cli();
00321 if (receive.slots > 0xa000) receive.slots = 0x3000;
00322 sei();
00323
00324
00325 cli();
00326 if ((send.status == SEND_STAT_WAIT) && (send.slot == 0xffff)) {
00327
00328 send.slot = LNK_BETA_2 + ((uint16_t)random() % (16*((uint16_t)send.backlog+1)));
00329 }
00330 sei();
00331
00332
00333 if (send.status == SEND_STAT_INFORM) {
00334
00335 if (send.backlog >= (uint8_t)(0xff-send.backlog_add))
00336 send.backlog = 0xff;
00337 else
00338 send.backlog += send.backlog_add;
00339
00340 lnk_con();
00341 send.status = SEND_STAT_IDLE;
00342 }
00343
00344
00345 if (receive.status == RECV_STAT_EXAMINE) {
00346 if (send.backlog > 0) send.backlog--;
00347
00348 if ((receive.pos == receive.buf[0]+4) &&
00349 (receive.crc16 == *((uint16_t*)(receive.buf+receive.pos-2)))) {
00350
00351 if (send.backlog >= (uint8_t)(0xff-receive.buf[1]))
00352 send.backlog = 0xff;
00353 else
00354 send.backlog += receive.buf[1];
00355
00356 lnk_ind(receive.buf+2, receive.buf[0]);
00357 } else {
00358 if (receive.pos != receive.buf[0]+4)
00359 err.rx_len++;
00360 else
00361 err.rx_crc++;
00362 }
00363
00364 receive.pos = 0;
00365 receive.crc16 = 0;
00366 receive.status = RECV_STAT_FREE;
00367 }
00368 }
00369
00383 int8_t lnk_requ(net_buf_t *buf, uint8_t backlog)
00384 {
00385 uint8_t len, *data, i;
00386 uint16_t crc;
00387
00388
00389 if (send.status != SEND_STAT_IDLE) return 0;
00390
00391
00392 len = buf_len(buf);
00393 buf_prep_char(buf, backlog);
00394 buf_prep_char(buf, len);
00395
00396
00397 len += 2;
00398 data = buf->data;
00399 crc = 0;
00400 while (len > 0) {
00401 len--;
00402 crc ^= ((uint16_t)(*data++) << 8);
00403 for (i=0; i<8; i++) {
00404 if (crc & 0x8000)
00405 crc = (crc << 1) ^ POLY_CRC16;
00406 else
00407 crc <<= 1;
00408 }
00409 }
00410 buf_app_int(buf, crc);
00411
00412
00413 send.data = *buf;
00414 send.backlog_add = backlog;
00415 send.slot = 0xffff;
00416 send.status = SEND_STAT_WAIT;
00417 return 1;
00418 }
00419
00426 uint8_t lnk_clear_to_send(void)
00427 {
00428 return send.status == SEND_STAT_IDLE;
00429 }
00430
00436 void lnk_get_error_stats(struct lnk_err_t *buf)
00437 {
00438 memcpy(buf, &err, sizeof(err));
00439 }