| 1 | /** |
|---|
| 2 | \brief This program shows the use of the "radio" bsp module. |
|---|
| 3 | |
|---|
| 4 | Since the bsp modules for different platforms have the same declaration, you |
|---|
| 5 | can use this project with any platform. |
|---|
| 6 | |
|---|
| 7 | \author Thomas Watteyne <watteyne@eecs.berkeley.edu>, February 2012 |
|---|
| 8 | */ |
|---|
| 9 | |
|---|
| 10 | #include "stdint.h" |
|---|
| 11 | #include "string.h" |
|---|
| 12 | #include "board.h" |
|---|
| 13 | #include "radio.h" |
|---|
| 14 | #include "leds.h" |
|---|
| 15 | #include "bsp_timers.h" |
|---|
| 16 | |
|---|
| 17 | //=========================== defines ========================================= |
|---|
| 18 | |
|---|
| 19 | #define LENGTH_PACKET 125+LENGTH_CRC // maximum length is 127 bytes |
|---|
| 20 | #define CHANNEL 11 // 2.405GHz |
|---|
| 21 | #define TIMER_ID 0 |
|---|
| 22 | #define TIMER_DURATION 32768 // ~1s @ 32kHz |
|---|
| 23 | |
|---|
| 24 | //=========================== variables ======================================= |
|---|
| 25 | |
|---|
| 26 | enum { |
|---|
| 27 | APP_FLAG_START_FRAME = 0x01, |
|---|
| 28 | APP_FLAG_END_FRAME = 0x02, |
|---|
| 29 | APP_FLAG_TIMER = 0x04, |
|---|
| 30 | }; |
|---|
| 31 | |
|---|
| 32 | typedef enum { |
|---|
| 33 | APP_STATE_TX = 0x01, |
|---|
| 34 | APP_STATE_RX = 0x02, |
|---|
| 35 | } app_state_t; |
|---|
| 36 | |
|---|
| 37 | typedef struct { |
|---|
| 38 | uint8_t num_radioTimerOverflows; |
|---|
| 39 | uint8_t num_radioTimerCompare; |
|---|
| 40 | uint8_t num_startFrame; |
|---|
| 41 | uint8_t num_endFrame; |
|---|
| 42 | uint8_t num_timer; |
|---|
| 43 | } app_dbg_t; |
|---|
| 44 | |
|---|
| 45 | app_dbg_t app_dbg; |
|---|
| 46 | |
|---|
| 47 | typedef struct { |
|---|
| 48 | uint8_t flags; |
|---|
| 49 | app_state_t state; |
|---|
| 50 | uint8_t packet[LENGTH_PACKET]; |
|---|
| 51 | uint8_t packet_len; |
|---|
| 52 | int8_t rxpk_rssi; |
|---|
| 53 | uint8_t rxpk_lqi; |
|---|
| 54 | uint8_t rxpk_crc; |
|---|
| 55 | } app_vars_t; |
|---|
| 56 | |
|---|
| 57 | app_vars_t app_vars; |
|---|
| 58 | |
|---|
| 59 | //=========================== prototypes ====================================== |
|---|
| 60 | |
|---|
| 61 | void cb_radioTimerOverflows(); |
|---|
| 62 | void cb_radioTimerCompare(); |
|---|
| 63 | void cb_startFrame(uint16_t timestamp); |
|---|
| 64 | void cb_endFrame(uint16_t timestamp); |
|---|
| 65 | void cb_timer(); |
|---|
| 66 | |
|---|
| 67 | //=========================== main ============================================ |
|---|
| 68 | |
|---|
| 69 | /** |
|---|
| 70 | \brief The program starts executing here. |
|---|
| 71 | */ |
|---|
| 72 | int main(void) |
|---|
| 73 | { |
|---|
| 74 | uint8_t i; |
|---|
| 75 | |
|---|
| 76 | // clear local variables |
|---|
| 77 | memset(&app_vars,0,sizeof(app_vars_t)); |
|---|
| 78 | |
|---|
| 79 | // initialize board |
|---|
| 80 | board_init(); |
|---|
| 81 | |
|---|
| 82 | // add callback functions radio |
|---|
| 83 | radio_setOverflowCb(cb_radioTimerOverflows); |
|---|
| 84 | radio_setCompareCb(cb_radioTimerCompare); |
|---|
| 85 | radio_setStartFrameCb(cb_startFrame); |
|---|
| 86 | radio_setEndFrameCb(cb_endFrame); |
|---|
| 87 | |
|---|
| 88 | // prepare packet |
|---|
| 89 | app_vars.packet_len = sizeof(app_vars.packet); |
|---|
| 90 | for (i=0;i<app_vars.packet_len;i++) { |
|---|
| 91 | app_vars.packet[i] = i; |
|---|
| 92 | } |
|---|
| 93 | |
|---|
| 94 | // start timer |
|---|
| 95 | timers_start(TIMER_ID, |
|---|
| 96 | TIMER_DURATION, |
|---|
| 97 | TIMER_PERIODIC, |
|---|
| 98 | cb_timer); |
|---|
| 99 | |
|---|
| 100 | // prepare radio |
|---|
| 101 | radio_rfOn(); |
|---|
| 102 | radio_setFrequency(CHANNEL); |
|---|
| 103 | |
|---|
| 104 | // switch in RX by default |
|---|
| 105 | radio_rxEnable(); |
|---|
| 106 | app_vars.state = APP_STATE_RX; |
|---|
| 107 | |
|---|
| 108 | // start by a transmit |
|---|
| 109 | app_vars.flags |= APP_FLAG_TIMER; |
|---|
| 110 | |
|---|
| 111 | while (1) { |
|---|
| 112 | // sleep while waiting for at least one of the flags to be set |
|---|
| 113 | while (app_vars.flags==0x00) { |
|---|
| 114 | board_sleep(); |
|---|
| 115 | } |
|---|
| 116 | // handle and clear every flag |
|---|
| 117 | while (app_vars.flags) { |
|---|
| 118 | |
|---|
| 119 | if (app_vars.flags & APP_FLAG_START_FRAME) { |
|---|
| 120 | // start of frame |
|---|
| 121 | |
|---|
| 122 | switch (app_vars.state) { |
|---|
| 123 | case APP_STATE_RX: |
|---|
| 124 | // started receiving a packet |
|---|
| 125 | leds_error_on(); |
|---|
| 126 | break; |
|---|
| 127 | case APP_STATE_TX: |
|---|
| 128 | // started sending a packet |
|---|
| 129 | leds_sync_on(); |
|---|
| 130 | break; |
|---|
| 131 | } |
|---|
| 132 | // clear flag |
|---|
| 133 | app_vars.flags &= ~APP_FLAG_START_FRAME; |
|---|
| 134 | } |
|---|
| 135 | |
|---|
| 136 | if (app_vars.flags & APP_FLAG_END_FRAME) { |
|---|
| 137 | // end of frame |
|---|
| 138 | |
|---|
| 139 | switch (app_vars.state) { |
|---|
| 140 | case APP_STATE_RX: |
|---|
| 141 | // done receiving a packet |
|---|
| 142 | |
|---|
| 143 | // get packet from radio |
|---|
| 144 | radio_getReceivedFrame(app_vars.packet, |
|---|
| 145 | &app_vars.packet_len, |
|---|
| 146 | sizeof(app_vars.packet), |
|---|
| 147 | &app_vars.rxpk_rssi, |
|---|
| 148 | &app_vars.rxpk_lqi, |
|---|
| 149 | &app_vars.rxpk_crc); |
|---|
| 150 | |
|---|
| 151 | leds_error_off(); |
|---|
| 152 | break; |
|---|
| 153 | case APP_STATE_TX: |
|---|
| 154 | // done sending a packet |
|---|
| 155 | |
|---|
| 156 | // switch to RX mode |
|---|
| 157 | radio_rxEnable(); |
|---|
| 158 | app_vars.state = APP_STATE_RX; |
|---|
| 159 | |
|---|
| 160 | leds_sync_off(); |
|---|
| 161 | break; |
|---|
| 162 | } |
|---|
| 163 | // clear flag |
|---|
| 164 | app_vars.flags &= ~APP_FLAG_END_FRAME; |
|---|
| 165 | } |
|---|
| 166 | |
|---|
| 167 | if (app_vars.flags & APP_FLAG_TIMER) { |
|---|
| 168 | // timer fired |
|---|
| 169 | |
|---|
| 170 | if (app_vars.state==APP_STATE_RX) { |
|---|
| 171 | // stop listening |
|---|
| 172 | radio_rfOff(); |
|---|
| 173 | |
|---|
| 174 | // start transmitting packet |
|---|
| 175 | radio_loadPacket(app_vars.packet,app_vars.packet_len); |
|---|
| 176 | radio_txEnable(); |
|---|
| 177 | radio_txNow(); |
|---|
| 178 | |
|---|
| 179 | app_vars.state = APP_STATE_TX; |
|---|
| 180 | } |
|---|
| 181 | |
|---|
| 182 | // clear flag |
|---|
| 183 | app_vars.flags &= ~APP_FLAG_TIMER; |
|---|
| 184 | } |
|---|
| 185 | } |
|---|
| 186 | } |
|---|
| 187 | } |
|---|
| 188 | |
|---|
| 189 | //=========================== callbacks ======================================= |
|---|
| 190 | |
|---|
| 191 | void cb_radioTimerOverflows() { |
|---|
| 192 | app_dbg.num_radioTimerOverflows++; |
|---|
| 193 | } |
|---|
| 194 | |
|---|
| 195 | void cb_radioTimerCompare() { |
|---|
| 196 | app_dbg.num_radioTimerCompare++; |
|---|
| 197 | } |
|---|
| 198 | |
|---|
| 199 | void cb_startFrame(uint16_t timestamp) { |
|---|
| 200 | // set flag |
|---|
| 201 | app_vars.flags |= APP_FLAG_START_FRAME; |
|---|
| 202 | // update debug stats |
|---|
| 203 | app_dbg.num_startFrame++; |
|---|
| 204 | } |
|---|
| 205 | |
|---|
| 206 | void cb_endFrame(uint16_t timestamp) { |
|---|
| 207 | // set flag |
|---|
| 208 | app_vars.flags |= APP_FLAG_END_FRAME; |
|---|
| 209 | // update debug stats |
|---|
| 210 | app_dbg.num_endFrame++; |
|---|
| 211 | } |
|---|
| 212 | |
|---|
| 213 | void cb_timer() { |
|---|
| 214 | // set flag |
|---|
| 215 | app_vars.flags |= APP_FLAG_TIMER; |
|---|
| 216 | // update debug stats |
|---|
| 217 | app_dbg.num_timer++; |
|---|
| 218 | } |
|---|