void radio_txNow() { PORT_TIMER_WIDTH val; // change state radio_vars.state = RADIOSTATE_TRANSMITTING; // send packet by pulsing the SLP_TR_CNTL pin PORT_PIN_RADIO_SLP_TR_CNTL_HIGH(); PORT_PIN_RADIO_SLP_TR_CNTL_LOW(); // The AT86RF231 does not generate an interrupt when the radio transmits the // SFD, which messes up the MAC state machine. The danger is that, if we leave // this funtion like this, any radio watchdog timer will expire. // Instead, we cheat an mimick a start of frame event by calling // ieee154e_startOfFrame from here. This also means that software can never catch // a radio glitch by which #radio_txEnable would not be followed by a packet being // transmitted (I've never seen that). if (radio_vars.startFrame_cb!=NULL) { // call the callback val=radiotimer_getCapturedTime(); radio_vars.startFrame_cb(val); } }
/** \brief The program starts executing here. */ int mote_main(void) { uint8_t i; // clear local variables memset(&app_vars,0,sizeof(app_vars_t)); // initialize board board_init(); GPIO_Configuration(); EXTI_Configuration(); GPIOD->BRR = (uint32_t)GPIO_Pin_2; #ifdef RADIO_SLEEP PORT_PIN_RADIO_SLP_TR_CNTL_HIGH(); #ifdef RADIO_SLEEP_IN_RUN_MOdE while(1); #endif board_sleep(); #endif #ifdef RADIO_TRXOFF board_sleep(); #endif // add callback functions radio radio_setOverflowCb(cb_radioTimerOverflows); radio_setCompareCb(cb_radioTimerCompare); radio_setStartFrameCb(cb_startFrame); radio_setEndFrameCb(cb_endFrame); // prepare packet app_vars.packet_len = sizeof(app_vars.packet); for (i=0;i<app_vars.packet_len;i++) { app_vars.packet[i] = ID; } // start bsp timer bsp_timer_set_callback(cb_timer); bsp_timer_scheduleIn(TIMER_PERIOD); // prepare radio radio_rfOn(); radio_setFrequency(CHANNEL); // switch in RX by default radio_rxEnable(); app_vars.state = APP_STATE_RX; #ifdef RADIO_RX_ON leds_all_off(); board_sleep(); #endif // start by a transmit app_vars.flags |= APP_FLAG_TIMER; while (1) { // sleep while waiting for at least one of the flags to be set while (app_vars.flags==0x00) { board_sleep(); } // handle and clear every flag while (app_vars.flags) { if (app_vars.flags & APP_FLAG_START_FRAME) { // start of frame switch (app_vars.state) { case APP_STATE_RX: // started receiving a packet leds_error_on(); break; case APP_STATE_TX: // started sending a packet leds_sync_on(); break; } // clear flag app_vars.flags &= ~APP_FLAG_START_FRAME; } if (app_vars.flags & APP_FLAG_END_FRAME) { // end of frame switch (app_vars.state) { case APP_STATE_RX: // done receiving a packet app_vars.packet_len = sizeof(app_vars.packet); for (i=0;i<app_vars.packet_len;i++) { app_vars.packet[i] = 0; } // get packet from radio radio_getReceivedFrame(app_vars.packet, &app_vars.packet_len, sizeof(app_vars.packet), &app_vars.rxpk_rssi, &app_vars.rxpk_lqi, &app_vars.rxpk_crc); leds_error_off(); break; case APP_STATE_TX: // done sending a packet // switch to RX mode radio_rxEnable(); app_vars.state = APP_STATE_RX; leds_sync_off(); break; } // clear flag app_vars.flags &= ~APP_FLAG_END_FRAME; } if (app_vars.flags & APP_FLAG_TIMER) { // timer fired if (app_vars.state==APP_STATE_RX) { // stop listening radio_rfOff(); // prepare packet app_vars.packet_len = sizeof(app_vars.packet); for (i=0;i<app_vars.packet_len;i++) { app_vars.packet[i] = ID; } // start transmitting packet radio_loadPacket(app_vars.packet,app_vars.packet_len); radio_txEnable(); #ifdef RADIO_PLL_ON leds_all_off(); board_sleep(); #endif radio_txNow(); #ifdef RADIO_BUSY_TX leds_all_off(); while(1) { //keep sending PORT_PIN_RADIO_SLP_TR_CNTL_HIGH(); PORT_PIN_RADIO_SLP_TR_CNTL_LOW(); } board_sleep(); #endif app_vars.state = APP_STATE_TX; } // clear flag app_vars.flags &= ~APP_FLAG_TIMER; } } } }
void board_init() { uint16_t i,j; //enable all port clocks. SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK ); //init all pins for the radio //SLPTR #ifdef TOWER_K20 PORTB_PCR3 = PORT_PCR_MUX(1);// -- PTB3 used as gpio for slptr GPIOB_PDDR |= RADIO_SLPTR_MASK; //set as output //RADIO RST -- TODO in the TWR change it to another pin! this is one of the leds. PORTC_PCR9 = PORT_PCR_MUX(1);// -- PTC9 used as gpio for radio rst GPIOC_PDDR |= RADIO_RST_MASK; //set as output #elif OPENMOTE_K20 PORTD_PCR4 = PORT_PCR_MUX(1);// -- PTD4 used as gpio for slptr GPIOD_PDDR |= RADIO_SLPTR_MASK; //set as output //RADIO RST PORTD_PCR5 = PORT_PCR_MUX(1);// -- PTD5 used as gpio for radio rst GPIOD_PDDR |= RADIO_RST_MASK; //set as output #endif PORT_PIN_RADIO_RESET_LOW();//activate the radio. PORT_PIN_RADIO_SLP_TR_CNTL_LOW(); //ptc5 .. ptc5 is pin 62, irq A enable_irq(RADIO_EXTERNAL_PORT_IRQ_NUM);//enable the irq. The function is mapped to the vector at position 105 (see manual page 69). The vector is in isr.h //external port radio_isr. PORTC_PCR5 = PORT_PCR_MUX(1);// -- PTC5 used as gpio for radio isr through llwu GPIOC_PDDR &= ~1<<RADIO_ISR_PIN; //set as input ==0 PORTC_PCR5 |= PORT_PCR_IRQC(0x09); //9 interrupt on raising edge. page 249 of the manual. PORTC_PCR5 |= PORT_PCR_ISF_MASK; //clear any pending interrupt. llwu_init();//low leakage unit init - to recover from deep sleep debugpins_init(); leds_init(); bsp_timer_init(); uart_init(); radiotimer_init(); spi_init(); radio_init(); leds_all_off(); leds_sync_on(); leds_radio_on(); leds_debug_on(); leds_error_on(); leds_all_off(); debugpins_fsm_clr(); }