Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00039 #include <string.h>
00040 #include "radio.h"
00041 #include "transceiver.h"
00042 #include "ioutil.h"
00043 #include "timer.h"
00044 #include "prot_wuart.h"
00045
00046
00047
00049 #define PAYLD_SIZE (PROT_WUART_PAYLD_SIZE)
00050
00051 #define CRC_SIZE (sizeof(crc_t))
00052
00053 #define UART_FRAME_SIZE (PROT_WUART_HEADER_SIZE +\
00054 PAYLD_SIZE + CRC_SIZE )
00055
00056 #define PAYLD_START (PROT_WUART_HEADER_SIZE)
00057
00058 #define PAYLD_END (UART_FRAME_SIZE - CRC_SIZE)
00059
00060 #define NL "\n\r"
00061
00063 #define ESC_NONE (0)
00064
00066 #define ESC_TMO_1 (1)
00067
00069 #define ESC_PATTERN (2)
00070
00072 #define ESC_TMO_2 (3)
00073
00074
00075
00076
00078 typedef uint16_t crc_t;
00079
00081 typedef struct
00082 {
00083 uint8_t start;
00084 uint8_t end;
00085 uint8_t buf[UART_FRAME_SIZE];
00086 } wuart_buffer_t;
00087
00088
00090 typedef enum
00091 {
00093 CMD_MODE,
00095 DATA_MODE,
00096 } wuart_state_t;
00097
00098
00099 static uint16_t rxcnt;
00100 static uint16_t txcnt;
00101
00102 volatile bool chkrxbuf;
00103 volatile bool txpending;
00104 volatile wuart_state_t wuart_state;
00105 bool echo = false;
00106
00107 timer_hdl_t tmr_uart;
00108 wuart_buffer_t rxbuf[2];
00109 volatile uint8_t rxbuf_idx = 0;
00110
00111 wuart_state_t wuart_check_escape(uint8_t * cmd, uint8_t size);
00112 wuart_state_t wuart_parse_at_command(char *cmd);
00113
00114
00115
00119 void wuart_init()
00120 {
00121 trx_param_t trxp;
00122
00123 LED_INIT();
00124 LED_SET_VALUE(0);
00125 KEY_INIT();
00126
00127 hif_init(9600);
00128 timer_init();
00129
00130 rxbuf_idx = 0;
00131 memset(rxbuf, 0, sizeof(rxbuf));
00132 rxbuf[0].end = PAYLD_START;
00133 rxbuf[1].end = PAYLD_START;
00134 radio_init(rxbuf[rxbuf_idx].buf, UART_FRAME_SIZE);
00135
00136
00137
00138 sei();
00139
00140 #if 0
00141 cfgt = radio_config_recall();
00142 #else
00143 # warning "currently no radio_config_recall()"
00144 #endif
00145 radio_set_state(STATE_OFF);
00146
00147 wuart_state = CMD_MODE;
00148 radio_set_param(RP_CHANNEL(17));
00149 radio_set_param(RP_IDLESTATE(STATE_RX));
00150 trx_parms_get(&trxp);
00151 PRINTF("Wuart 0.2 chan=%d"NL, trxp.chan);
00152
00153 if (trx_identify() != 0)
00154 {
00155 PRINT("RADIO DOES NOT MATCG"NL);
00156 while(1);
00157 }
00158
00159 }
00160
00161
00165 int main(void)
00166 {
00167 uint16_t inchar;
00168
00169 uint8_t txbuf[UART_FRAME_SIZE], cmdidx = 0, inbytes, *cmd, tmp;
00170 wuart_buffer_t *hif_tx_buf;
00171 prot_wuart_header_t *hdr;
00172 time_t lasttxtime = 0, currtime;
00173 bool do_send;
00174
00175 wuart_init();
00176 chkrxbuf = true;
00177 txpending = false;
00178 cmd = &txbuf[PAYLD_START];
00179 hdr = (prot_wuart_header_t*)txbuf;
00180 hdr->fcf = PROT_FCF_DATA;
00181 hdr->seq = 0;
00182 hdr->dst = 0xaa;
00183 hdr->src = 0xbb;
00184 DBG_INIT();
00185
00186 while(1)
00187 {
00188
00189 if (wuart_state == DATA_MODE)
00190 {
00191 currtime = timer_systime();
00192 if (1)
00193 {
00194
00195 inbytes = hif_get_blk(cmd+cmdidx, (PAYLD_SIZE-cmdidx));
00196 cmdidx += inbytes;
00197 if (cmdidx > 0)
00198 {
00199 cmd[cmdidx]=0;
00200 }
00201
00202 #if 0
00203 wuart_state = wuart_check_escape(cmd, cmdidx);
00204 if (wuart_state == CMD_MODE)
00205 {
00206 cmdidx = 0;
00207 radio_set_state(STATE_OFF);
00208 PRINT(NL"EXIT DATA MODE"NL);
00209 break;
00210 }
00211 else
00212 #endif
00213 do_send = false;
00214 if (cmdidx == PAYLD_SIZE)
00215 {
00216 do_send = true;
00217 }
00218 else if (((currtime - lasttxtime) > 20) && (cmdidx > 0))
00219 {
00220 do_send = true;
00221 }
00222 if ((do_send == true) && (txpending == false))
00223 {
00224
00225 radio_set_state(STATE_TX);
00226
00227 tmp = 10;
00228 LED_SET(0);
00229
00230 do
00231 {
00232
00233 if (radio_do_cca() == RADIO_CCA_FREE)
00234 {
00235 hdr->seq ++;
00236 radio_send_frame(PAYLD_START + cmdidx + CRC_SIZE, txbuf, 0);
00237 txpending = true;
00238 lasttxtime = currtime;
00239 cmdidx = 0;
00240 tmp = 0;
00241 LED_SET(1);
00242 }
00243 else
00244 {
00245
00246 DELAY_US(64);
00247 }
00248 }
00249 while(tmp-- > 0);
00250
00251 if (txpending != true)
00252 {
00253 hif_puts(NL"TXFAILED"NL);
00254
00255 }
00256 else
00257 {
00258 LED_CLR(0);
00259 }
00260 if (echo)
00261 {
00262 hif_puts((char*)cmd);
00263 }
00264 }
00265 else if (cmdidx == 0)
00266 {
00267
00268 chkrxbuf = false;
00269 }
00270 }
00271 }
00272
00273 if (wuart_state == CMD_MODE)
00274 {
00275 inchar = hif_getc();
00276 if (inchar < 0x100)
00277 {
00278 if (echo)
00279 {
00280 hif_putc(inchar);
00281 if (inchar == '\n') hif_putc('\r');
00282 if (inchar == '\r') hif_putc('\n');
00283 }
00284 if (inchar == '\n' || inchar == '\r')
00285 {
00286
00287 cmd[cmdidx] = 0;
00288 wuart_state = wuart_parse_at_command((char*)cmd);
00289 cmdidx = 0;
00290 memset(cmd, 0, sizeof(cmd));
00291 if (wuart_state == DATA_MODE)
00292 {
00293 radio_set_state(STATE_RX);
00294 }
00295 }
00296 else
00297 {
00298 cmd[cmdidx++] = inchar;
00299 }
00300 }
00301 }
00302
00303
00304 hif_tx_buf = &rxbuf[(rxbuf_idx + 1)&1];
00305 if (hif_tx_buf->end > PAYLD_START)
00306 {
00307 uint8_t *p = &hif_tx_buf->buf[hif_tx_buf->start];
00308 uint8_t sz = hif_tx_buf->end - hif_tx_buf->start;
00309 hif_tx_buf->start += hif_put_blk(p, sz);
00310 if (hif_tx_buf->start >= hif_tx_buf->end)
00311 {
00312 hif_tx_buf->end = PAYLD_START;
00313 }
00314 }
00315 }
00316 }
00317
00318
00322 #ifdef DOXYGEN
00323 uint8_t * wuart_usr_radio_tx_done()
00324 #else
00325 void usr_radio_tx_done(radio_tx_done_t status)
00326 #endif
00327 {
00328 if (status == TX_OK)
00329 {
00330 LED_CLR(1);
00331 txcnt ++;
00332 }
00333 txpending = false;
00334 }
00335
00339 #ifdef DOXYGEN
00340 uint8_t * wuart_usr_radio_receive_frame()
00341 #else
00342 uint8_t * usr_radio_receive_frame(uint8_t len, uint8_t *frm, uint8_t lqi,
00343 int8_t ed, uint8_t crc)
00344 #endif
00345 {
00346 static uint8_t rxseq = 0;
00347 static uint16_t seqerr;
00348 prot_wuart_header_t *rxhdr;
00349 uint8_t __sreg = SREG; cli();
00350 LED_TOGGLE(1);
00351 if (crc == 0)
00352 {
00353 if( rxbuf[(rxbuf_idx^1)].end == PAYLD_START)
00354 {
00355
00356 rxhdr = (prot_wuart_header_t*) frm;
00357 if (rxhdr->seq != rxseq)
00358 {
00359 seqerr++;
00360 }
00361 rxseq = rxhdr->seq+1;
00362 rxbuf[rxbuf_idx].start = PAYLD_START;
00363 rxbuf[rxbuf_idx].end = len - CRC_SIZE;
00364 rxbuf_idx ^= 1;
00365 frm = rxbuf[rxbuf_idx].buf;
00366 }
00367 rxcnt ++;
00368 }
00369 SREG = __sreg;
00370 return frm;
00371 }
00372
00394 wuart_state_t wuart_check_escape(uint8_t * cmd, uint8_t size)
00395 {
00396
00397 static uint8_t pattern, tmo, esc_state, i;
00398 wuart_state_t ret = DATA_MODE;
00399
00400
00401 if (size > 0)
00402 {
00403
00404 if (size > 3)
00405 {
00406
00407 esc_state = ESC_NONE;
00408 tmo = 0;
00409 pattern = 0;
00410 }
00411 else
00412 {
00413
00414 if (esc_state > ESC_NONE)
00415 {
00416 for(i=0; i<size; i++)
00417 {
00418 if (cmd[i] == '+')
00419 {
00420 pattern++;
00421 }
00422 else
00423 {
00424 pattern = 0;
00425 esc_state = ESC_NONE;
00426 }
00427 if (pattern == 3)
00428 {
00429 esc_state = ESC_PATTERN;
00430 tmo = 0;
00431 }
00432 }
00433 }
00434 }
00435 }
00436 else
00437 {
00438
00439 tmo += 1;
00440 if (tmo > 10)
00441 {
00442 esc_state = (esc_state == ESC_PATTERN) ? ESC_TMO_2 : ESC_TMO_1;
00443 tmo = 0;
00444 }
00445 }
00446 ret = (esc_state != ESC_TMO_2) ? DATA_MODE : CMD_MODE;
00447 if (ret == CMD_MODE)
00448 {
00449 esc_state = ESC_NONE;
00450 tmo = 0;
00451 pattern = 0;
00452 }
00453 return ret;
00454 }
00455
00456
00460 wuart_state_t wuart_parse_at_command(char *cmd)
00461 {
00462
00463 wuart_state_t ret = CMD_MODE;
00464 bool atok;
00465 if (cmd[0] == 'A' && cmd[1] == 'T')
00466 {
00467 cmd += 2;
00468 while (*cmd != 0)
00469 {
00470
00471 atok = true;
00472 if (*cmd == 'D')
00473 {
00474 PRINT("ENTER DATA MODE"NL);
00475 ret = DATA_MODE;
00476 }
00477 else if (*cmd == 'E')
00478 {
00479 cmd++;
00480 if (*cmd == '0')
00481 {
00482 echo = false;
00483 }
00484 else if (*cmd == '1')
00485 {
00486 echo = true;
00487
00488 }
00489 else if (*cmd == '?')
00490 {
00491 PRINTF("ECHO %s"NL, echo ? "ON":"OFF");
00492 }
00493 else
00494 {
00495 atok = false;
00496 }
00497 }
00498 else if (*cmd == 'I')
00499 {
00500 trx_param_t trxp;
00501 trx_parms_get(&trxp);
00502 PRINTF( "E%d "\
00503 "CHA:%d TXP:%d "\
00504 "CCA:%d EDT:%d "\
00505 "CLK:%d"NL,
00506 echo,
00507 trxp.chan, trxp.txp, trxp.cca,
00508 trxp.edt, trxp.clkm);
00509 }
00510 else if (*cmd == 'S')
00511 {
00512 uint8_t reg;
00513 cmd++;
00514 reg = 0;
00515 while (*cmd != '=' && *cmd != '?')
00516 {
00517 reg *= 10;
00518 reg += (*cmd++ - '0');
00519 }
00520 if (*cmd == '=')
00521 {
00522 uint8_t val;
00523 cmd ++;
00524 val = 0;
00525 while(*cmd >= '0' && *cmd <= '9' )
00526 {
00527 val *= 10;
00528 val += (*cmd++ - '0');
00529 }
00530 PRINTF("S%d = %d"NL, reg, val);
00531 }
00532 else if (*cmd == '?')
00533 {
00534 PRINTF("S%d = %d"NL, reg, 42);
00535 }
00536 else
00537 {
00538 cmd ++;
00539 atok = false;
00540 }
00541
00542 }
00543 else
00544 {
00545 atok = false;
00546 }
00547 cmd ++;
00548 PRINTF("%s"NL, atok ? "OK" : "ERROR");
00549 }
00550 }
00551 return ret;
00552 }