diff --git a/.gitignore b/.gitignore index 637c11b..f10186a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,10 @@ tags *.o *.d *.lib +*.dep +JLinkLog.txt +*.uvgui* tests/all_tests +*.bak diff --git a/app/rx/keil/nrf51-simple-radio-rx.uvopt b/app/rx/keil/nrf51-simple-radio-rx.uvopt index ba13430..dd5b95b 100644 --- a/app/rx/keil/nrf51-simple-radio-rx.uvopt +++ b/app/rx/keil/nrf51-simple-radio-rx.uvopt @@ -1043,8 +1043,8 @@ 0 0 0 - ..\..\..\lib\packet_timer.c - packet_timer.c + ..\..\..\lib\packet.c + packet.c 0 0 diff --git a/app/rx/keil/nrf51-simple-radio-rx.uvproj b/app/rx/keil/nrf51-simple-radio-rx.uvproj index 4c0a188..4089da1 100644 --- a/app/rx/keil/nrf51-simple-radio-rx.uvproj +++ b/app/rx/keil/nrf51-simple-radio-rx.uvproj @@ -454,9 +454,9 @@ ..\..\..\lib\tx_queue.c - packet_timer.c + packet.c 1 - ..\..\..\lib\packet_timer.c + ..\..\..\lib\packet.c @@ -910,9 +910,9 @@ ..\..\..\lib\tx_queue.c - packet_timer.c + packet.c 1 - ..\..\..\lib\packet_timer.c + ..\..\..\lib\packet.c @@ -1366,9 +1366,9 @@ ..\..\..\lib\tx_queue.c - packet_timer.c + packet.c 1 - ..\..\..\lib\packet_timer.c + ..\..\..\lib\packet.c @@ -1822,9 +1822,9 @@ ..\..\..\lib\tx_queue.c - packet_timer.c + packet.c 1 - ..\..\..\lib\packet_timer.c + ..\..\..\lib\packet.c @@ -2278,9 +2278,9 @@ ..\..\..\lib\tx_queue.c - packet_timer.c + packet.c 1 - ..\..\..\lib\packet_timer.c + ..\..\..\lib\packet.c @@ -2734,9 +2734,9 @@ ..\..\..\lib\tx_queue.c - packet_timer.c + packet.c 1 - ..\..\..\lib\packet_timer.c + ..\..\..\lib\packet.c diff --git a/app/rx/main.c b/app/rx/main.c index d4eb1cb..c9ddaa4 100644 --- a/app/rx/main.c +++ b/app/rx/main.c @@ -8,8 +8,13 @@ #include "leds.h" #include "radio.h" +volatile uint32_t n_packets_received = 0; + void error_handler(uint32_t err_code, uint32_t line_num, char * file_name) { + volatile uint32_t m_err_code = err_code; + volatile uint32_t m_line_num = line_num; + char * volatile m_file_name = file_name; while (1) { for (uint8_t i = LED_START; i < LED_STOP; i++) @@ -26,6 +31,7 @@ void radio_evt_handler(radio_evt_t * evt) { case PACKET_RECEIVED: led_toggle(LED1); + n_packets_received++; break; default: @@ -35,17 +41,17 @@ void radio_evt_handler(radio_evt_t * evt) int main(void) { - radio_init(radio_evt_handler); - - radio_receive_start(); + static uint32_t err_code, temp; + err_code = radio_init(radio_evt_handler, 0); + ASSUME_SUCCESS(err_code); leds_init(); - gpio_pins_cfg_out(0, 8); while (1) { + err_code = radio_start_rx(); led_on(LED0); - nrf_delay_us(1000); + nrf_delay_us(50000); led_off(LED0); nrf_delay_us(100000); } diff --git a/app/rx/pure-gcc/Makefile b/app/rx/pure-gcc/Makefile index 3840af6..99cf883 100644 --- a/app/rx/pure-gcc/Makefile +++ b/app/rx/pure-gcc/Makefile @@ -8,13 +8,13 @@ APPLICATION_LIBS += radio.lib PROJECT_NAME = $(shell basename "$(realpath ../)") DEVICE = NRF51 -BOARD = BOARD_PCA10000 -SEGGER_SERIAL = 480104825 +BOARD = BOARD_PCA10001 +SEGGER_SERIAL = 480205185 #USE_SOFTDEVICE = S110 -SDK_PATH ?= $(HOME)/Projects/nrf51/nrf51822/ -TEMPLATE_PATH ?= $(HOME)/Projects/nrf51-pure-gcc-setup/template/ +SDK_PATH ?= /usr/lib/nRF51-SDK/nrf51822/ +TEMPLATE_PATH ?= $(HOME)/git/nrf51-pure-gcc-setup/template/ LIB_PATH = ../../../lib/ diff --git a/app/tx/keil/nrf51-simple-radio-tx.uvopt b/app/tx/keil/nrf51-simple-radio-tx.uvopt index 01477f0..6915b26 100644 --- a/app/tx/keil/nrf51-simple-radio-tx.uvopt +++ b/app/tx/keil/nrf51-simple-radio-tx.uvopt @@ -1167,8 +1167,8 @@ 25 51 0 - ..\..\..\lib\packet_timer.c - packet_timer.c + ..\..\..\lib\packet.c + packet.c 0 0 diff --git a/app/tx/keil/nrf51-simple-radio-tx.uvproj b/app/tx/keil/nrf51-simple-radio-tx.uvproj index c039745..3d2f888 100644 --- a/app/tx/keil/nrf51-simple-radio-tx.uvproj +++ b/app/tx/keil/nrf51-simple-radio-tx.uvproj @@ -454,9 +454,9 @@ ..\..\..\lib\tx_queue.c - packet_timer.c + packet.c 1 - ..\..\..\lib\packet_timer.c + ..\..\..\lib\packet.c @@ -910,9 +910,9 @@ ..\..\..\lib\tx_queue.c - packet_timer.c + packet.c 1 - ..\..\..\lib\packet_timer.c + ..\..\..\lib\packet.c @@ -1366,9 +1366,9 @@ ..\..\..\lib\tx_queue.c - packet_timer.c + packet.c 1 - ..\..\..\lib\packet_timer.c + ..\..\..\lib\packet.c @@ -1822,9 +1822,9 @@ ..\..\..\lib\tx_queue.c - packet_timer.c + packet.c 1 - ..\..\..\lib\packet_timer.c + ..\..\..\lib\packet.c @@ -2278,9 +2278,9 @@ ..\..\..\lib\tx_queue.c - packet_timer.c + packet.c 1 - ..\..\..\lib\packet_timer.c + ..\..\..\lib\packet.c @@ -2734,9 +2734,9 @@ ..\..\..\lib\tx_queue.c - packet_timer.c + packet.c 1 - ..\..\..\lib\packet_timer.c + ..\..\..\lib\packet.c diff --git a/app/tx/main.c b/app/tx/main.c index ee3f8ab..809ae70 100644 --- a/app/tx/main.c +++ b/app/tx/main.c @@ -10,8 +10,14 @@ #include "leds.h" #include "radio.h" +volatile uint32_t n_packets_sent = 0; +volatile uint32_t n_packets_lost = 0; + void error_handler(uint32_t err_code, uint32_t line_num, char * file_name) { + volatile uint32_t m_err_code = err_code; + volatile uint32_t m_line_num = line_num; + char * volatile m_file_name = file_name; while (1) { for (uint8_t i = LED_START; i < LED_STOP; i++) @@ -27,10 +33,12 @@ void radio_evt_handler(radio_evt_t * evt) { case PACKET_SENT: led_toggle(LED1); + n_packets_sent++; break; - case PACKET_LOST: + case PACKET_RECEIVED: led_toggle(LED0); + n_packets_lost++; break; default: @@ -46,24 +54,26 @@ int main(void) leds_init(); + radio_packet_t initial_packet; + initial_packet.len = 4; + radio_packet_t packet; packet.len = 4; - packet.flags.ack = 0; - radio_init(radio_evt_handler); + radio_init(radio_evt_handler, &initial_packet); while (1) { packet.data[0] = i++; packet.data[1] = 0x12; - err_code = radio_send(&packet); - ASSUME_SUCCESS(err_code); - packet.data[0] = i++; - packet.data[1] = 0x12; err_code = radio_send(&packet); ASSUME_SUCCESS(err_code); + nrf_delay_us(2000); + + radio_stop_rx(); + nrf_delay_us(1000000); } } diff --git a/app/tx/pure-gcc/Makefile b/app/tx/pure-gcc/Makefile index d906b39..00a837b 100644 --- a/app/tx/pure-gcc/Makefile +++ b/app/tx/pure-gcc/Makefile @@ -8,13 +8,13 @@ APPLICATION_LIBS += radio.lib PROJECT_NAME = $(shell basename "$(realpath ../)") DEVICE = NRF51 -BOARD = BOARD_PCA10001 -SEGGER_SERIAL = 480200976 +BOARD = BOARD_PCA10000 +SEGGER_SERIAL = 480107090 #USE_SOFTDEVICE = S110 -SDK_PATH ?= $(HOME)/Projects/nrf51/nrf51822/ -TEMPLATE_PATH ?= $(HOME)/Projects/nrf51-pure-gcc-setup/template/ +SDK_PATH ?= /usr/lib/nRF51-SDK/nrf51822/ +TEMPLATE_PATH ?= ../../../../nrf51-pure-gcc-setup/template/ LIB_PATH = ../../../lib/ diff --git a/lib/Makefile b/lib/Makefile index cf84597..d525e06 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,5 +1,6 @@ RADIO_SRCS += radio.c RADIO_SRCS += queue.c +RADIO_SRCS += packet.c RADIO_SRCS += evt_queue.c RADIO_SRCS += tx_queue.c RADIO_SRCS += rx_queue.c diff --git a/lib/packet.c b/lib/packet.c new file mode 100644 index 0000000..c893570 --- /dev/null +++ b/lib/packet.c @@ -0,0 +1,20 @@ +#include "packet.h" +#include "error.h" + + +uint32_t dummy_packet_get(radio_packet_t ** packet) +{ + static radio_packet_t empty_packet = + { + .len = 0, + .flags = 0x80 + }; + + *packet = &empty_packet; + return SUCCESS; +} + +bool packet_is_empty(radio_packet_t* packet) +{ + return (packet->len == 0); +} diff --git a/lib/packet.h b/lib/packet.h new file mode 100644 index 0000000..4095527 --- /dev/null +++ b/lib/packet.h @@ -0,0 +1,24 @@ +#ifndef PACKET_H_INCLUDED +#define PACKET_H_INCLUDED +#include +#include + +#define RADIO_PACKET_MAX_LEN 64 +#define RADIO_PACKET_QUEUE_SIZE 8 + +typedef struct __attribute__((packed)) +{ + uint8_t len; + struct __attribute__((packed)) + { + uint8_t padding : 8; + //uint8_t ack : 1; + } flags; + uint8_t data[RADIO_PACKET_MAX_LEN]; +} radio_packet_t; + +uint32_t dummy_packet_get(radio_packet_t ** packet); + +bool packet_is_empty(radio_packet_t* packet); + +#endif diff --git a/lib/packet_timer.c b/lib/packet_timer.c index 221d9a6..27fe83c 100644 --- a/lib/packet_timer.c +++ b/lib/packet_timer.c @@ -8,6 +8,10 @@ packet_timer_timeout_callback m_timeout_callback; void TIMER0_IRQHandler(void) { + if (NRF_TIMER0->EVENTS_COMPARE[0] == 1 && NRF_TIMER0->INTENSET & (TIMER_INTENSET_COMPARE0_Msk)) + { + NRF_TIMER0->EVENTS_COMPARE[0] = 0; + } if (NRF_TIMER0->EVENTS_COMPARE[1] == 1 && NRF_TIMER0->INTENSET & (TIMER_INTENSET_COMPARE1_Msk)) { NRF_TIMER0->EVENTS_COMPARE[1] = 0; @@ -26,15 +30,6 @@ static void hfclk_stop(void) NRF_CLOCK->TASKS_HFCLKSTOP = 1; } -void TIMER0_IRQHandler(void) -{ - if (NRF_TIMER0->EVENTS_COMPARE[1] == 1 && NRF_TIMER0->INTENSET & (TIMER_INTENSET_COMPARE1_Msk)) - { - NRF_TIMER0->EVENTS_COMPARE[1] = 0; - - m_timeout_callback(); - } -} void packet_timer_evt_handler(packet_timer_evt_t evt) { @@ -51,7 +46,10 @@ void packet_timer_rx_prepare(void) hfclk_start(); NRF_TIMER0->CC[0] = 1500; - NRF_TIMER0->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos; + NRF_TIMER0->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos | + TIMER_SHORTS_COMPARE0_STOP_Enabled << TIMER_SHORTS_COMPARE0_STOP_Pos; + + NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos; // CH21: TIMER0->EVENTS_COMPARE[0] -> RADIO->TASKS_RXEN NRF_PPI->CHENSET = PPI_CHENSET_CH21_Enabled << PPI_CHENSET_CH21_Pos; @@ -66,7 +64,7 @@ void packet_timer_tx_prepare(packet_timer_timeout_callback timeout_callback) NRF_TIMER0->PRESCALER = 4; NRF_TIMER0->CC[0] = 1500; - NRF_TIMER0->CC[1] = 2000; + NRF_TIMER0->CC[1] = 4000; NRF_TIMER0->SHORTS = TIMER_SHORTS_COMPARE1_CLEAR_Enabled << TIMER_SHORTS_COMPARE1_CLEAR_Pos; NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos | TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos; diff --git a/lib/packet_timer.h b/lib/packet_timer.h index 12ffed0..e55e917 100644 --- a/lib/packet_timer.h +++ b/lib/packet_timer.h @@ -9,7 +9,7 @@ typedef enum } packet_timer_evt_t; -void packet_timer_evt_handler(packet_timer_evt_t * evt); +void packet_timer_evt_handler(packet_timer_evt_t evt); void packet_timer_tx_prepare(packet_timer_timeout_callback timeout_callback); diff --git a/lib/queue.c b/lib/queue.c index 6cfa50f..6bc0042 100644 --- a/lib/queue.c +++ b/lib/queue.c @@ -23,7 +23,7 @@ bool queue_is_empty(queue_t * queue) bool queue_is_full(queue_t * queue) { - return ((queue->tail + 1u) % queue->size) == queue->head; + return ((queue->tail + 2u) % queue->size) == queue->head; } uint32_t queue_new(queue_t * queue, uint8_t ** element) @@ -33,8 +33,12 @@ uint32_t queue_new(queue_t * queue, uint8_t ** element) *element = &queue->elements[queue->tail * queue->element_size]; - queue->tail = (queue->tail + 1u) % queue->size; + return SUCCESS; +} +uint32_t queue_ready(queue_t * queue) +{ + queue->tail = (queue->tail + 1u) % queue->size; return SUCCESS; } @@ -44,23 +48,34 @@ uint32_t queue_add(queue_t * queue, uint8_t * element) uint8_t * new_element; err_code = queue_new(queue, &new_element); - if (err_code != SUCCESS) - return err_code; - - memcpy(new_element, element, queue->element_size); - - return SUCCESS; + if (err_code == SUCCESS) + { + memcpy(new_element, element, queue->element_size); + queue->tail = (queue->tail + 1u) % queue->size; + } + return err_code; } uint32_t queue_get(queue_t * queue, uint8_t * element) +{ + uint8_t * element_ptr; + uint32_t ret_val = queue_get_ptr(queue, &element_ptr); + + if (ret_val == SUCCESS) + { + memcpy(element, element_ptr, queue->element_size); + } + return ret_val; +} + +uint32_t queue_get_ptr(queue_t * queue, uint8_t ** element) { if (queue_is_empty(queue)) return ERROR_NOT_FOUND; - memcpy(element, &queue->elements[queue->head * queue->element_size], queue->element_size); + *element = &queue->elements[queue->head * queue->element_size]; queue->head = (queue->head + 1u) % queue->size; return SUCCESS; } - diff --git a/lib/queue.h b/lib/queue.h index 4ee0424..9482454 100644 --- a/lib/queue.h +++ b/lib/queue.h @@ -35,4 +35,8 @@ uint32_t queue_add(queue_t * queue, uint8_t * packet); uint32_t queue_get(queue_t * queue, uint8_t * packet); +uint32_t queue_get_ptr(queue_t * queue, uint8_t ** element); + +uint32_t queue_ready(queue_t * queue); + #endif diff --git a/lib/radio.c b/lib/radio.c index 8d26c82..3978671 100644 --- a/lib/radio.c +++ b/lib/radio.c @@ -5,244 +5,196 @@ #include "error.h" #include "evt_queue.h" -#include "packet_timer.h" #include "tx_queue.h" #include "rx_queue.h" +#include "packet.h" #include "nrf51.h" #include "nrf51_bitfields.h" -#define PREPARE_TX(x) do \ - { \ - NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos | \ - RADIO_SHORTS_END_DISABLE_Enabled << RADIO_SHORTS_END_DISABLE_Pos | \ - RADIO_SHORTS_DISABLED_TXEN_Enabled << RADIO_SHORTS_DISABLED_TXEN_Pos; \ - } while(0) - -#define PREPARE_RX(x) do \ - { \ - NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos | \ - RADIO_SHORTS_END_DISABLE_Enabled << RADIO_SHORTS_END_DISABLE_Pos | \ - RADIO_SHORTS_DISABLED_RXEN_Enabled << RADIO_SHORTS_DISABLED_RXEN_Pos; \ - } while(0) - -#define PREPARE_DISABLE(x) do \ - { \ - NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos | \ - RADIO_SHORTS_END_DISABLE_Enabled << RADIO_SHORTS_END_DISABLE_Pos; \ - } while(0) typedef enum { IDLE, RX_PACKET_RECEIVE, - RX_ACK_SEND, TX_PACKET_SEND, - TX_ACK_RECEIVE, } radio_state_t; -volatile static radio_state_t m_state; +volatile radio_state_t m_state; -static radio_packet_t m_tx_packet; -static radio_packet_t m_rx_packet; +static radio_packet_t * m_tx_packet; +static radio_packet_t * m_rx_packet; +static radio_packet_t * m_initial_packet; -static uint8_t m_tx_attempt_count; +uint32_t prepare_rx(void); +uint32_t prepare_tx(void); +uint32_t prepare_idle(void); -static void tx_packet_prepare(void) +uint32_t radio_init(radio_evt_handler_t * evt_handler, radio_packet_t * initial_packet) { - uint32_t err_code; - err_code = tx_queue_get(&m_tx_packet); - ASSUME_SUCCESS(err_code); + m_state = IDLE; - m_tx_attempt_count = 0; + m_initial_packet = initial_packet; - NRF_RADIO->PACKETPTR = (uint32_t) &m_tx_packet; -} + evt_queue_init(evt_handler); + tx_queue_init(); + rx_queue_init(); -void RADIO_IRQHandler(void) -{ - radio_evt_type_t evt_type; - uint32_t err_code; + NRF_RADIO->BASE0 = 0xE7E7E7E7; + NRF_RADIO->PREFIX0 = 0xE7E7E7E7; - if((NRF_RADIO->EVENTS_END == 1) && (NRF_RADIO->INTENSET & RADIO_INTENSET_END_Msk)) - { - NRF_RADIO->EVENTS_END = 0; + NRF_RADIO->RXADDRESSES = RADIO_RXADDRESSES_ADDR0_Enabled << RADIO_RXADDRESSES_ADDR0_Pos; - switch (m_state) - { - case TX_PACKET_SEND: - NRF_RADIO->PACKETPTR = (uint32_t) &m_rx_packet; + NRF_RADIO->PCNF0 = 8 << RADIO_PCNF0_LFLEN_Pos | + 8 << RADIO_PCNF0_S1LEN_Pos; + NRF_RADIO->PCNF1 = 64 << RADIO_PCNF1_MAXLEN_Pos | + 4 << RADIO_PCNF1_BALEN_Pos; - m_state = TX_ACK_RECEIVE; - break; + NRF_RADIO->FREQUENCY = 40; + NRF_RADIO->TIFS = 150; + NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit << RADIO_MODE_MODE_Pos; - case TX_ACK_RECEIVE: - packet_timer_evt_handler(PACKET_TIMER_EVT_PACKET_RX); + NRF_RADIO->CRCCNF = RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos; - if (m_rx_packet.flags.ack == 1) - evt_type = PACKET_SENT; - else - evt_type = PACKET_LOST; + NRF_RADIO->CRCINIT = 0xFFFF; + NRF_RADIO->CRCPOLY = 0x11021; - evt_queue_add(evt_type); + NRF_RADIO->INTENSET = RADIO_INTENSET_END_Enabled << RADIO_INTENSET_END_Pos; + NVIC_SetPriority(RADIO_IRQn, 0); + NVIC_EnableIRQ(RADIO_IRQn); - if (tx_queue_is_empty()) - { - m_state = IDLE; - } - else - { - tx_packet_prepare(); - m_state = TX_PACKET_SEND; - } - break; + return SUCCESS; +} - case RX_PACKET_RECEIVE: - m_tx_packet.flags.ack = 0; +uint32_t radio_start_tx() +{ + uint32_t err_code; - err_code = rx_queue_add(&m_rx_packet); - if (err_code == SUCCESS) - { - m_tx_packet.flags.ack = 1; + NRF_CLOCK->TASKS_HFCLKSTART = 1; - evt_queue_add(PACKET_RECEIVED); - } - NRF_RADIO->PACKETPTR = (uint32_t) &m_tx_packet; + NRF_RADIO->TASKS_TXEN = 1; - m_state = RX_ACK_SEND; - break; + err_code = prepare_tx(); - case RX_ACK_SEND: - NRF_RADIO->PACKETPTR = (uint32_t) &m_rx_packet; + return err_code; +} - m_state = RX_PACKET_RECEIVE; - break; +uint32_t radio_start_rx() +{ + uint32_t err_code = SUCCESS; - case IDLE: - break; - } - } - if ((NRF_RADIO->EVENTS_DISABLED == 1) && (NRF_RADIO->INTENSET & RADIO_INTENSET_DISABLED_Msk)) + if (m_state == IDLE) { - NRF_RADIO->EVENTS_DISABLED = 0; + NRF_CLOCK->TASKS_HFCLKSTART = 1; - switch (m_state) - { - case TX_PACKET_SEND: - case RX_ACK_SEND: - PREPARE_RX(); - break; + NRF_RADIO->TASKS_RXEN = 1; - case RX_PACKET_RECEIVE: - PREPARE_TX(); - break; - - case TX_ACK_RECEIVE: - if (tx_queue_is_empty()) - PREPARE_DISABLE(); - else - PREPARE_TX(); - break; - - case IDLE: - packet_timer_event_stop(); - break; - } + err_code = prepare_rx(); } + + return err_code; } -void on_packet_timer_timeout(void) +uint32_t prepare_tx() { - if (m_tx_attempt_count++ < RADIO_TX_ATTEMPT_MAX) - { - PREPARE_TX(); - m_state = TX_PACKET_SEND; - } - else + uint32_t err_code = SUCCESS; + err_code = tx_queue_get_ptr(&m_tx_packet); + + if (err_code == ERROR_NOT_FOUND) { - packet_timer_event_stop(); - evt_queue_add(PACKET_LOST); + if (m_state == IDLE) + { + m_tx_packet = m_initial_packet; + err_code = SUCCESS; + } + else + { + err_code = dummy_packet_get(&m_tx_packet); + } } + NRF_RADIO->PACKETPTR = (uint32_t)m_tx_packet; + m_state = TX_PACKET_SEND; + + NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos | + RADIO_SHORTS_END_DISABLE_Enabled << RADIO_SHORTS_END_DISABLE_Pos | + RADIO_SHORTS_DISABLED_RXEN_Enabled << RADIO_SHORTS_DISABLED_RXEN_Pos; + + return err_code; } -uint32_t radio_init(radio_evt_handler_t * evt_handler) +uint32_t prepare_rx() { - m_state = IDLE; + uint32_t err_code; + err_code = rx_queue_new(&m_rx_packet); - evt_queue_init(evt_handler); - tx_queue_init(); - rx_queue_init(); + if (err_code == SUCCESS) + { + NRF_RADIO->PACKETPTR = (uint32_t)m_rx_packet; + m_state = RX_PACKET_RECEIVE; - NRF_RADIO->BASE0 = 0xE7E7E7E7; - NRF_RADIO->PREFIX0 = 0xE7E7E7E7; + NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos | + RADIO_SHORTS_END_DISABLE_Enabled << RADIO_SHORTS_END_DISABLE_Pos | + RADIO_SHORTS_DISABLED_TXEN_Enabled << RADIO_SHORTS_DISABLED_TXEN_Pos; + } - NRF_RADIO->PCNF0 = 8 << RADIO_PCNF0_LFLEN_Pos | - 8 << RADIO_PCNF0_S1LEN_Pos; - NRF_RADIO->PCNF1 = 64 << RADIO_PCNF1_MAXLEN_Pos | - 4 << RADIO_PCNF1_BALEN_Pos; + return err_code; +} - NRF_RADIO->FREQUENCY = 40; - NRF_RADIO->TIFS = 150; - NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit << RADIO_MODE_MODE_Pos; +uint32_t prepare_idle() +{ + m_state = IDLE; - NRF_RADIO->CRCCNF = RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos; + NRF_RADIO->SHORTS = 0; - NRF_RADIO->CRCINIT = 0xFFFF; - NRF_RADIO->CRCPOLY = 0x11021; + NRF_RADIO->TASKS_DISABLE = 1; return SUCCESS; } -uint32_t radio_send(radio_packet_t * packet) +void RADIO_IRQHandler(void) { - uint32_t err_code; - - err_code = tx_queue_add(packet); - if (err_code != SUCCESS) - return err_code; - - if (m_state != IDLE) - return SUCCESS; - - m_state = TX_PACKET_SEND; + uint32_t err_code = SUCCESS; + uint32_t temp = NRF_RADIO->STATE; - packet_timer_tx_prepare(on_packet_timer_timeout); + if((NRF_RADIO->EVENTS_END == 1) && (NRF_RADIO->INTENSET & RADIO_INTENSET_END_Msk)) + { + NRF_RADIO->EVENTS_END = 0; + switch(m_state) + { + case RX_PACKET_RECEIVE: + evt_queue_add(PACKET_RECEIVED); + rx_queue_ready(); - NRF_RADIO->RXADDRESSES = RADIO_RXADDRESSES_ADDR0_Enabled << RADIO_RXADDRESSES_ADDR0_Pos; + if (tx_queue_is_empty() && packet_is_empty(m_rx_packet)) + err_code = prepare_idle(); + else + err_code = prepare_tx(); + break; - NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos | - RADIO_SHORTS_END_DISABLE_Enabled << RADIO_SHORTS_END_DISABLE_Pos | - RADIO_SHORTS_DISABLED_RXEN_Enabled << RADIO_SHORTS_DISABLED_RXEN_Pos; + case TX_PACKET_SEND: + evt_queue_add(PACKET_SENT); - NRF_RADIO->INTENSET = RADIO_INTENSET_END_Enabled << RADIO_INTENSET_END_Pos | - RADIO_INTENSET_DISABLED_Enabled << RADIO_INTENSET_DISABLED_Pos; - NVIC_SetPriority(RADIO_IRQn, 0); - NVIC_EnableIRQ(RADIO_IRQn); + err_code = prepare_rx(); + break; - tx_packet_prepare(); + default: + break; + } + } - packet_timer_event_start(); + ASSUME_SUCCESS(err_code); +} +uint32_t radio_stop_rx(void) +{ + prepare_idle(); return SUCCESS; } -uint32_t radio_receive_start(void) +uint32_t radio_send(radio_packet_t * packet) { - m_state = RX_PACKET_RECEIVE; - - packet_timer_rx_prepare(); - - NRF_RADIO->RXADDRESSES = RADIO_RXADDRESSES_ADDR0_Enabled << RADIO_RXADDRESSES_ADDR0_Pos; - - NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos | - RADIO_SHORTS_END_DISABLE_Enabled << RADIO_SHORTS_END_DISABLE_Pos | - RADIO_SHORTS_DISABLED_TXEN_Enabled << RADIO_SHORTS_DISABLED_TXEN_Pos; - - NRF_RADIO->INTENSET = RADIO_INTENSET_END_Enabled << RADIO_INTENSET_END_Pos | - RADIO_INTENSET_DISABLED_Enabled << RADIO_INTENSET_DISABLED_Pos; - NVIC_EnableIRQ(RADIO_IRQn); - - NRF_RADIO->PACKETPTR = (uint32_t) &m_rx_packet; - - return SUCCESS; + uint32_t err_code = tx_queue_add(packet); + if (m_state == IDLE) + radio_start_tx(); + return err_code; } diff --git a/lib/radio.h b/lib/radio.h index d914249..e6f7619 100644 --- a/lib/radio.h +++ b/lib/radio.h @@ -2,14 +2,13 @@ #define RADIO_H_INCLUDED #include +#include "packet.h" #ifdef __CC_ARM #pragma anon_unions #endif -#define RADIO_PACKET_MAX_LEN 64 -#define RADIO_PACKET_QUEUE_SIZE 8 -#define RADIO_EVT_QUEUE_SIZE 8 +#define RADIO_EVT_QUEUE_SIZE 12 #define RADIO_TX_ATTEMPT_MAX 3 typedef enum @@ -19,16 +18,6 @@ typedef enum PACKET_LOST, } radio_evt_type_t; -typedef struct __attribute__((packed)) -{ - uint8_t len; - struct __attribute__((packed)) - { - uint8_t padding : 7; - uint8_t ack : 1; - } flags; - uint8_t data[RADIO_PACKET_MAX_LEN]; -} radio_packet_t; typedef struct { @@ -41,8 +30,10 @@ typedef struct typedef void (radio_evt_handler_t)(radio_evt_t * evt); -uint32_t radio_init(radio_evt_handler_t * evt_handler); +uint32_t radio_init(radio_evt_handler_t * evt_handler, radio_packet_t * initial_packet); +uint32_t radio_start_tx(void); +uint32_t radio_start_rx(void); +uint32_t radio_stop_rx(void); uint32_t radio_send(radio_packet_t * packet); -uint32_t radio_receive_start(void); #endif diff --git a/lib/rx_queue.c b/lib/rx_queue.c index a8bb940..c125084 100644 --- a/lib/rx_queue.c +++ b/lib/rx_queue.c @@ -21,6 +21,24 @@ uint32_t rx_queue_add(radio_packet_t * packet) return queue_add(&m_rx_queue, (uint8_t *) packet); } + +uint32_t rx_queue_new(radio_packet_t ** packet) +{ + return queue_new(&m_rx_queue, (uint8_t **) packet); +} + +uint32_t rx_queue_get_ptr(radio_packet_t ** packet) +{ + return queue_get_ptr(&m_rx_queue, (uint8_t **) packet); +} + + +uint32_t rx_queue_ready() +{ + return queue_ready(&m_rx_queue); +} + + bool rx_queue_is_empty(void) { return queue_is_empty(&m_rx_queue); diff --git a/lib/rx_queue.h b/lib/rx_queue.h index 716d11e..e03578c 100644 --- a/lib/rx_queue.h +++ b/lib/rx_queue.h @@ -11,6 +11,12 @@ uint32_t rx_queue_get(radio_packet_t * packet); uint32_t rx_queue_add(radio_packet_t * packet); +uint32_t rx_queue_new(radio_packet_t ** packet); + +uint32_t rx_queue_get_ptr(radio_packet_t ** packet); + +uint32_t rx_queue_ready(void); + bool rx_queue_is_empty(void); #endif diff --git a/lib/tx_queue.c b/lib/tx_queue.c index 5805840..fb3e1c3 100644 --- a/lib/tx_queue.c +++ b/lib/tx_queue.c @@ -21,6 +21,17 @@ uint32_t tx_queue_add(radio_packet_t * packet) return queue_add(&m_tx_queue, (uint8_t *) packet); } + +uint32_t tx_queue_new(radio_packet_t ** packet) +{ + return queue_new(&m_tx_queue, (uint8_t **) packet); +} + +uint32_t tx_queue_get_ptr(radio_packet_t ** packet) +{ + return queue_get_ptr(&m_tx_queue, (uint8_t **) packet); +} + bool tx_queue_is_empty(void) { return queue_is_empty(&m_tx_queue); diff --git a/lib/tx_queue.h b/lib/tx_queue.h index 56afe8e..9313047 100644 --- a/lib/tx_queue.h +++ b/lib/tx_queue.h @@ -11,6 +11,10 @@ uint32_t tx_queue_get(radio_packet_t * packet); uint32_t tx_queue_add(radio_packet_t * packet); +uint32_t tx_queue_new(radio_packet_t ** packet); + +uint32_t tx_queue_get_ptr(radio_packet_t ** packet); + bool tx_queue_is_empty(void); #endif