/***************************************** * Functions for start/end of WAIT_FOR_IDLE ******************************************/ static void sm_enter_wait_for_idle(bool req_rx_accepted) { sm_state = STATE_WAIT_FOR_IDLE; /* enable disabled interrupt to avoid race conditions */ periph_radio_intenset(RADIO_INTENSET_DISABLED_Msk); /* different behaviour depending on whether we actually received a scan request or not */ if (req_rx_accepted) { /* need to answer request, set scan_rsp packet and let radio continue to send */ periph_radio_packet_ptr_set(&ble_scan_rsp_data[0]); periph_radio_shorts_set(RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk); /* wait exactly 150us to send response. NOTE: the Reference manual is wrong */ periph_radio_tifs_set(150); /* send scan req to user space */ scan_req_evt_dispatch(); } else { /* remove shorts and disable radio */ periph_radio_shorts_set(0); PERIPHERAL_TASK_TRIGGER(NRF_RADIO->TASKS_DISABLE); } }
static void ble_evt_setup(void) { /*set radio*/ periph_radio_setup(); periph_radio_shorts_set( RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_DISABLED_RXEN_Msk );// //ppi //periph_ppi_set(1, &(NRF_TIMER0->TASKS_CAPTURE[0]), &(NRF_RADIO->EVENTS_DISABLED)); periph_ppi_set(26, &(NRF_TIMER0->TASKS_CAPTURE[1]), &(NRF_RADIO->EVENTS_ADDRESS)); periph_ppi_set(2, &(NRF_RADIO->TASKS_START), &(NRF_TIMER0->EVENTS_COMPARE[0])); //periph_ppi_set(3, &(NRF_RADIO->TASKS_DISABLE), &(NRF_TIMER0->EVENTS_COMPARE[1])); ///timer0 NRF_TIMER0->TASKS_CLEAR = 1; NRF_TIMER0->EVENTS_COMPARE[0] = 0; NRF_TIMER0->EVENTS_COMPARE[1] = 0; NRF_TIMER0->EVENTS_COMPARE[2] = 0; NRF_TIMER0->EVENTS_COMPARE[3] = 0; NRF_TIMER0->INTENSET = (1 << (TIMER_INTENSET_COMPARE0_Pos + 2)); NRF_TIMER0->INTENSET = (1 << (TIMER_INTENSET_COMPARE0_Pos + 3)); NVIC_EnableIRQ(TIMER0_IRQn); NRF_TIMER0->TASKS_START = 1; //| RADIO_SHORTS_DISABLED_TXEN_Msk /*set disable irq*/ periph_radio_intenset(RADIO_INTENSET_DISABLED_Msk); periph_radio_intenset(RADIO_INTENSET_READY_Msk); periph_radio_intenset(RADIO_INTENSET_ADDRESS_Msk); periph_radio_intenset(RADIO_INTENSET_PAYLOAD_Msk); periph_radio_intenset(RADIO_INTENSET_END_Msk); }
/****************************************** * Functions for start/end of adv_send state ******************************************/ static void sm_enter_adv_send(void) { sm_state = STATE_ADV_SEND; periph_radio_ch_set(channel); /* trigger task early, the rest of the setup can be done in RXRU */ PERIPHERAL_TASK_TRIGGER(NRF_RADIO->TASKS_TXEN); periph_radio_packet_ptr_set(&ble_adv_data[0]); periph_radio_shorts_set( RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_DISABLED_RXEN_Msk); periph_radio_intenset(RADIO_INTENSET_DISABLED_Msk); }
/****************************************** * Functions for start/end of SCAN_REQ_RSP ******************************************/ static void sm_enter_scan_req_rsp(void) { sm_state = STATE_SCAN_REQ_RSP; periph_radio_packet_ptr_set(&ble_rx_buf[0]); periph_radio_shorts_set( RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_DISABLED_TXEN_Msk | RADIO_SHORTS_ADDRESS_RSSISTART_Msk); periph_radio_intenset( RADIO_INTENSET_DISABLED_Msk); /* change the tifs in order to be able to capture all packets */ periph_radio_tifs_set(148); /* start the timer that aborts the RX if no address is received. */ periph_timer_start(0, 200, true); /* set PPI pipe to stop the timer as soon as an address is received */ periph_ppi_set(0, &(NRF_TIMER0->TASKS_STOP), &(NRF_RADIO->EVENTS_ADDRESS)); }
void RADIO_IRQHandler(void) { if(NRF_RADIO->EVENTS_DISABLED == 1){ NRF_RADIO->EVENTS_DISABLED = 0; if(bb_getConnState() == BLE_TX_MODE){ bb_fsm->onSleep(); tx_count++; bb_setConnState(BLE_RX_MODE); }else { rx_count++; if((bb_getConnRole() == ADV_STATE) || (bb_getConnRole() == SLAVE_STATE)){ bb_fsm->onTxStarted(); bb_setConnState(BLE_TX_MODE); } if((bb_getConnRole() == CONN_REQ)){ bb_setConnState(BLE_RX_MODE); bb_setConnRole(SLAVE_STATE); } } } if(NRF_RADIO->EVENTS_READY == 1){ NRF_RADIO->EVENTS_READY = 0; if(bb_getConnState() == BLE_TX_MODE){ if(bb_getConnRole()== ADV_STATE){ periph_radio_shorts_set( RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_DISABLED_RXEN_Msk | RADIO_SHORTS_READY_START_Msk );//// } if(bb_getConnRole()==SLAVE_STATE){ periph_radio_shorts_set( RADIO_SHORTS_END_DISABLE_Msk ); } }else{ if(bb_getConnRole()==SLAVE_STATE){ periph_radio_shorts_set( RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_DISABLED_TXEN_Msk | RADIO_SHORTS_READY_START_Msk );//// //NRF_TIMER0->CC[3] = 0; } if(bb_getConnRole()== ADV_STATE){ periph_radio_shorts_set( RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_DISABLED_TXEN_Msk //| RADIO_SHORTS_READY_START_Msk ); } } } if(NRF_RADIO->EVENTS_ADDRESS == 1){ NRF_RADIO->EVENTS_ADDRESS = 0; if(bb_getConnState() == BLE_RX_MODE){ bb_fsm->onRxAA(); } } if(NRF_RADIO->EVENTS_PAYLOAD == 1){ NRF_RADIO->EVENTS_PAYLOAD = 0; if(bb_getConnState() == BLE_RX_MODE){ if((bb_getConnRole() == CONN_REQ)){ bb_fsm->onWakeup(); } if(bb_getConnRole() == SLAVE_STATE){ bb_fsm->onWakeup(); bb_fsm->onRxPDU(); } }else{ if(bb_getConnRole()==ADV_STATE){ bb_fsm->onWakeup(); } } } if(NRF_RADIO->EVENTS_END == 1){ NRF_RADIO->EVENTS_END = 0; } }