| /* |
| * ======== talk.c ======== |
| */ |
| #include <xdc/runtime/System.h> |
| #include <local/rf/Radio.h> |
| #include <local/rf/Bsp.h> |
| |
| #define MINPERIOD 1 |
| #define MAXPERIOD 1000 |
| |
| uint16_t sMsgPeriod = 100; |
| static uint8_t sTxTid = 0, sRxTid = 0; |
| static Radio_LinkId sLinkID1; |
| |
| static void linkTo(void); |
| static uint8_t sRxCallback(Radio_LinkId); /* UART Rx frame handler. */ |
| |
| /* |
| * ======== main ======== |
| */ |
| void main(void) |
| { |
| Radio_Addr lAddr = {0x77, 0x56, 0x34, 0x12}; |
| |
| /* This call will fail because the join will fail since there is no Access |
| * Point in this scenario. But we don't care -- just use the default link |
| * token later. |
| * |
| * We supply a callback pointer to handle the message returned by the |
| * peer. |
| */ |
| Radio_start(sRxCallback, &lAddr); |
| |
| /* turn on LEDs. */ |
| if (!Bsp_led(2)) { |
| Bsp_toggleLed(2); |
| } |
| if (!Bsp_led(1)) { |
| Bsp_toggleLed(1); |
| } |
| |
| /* wait for a button press... */ |
| System_printf("waiting for any button ...\n"); |
| for (;;) { |
| if (Bsp_button(1) || Bsp_button(2)) { |
| break; |
| } |
| } |
| |
| /* never coming back... */ |
| linkTo(); |
| |
| /* but in case we do... */ |
| System_printf("oops!\n"); |
| System_exit(1); |
| } |
| |
| /* |
| * ======== linkTo ======== |
| */ |
| static void linkTo() |
| { |
| uint8_t msg[2], delay = 0; |
| |
| /* wait for peer to link to us */ |
| System_printf("linking ...\n"); |
| while (Radio_SUCCESS != Radio_link(&sLinkID1)) { |
| /* blink LEDs until we link successfully */ |
| Bsp_toggleLed(1); |
| Bsp_toggleLed(2); |
| Bsp_delay(1000); |
| } |
| |
| /* we're linked. turn off red LED. received messages will toggle the |
| * green LED. |
| */ |
| System_printf("linked to %d.\n", sLinkID1); |
| if (Bsp_led(2)) { |
| Bsp_toggleLed(2); |
| } |
| |
| /* turn on RX. default is RX off. */ |
| Radio_setRxOn(); |
| |
| /* put LED to toggle in the message */ |
| msg[0] = 2; /* toggle red */ |
| while (1) { |
| Bsp_delay(sMsgPeriod + (delay * sMsgPeriod)); |
| |
| /* delay longer and longer -- then start over */ |
| delay = (delay + 1) & 0x07; |
| |
| /* put the sequence ID in the message */ |
| msg[1] = ++sTxTid; |
| Radio_send(sLinkID1, msg, sizeof(msg)); |
| } |
| } |
| |
| /* |
| * ======== sRxCallback ======== |
| * handle received frames. |
| */ |
| static uint8_t sRxCallback(Radio_LinkId port) |
| { |
| uint8_t msg[2], len, tid, delta; |
| |
| /* is the callback for the link ID we want to handle? */ |
| if (port == sLinkID1) { |
| /* yes. go get the frame. we know this call will succeed. */ |
| if ((Radio_SUCCESS == Radio_receive(sLinkID1, msg, &len)) && len) { |
| /* Check the application sequence number to detect |
| * late or missing frames... |
| */ |
| tid = msg[1]; |
| delta = tid - sRxTid; |
| if (delta != 1) { |
| System_printf( |
| "frame error: prev = 0x%x, received = 0x%x, sent = 0x%x\n", |
| sRxTid, tid, sTxTid); |
| } |
| if (tid) { |
| if (tid > sRxTid) { |
| /* we're good. toggle the LED specified in the message */ |
| Bsp_toggleLed(msg[0]); |
| sRxTid = tid; |
| } |
| } |
| else { |
| /* the wrap case... */ |
| if (sRxTid) { |
| /* we're good. toggle LED in the message */ |
| Bsp_toggleLed(msg[0]); |
| sRxTid = tid; |
| } |
| } |
| |
| /* drop frame. we're done with it. */ |
| return (1); |
| } |
| else { |
| System_printf("receive from %d (len = %d) failed.\n", |
| sLinkID1, len); |
| } |
| } |
| |
| /* keep frame for later handling. */ |
| return (0); |
| } |
| |
| /* |
| * ======== uartRxCallback ======== |
| * SysUart callack function specified in config file |
| */ |
| void uartRxCallback(char *buf, int len) |
| { |
| switch (buf[0]) { |
| case '-': { |
| sMsgPeriod -= 10; |
| break; |
| } |
| case '+': { |
| sMsgPeriod += 10; |
| break; |
| } |
| case '0': { |
| sMsgPeriod = 0; |
| break; |
| } |
| default: { |
| break; |
| } |
| } |
| |
| if (sMsgPeriod < MINPERIOD) { |
| sMsgPeriod = MINPERIOD; |
| } |
| if (sMsgPeriod > MAXPERIOD) { |
| sMsgPeriod = MAXPERIOD; |
| } |
| } |