Skip to content

Commit

Permalink
Add RADIO SHORTS
Browse files Browse the repository at this point in the history
  • Loading branch information
pipe01 committed Jun 20, 2024
1 parent 1a67e23 commit 19f51b4
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 67 deletions.
15 changes: 15 additions & 0 deletions include/peripherals/nrf52832/ppi.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@

typedef struct PPI_t PPI_t;

typedef enum
{
SHORT_RADIO_READY_START = 0,
SHORT_RADIO_END_DISABLE,
SHORT_RADIO_DISABLED_TXEN,
SHORT_RADIO_DISABLED_RXEN,
SHORT_RADIO_ADDRESS_RSSISTART,
SHORT_RADIO_END_START,
SHORT_RADIO_ADDRESS_BCSTART,
SHORT_RADIO_DISABLED_RSSISTOP,
} ppi_short_t;

// OPERATION(ppi);
memreg_op_result_t ppi_operation(uint32_t base, uint32_t offset, uint32_t *value, memreg_op_t op, void *userdata);

Expand All @@ -25,3 +37,6 @@ void ppi_fire_task(PPI_t *, uint8_t peripheral_id, uint8_t task_id);
void ppi_fire_event(PPI_t *, uint8_t peripheral_id, uint8_t event_id, bool pend_exception);
void ppi_clear_event(PPI_t *, uint8_t peripheral_id, uint8_t event_id);
bool ppi_event_is_set(PPI_t *, uint8_t peripheral_id, uint8_t event_id);

void ppi_shorts_set_enabled(PPI_t *, ppi_short_t short_id, bool enabled);
bool ppi_shorts_is_enabled(PPI_t *, ppi_short_t short_id);
118 changes: 54 additions & 64 deletions src/peripherals/nrf52832/ppi.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,20 @@
#include "peripherals/peripheral.h"

#define CHANNELS_COUNT 32
#define SHORTS_COUNT 32
#define PROGRAMMABLE_CHANNELS_COUNT (CHANNELS_COUNT - 12)

#define PERIPHERALS_COUNT 0x26
#define EVENTS_COUNT 64

#define SHORT_CHANNEL_INDEX(n) ((n) + CHANNELS_COUNT)

#define SET_CHANNEL(n, eep_p, eep_e, tep_p, tep_t) \
ppi->channels[n].eep_peripheral = eep_p; \
ppi->channels[n].eep_event = EVENT_ID(eep_e); \
ppi->channels[n].tep_peripheral = tep_p; \
ppi->channels[n].tep_task = TASK_ID(tep_t);

_Thread_local PPI_t *current_ppi;

typedef struct
Expand All @@ -40,7 +49,7 @@ struct PPI_t
{
cpu_t **cpu;

channel_t channels[CHANNELS_COUNT];
channel_t channels[CHANNELS_COUNT + SHORTS_COUNT];
peripheral_t *peripherals[PERIPHERALS_COUNT];
};

Expand Down Expand Up @@ -172,69 +181,32 @@ PPI_t *ppi_new(cpu_t **cpu)
{
ppi->channels[i].fixed = true;
}
for (size_t i = CHANNELS_COUNT; i < CHANNELS_COUNT + SHORTS_COUNT; i++)
{
ppi->channels[i].fixed = true;
}

// TIMER0 COMPARE[0] -> RADIO TXEN
ppi->channels[20].eep_peripheral = INSTANCE_TIMER0;
ppi->channels[20].eep_event = EVENT_ID(TIMER_EVENTS_COMPARE0);
ppi->channels[20].tep_peripheral = INSTANCE_RADIO;
ppi->channels[20].tep_task = TASK_ID(RADIO_TASKS_TXEN);

// TIMER0 COMPARE[0] -> RADIO RXEN
ppi->channels[21].eep_peripheral = INSTANCE_TIMER0;
ppi->channels[21].eep_event = EVENT_ID(TIMER_EVENTS_COMPARE0);
ppi->channels[21].tep_peripheral = INSTANCE_RADIO;
ppi->channels[21].tep_task = TASK_ID(RADIO_TASKS_RXEN);

// TIMER0 COMPARE[1] -> RADIO DISABLE
ppi->channels[22].eep_peripheral = INSTANCE_TIMER0;
ppi->channels[22].eep_event = EVENT_ID(TIMER_EVENTS_COMPARE1);
ppi->channels[22].tep_peripheral = INSTANCE_RADIO;
ppi->channels[22].tep_task = TASK_ID(RADIO_TASKS_DISABLE);

// RADIO BCMATCH -> AAR START
// TODO: Implement

// RADIO READY -> CCM KSGEN
// TODO: Implement

// RADIO ADDRESS -> CCM CRYPT
// TODO: Implement

// RADIO ADDRESS -> TIMER0 CAPTURE[1]
ppi->channels[26].eep_peripheral = INSTANCE_RADIO;
ppi->channels[26].eep_event = EVENT_ID(RADIO_EVENTS_ADDRESS);
ppi->channels[26].tep_peripheral = INSTANCE_TIMER0;
ppi->channels[26].tep_task = TASK_ID(TIMER_TASKS_CAPTURE1);

// RADIO END -> TIMER0 CAPTURE[1]
ppi->channels[27].eep_peripheral = INSTANCE_RADIO;
ppi->channels[27].eep_event = EVENT_ID(RADIO_EVENTS_END);
ppi->channels[27].tep_peripheral = INSTANCE_TIMER0;
ppi->channels[27].tep_task = TASK_ID(TIMER_TASKS_CAPTURE2);

// RTC0 COMPARE[0] -> RADIO TXEN
ppi->channels[28].eep_peripheral = INSTANCE_RTC0;
ppi->channels[28].eep_event = EVENT_ID(RTC_EVENTS_COMPARE0);
ppi->channels[28].tep_peripheral = INSTANCE_RADIO;
ppi->channels[28].tep_task = TASK_ID(RADIO_TASKS_TXEN);

// RTC0 COMPARE[0] -> RADIO RXEN
ppi->channels[29].eep_peripheral = INSTANCE_RTC0;
ppi->channels[29].eep_event = EVENT_ID(RTC_EVENTS_COMPARE0);
ppi->channels[29].tep_peripheral = INSTANCE_RADIO;
ppi->channels[29].tep_task = TASK_ID(RADIO_TASKS_RXEN);

// RTC0 COMPARE[0] -> TIMER0 CLEAR
ppi->channels[30].eep_peripheral = INSTANCE_RTC0;
ppi->channels[30].eep_event = EVENT_ID(RTC_EVENTS_COMPARE0);
ppi->channels[30].tep_peripheral = INSTANCE_TIMER0;
ppi->channels[30].tep_task = TASK_ID(TIMER_TASKS_CLEAR);

// RTC0 COMPARE[0] -> TIMER0 START
ppi->channels[31].eep_peripheral = INSTANCE_RTC0;
ppi->channels[31].eep_event = EVENT_ID(RTC_EVENTS_COMPARE0);
ppi->channels[31].tep_peripheral = INSTANCE_TIMER0;
ppi->channels[31].tep_task = TASK_ID(TIMER_TASKS_START);
SET_CHANNEL(20, INSTANCE_TIMER0, TIMER_EVENTS_COMPARE0, INSTANCE_RADIO, RADIO_TASKS_TXEN)
SET_CHANNEL(21, INSTANCE_TIMER0, TIMER_EVENTS_COMPARE0, INSTANCE_RADIO, RADIO_TASKS_RXEN)
SET_CHANNEL(22, INSTANCE_TIMER0, TIMER_EVENTS_COMPARE1, INSTANCE_RADIO, RADIO_TASKS_DISABLE)
// TODO: Implement RADIO BCMATCH -> AAR START
// TODO: Implement RADIO READY -> CCM KSGEN
// TODO: Implement RADIO ADDRESS -> CCM CRYPT
SET_CHANNEL(26, INSTANCE_RADIO, RADIO_EVENTS_ADDRESS, INSTANCE_TIMER0, TIMER_TASKS_CAPTURE1)
SET_CHANNEL(27, INSTANCE_RADIO, RADIO_EVENTS_END, INSTANCE_TIMER0, TIMER_TASKS_CAPTURE1)
SET_CHANNEL(28, INSTANCE_RTC0, RTC_EVENTS_COMPARE0, INSTANCE_RADIO, RADIO_TASKS_TXEN)
SET_CHANNEL(29, INSTANCE_RTC0, RTC_EVENTS_COMPARE0, INSTANCE_RADIO, RADIO_TASKS_RXEN)
SET_CHANNEL(30, INSTANCE_RTC0, RTC_EVENTS_COMPARE0, INSTANCE_TIMER0, TIMER_TASKS_CLEAR)
SET_CHANNEL(31, INSTANCE_RTC0, RTC_EVENTS_COMPARE0, INSTANCE_TIMER0, TIMER_TASKS_START)

SET_CHANNEL(SHORT_CHANNEL_INDEX(SHORT_RADIO_READY_START), INSTANCE_RADIO, RADIO_EVENTS_READY, INSTANCE_RADIO, RADIO_TASKS_START)
SET_CHANNEL(SHORT_CHANNEL_INDEX(SHORT_RADIO_END_DISABLE), INSTANCE_RADIO, RADIO_EVENTS_END, INSTANCE_RADIO, RADIO_TASKS_DISABLE)
SET_CHANNEL(SHORT_CHANNEL_INDEX(SHORT_RADIO_DISABLED_TXEN), INSTANCE_RADIO, RADIO_EVENTS_DISABLED, INSTANCE_RADIO, RADIO_TASKS_TXEN)
SET_CHANNEL(SHORT_CHANNEL_INDEX(SHORT_RADIO_DISABLED_RXEN), INSTANCE_RADIO, RADIO_EVENTS_DISABLED, INSTANCE_RADIO, RADIO_TASKS_RXEN)
SET_CHANNEL(SHORT_CHANNEL_INDEX(SHORT_RADIO_ADDRESS_RSSISTART), INSTANCE_RADIO, RADIO_EVENTS_ADDRESS, INSTANCE_RADIO, RADIO_TASKS_RSSISTART)
SET_CHANNEL(SHORT_CHANNEL_INDEX(SHORT_RADIO_END_START), INSTANCE_RADIO, RADIO_EVENTS_END, INSTANCE_RADIO, RADIO_TASKS_START)
SET_CHANNEL(SHORT_CHANNEL_INDEX(SHORT_RADIO_ADDRESS_BCSTART), INSTANCE_RADIO, RADIO_EVENTS_ADDRESS, INSTANCE_RADIO, RADIO_TASKS_BCSTART)
SET_CHANNEL(SHORT_CHANNEL_INDEX(SHORT_RADIO_DISABLED_RSSISTOP), INSTANCE_RADIO, RADIO_EVENTS_DISABLED, INSTANCE_RADIO, RADIO_TASKS_RSSISTOP)

return ppi;
}
Expand Down Expand Up @@ -293,7 +265,7 @@ void ppi_fire_event(PPI_t *ppi, uint8_t peripheral_id, uint8_t event_id, bool pe
if (pend_exception)
cpu_exception_set_pending(*ppi->cpu, ARM_EXTERNAL_INTERRUPT_NUMBER(peripheral_id));

for (size_t i = 0; i < CHANNELS_COUNT; i++)
for (size_t i = 0; i < CHANNELS_COUNT + SHORTS_COUNT; i++)
{
channel_t *channel = &ppi->channels[i];

Expand Down Expand Up @@ -329,3 +301,21 @@ bool ppi_event_is_set(PPI_t *ppi, uint8_t peripheral_id, uint8_t event_id)

return (periph->events & (1 << event_id)) != 0;
}

void ppi_shorts_set_enabled(PPI_t *ppi, ppi_short_t short_id, bool enabled)
{
assert(short_id < SHORTS_COUNT);

channel_t *channel = &ppi->channels[SHORT_CHANNEL_INDEX(short_id)];

channel->enabled = enabled;
}

bool ppi_shorts_is_enabled(PPI_t *ppi, ppi_short_t short_id)
{
assert(short_id < SHORTS_COUNT);

channel_t *channel = &ppi->channels[SHORT_CHANNEL_INDEX(short_id)];

return channel->enabled;
}
100 changes: 97 additions & 3 deletions src/peripherals/nrf52832/radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stdlib.h>

#include "fault.h"
#include "nrf52832.h"
#include "peripherals/nrf52832/ppi.h"

#define STATE_CHANGE_DELAY_INST 10000
Expand Down Expand Up @@ -141,6 +142,9 @@ struct RADIO_inst_t
radio_state_t state, next_state;
inten_t inten;

bool tx_sent_address, tx_sent_payload;
bool rx_received_address, rx_received_payload;

uint32_t mode;
uint32_t txpower;
uint32_t packetptr;
Expand Down Expand Up @@ -173,29 +177,99 @@ void radio_reset(RADIO_t *radio)
void radio_do_state_change(void *userdata)
{
RADIO_t *radio = userdata;
radio_state_t old_state = radio->state;

radio->state = radio->next_state;

bool request_update = false;

switch (radio->state)
{
case STATE_RXDISABLE:
case STATE_TXDISABLE:
radio->next_state = STATE_DISABLED;
request_update = true;
break;

case STATE_TXRU:
radio->next_state = STATE_TXIDLE;
request_update = true;
break;

case STATE_RXRU:
radio->next_state = STATE_RXIDLE;
request_update = true;
break;

case STATE_TX:
if (radio->tx_sent_address && radio->tx_sent_payload)
{
radio->tx_sent_address = false;
radio->tx_sent_payload = false;
radio->next_state = STATE_TXIDLE;
}
else if (radio->tx_sent_address)
{
radio->tx_sent_payload = true;
ppi_fire_event(current_ppi, INSTANCE_RADIO, EVENT_ID(RADIO_EVENTS_PAYLOAD), radio->inten.PAYLOAD);
}
else
{
radio->tx_sent_address = true;
ppi_fire_event(current_ppi, INSTANCE_RADIO, EVENT_ID(RADIO_EVENTS_ADDRESS), radio->inten.ADDRESS);
}
request_update = true;
break;

case STATE_RX:
if (radio->rx_received_address && radio->rx_received_payload)
{
radio->rx_received_address = false;
radio->rx_received_payload = false;
radio->next_state = STATE_RXIDLE;
}
else if (radio->rx_received_address)
{
radio->rx_received_payload = true;
ppi_fire_event(current_ppi, INSTANCE_RADIO, EVENT_ID(RADIO_EVENTS_PAYLOAD), radio->inten.PAYLOAD);
}
else
{
radio->rx_received_address = true;
ppi_fire_event(current_ppi, INSTANCE_RADIO, EVENT_ID(RADIO_EVENTS_ADDRESS), radio->inten.ADDRESS);
}
request_update = true;
break;

default:
switch (radio->next_state)
{
case STATE_DISABLED:
if (old_state == STATE_TXDISABLE || old_state == STATE_RXDISABLE)
ppi_fire_event(current_ppi, INSTANCE_RADIO, EVENT_ID(RADIO_EVENTS_DISABLED), radio->inten.DISABLED);
break;

case STATE_TXIDLE:
if (old_state == STATE_TXRU)
ppi_fire_event(current_ppi, INSTANCE_RADIO, EVENT_ID(RADIO_EVENTS_READY), radio->inten.READY);
else if (old_state == STATE_TX)
ppi_fire_event(current_ppi, INSTANCE_RADIO, EVENT_ID(RADIO_EVENTS_END), radio->inten.END);
break;

case STATE_RXIDLE:
if (old_state == STATE_RXRU)
ppi_fire_event(current_ppi, INSTANCE_RADIO, EVENT_ID(RADIO_EVENTS_READY), radio->inten.READY);
else if (old_state == STATE_RX)
ppi_fire_event(current_ppi, INSTANCE_RADIO, EVENT_ID(RADIO_EVENTS_END), radio->inten.END);
break;

default:
break;
}
break;
}

if (radio->next_state != radio->state)
if (request_update)
ticker_add(radio->ticker, radio_do_state_change, radio, STATE_CHANGE_DELAY_INST, false);
}

Expand Down Expand Up @@ -320,7 +394,27 @@ OPERATION(radio)
OP_EVENT(RADIO_EVENTS_CRCERROR)

case 0x200: // SHORTS
OP_RETURN_REG(radio->shorts.value, WORD);
OP_ASSERT_SIZE(op, WORD);

if (op == OP_READ_WORD)
{
*value = radio->shorts.value;
}
else if (op == OP_WRITE_WORD)
{
radio->shorts.value = *value;

ppi_shorts_set_enabled(current_ppi, SHORT_RADIO_READY_START, radio->shorts.READY_START);
ppi_shorts_set_enabled(current_ppi, SHORT_RADIO_END_DISABLE, radio->shorts.END_DISABLE);
ppi_shorts_set_enabled(current_ppi, SHORT_RADIO_DISABLED_TXEN, radio->shorts.DISABLED_TXEN);
ppi_shorts_set_enabled(current_ppi, SHORT_RADIO_DISABLED_RXEN, radio->shorts.DISABLED_RXEN);
ppi_shorts_set_enabled(current_ppi, SHORT_RADIO_ADDRESS_RSSISTART, radio->shorts.ADDRESS_RSSISTART);
ppi_shorts_set_enabled(current_ppi, SHORT_RADIO_END_START, radio->shorts.END_START);
ppi_shorts_set_enabled(current_ppi, SHORT_RADIO_ADDRESS_BCSTART, radio->shorts.ADDRESS_BCSTART);
ppi_shorts_set_enabled(current_ppi, SHORT_RADIO_DISABLED_RSSISTOP, radio->shorts.DISABLED_RSSISTOP);
}

return (MEMREG_RESULT_OK);

case 0x304: // INTENSET
if (OP_IS_READ(op))
Expand Down Expand Up @@ -423,7 +517,7 @@ OPERATION(radio)

NRF52_PERIPHERAL_CONSTRUCTOR(RADIO, radio)
{
RADIO_t *radio = malloc(sizeof(RADIO_t));
RADIO_t *radio = calloc(1, sizeof(RADIO_t));
radio->ticker = ctx.ticker;

ppi_add_peripheral(ctx.ppi, ctx.id, radio_task_handler, radio);
Expand Down

0 comments on commit 19f51b4

Please sign in to comment.