working version - communication with a single client tested, works

retry
Ondřej Hruška 6 years ago
parent 5f563e9038
commit 99904eec7c
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 3
      Inc/nrf.h
  2. 35
      Src/gex_gateway.c
  3. 2
      Src/gpio.c
  4. 13
      Src/main.c
  5. 127
      Src/nrf.c
  6. 2
      Src/spi.c

@ -21,6 +21,9 @@
#include "main.h"
#define dbg_nrf(...) do{}while(0)
//#define dbg_nrf(...) dbg(##__VA_ARGS__)
// Initialize SPI and the Nordic
/**

@ -86,10 +86,10 @@ void handle_txframe_chunk(const uint8_t *buffer, uint16_t size)
ck = ~ck;
if (ck != txmsg_cksum) {
dbg("Checksum mismatch!");
dbg("Checksum from usb master mismatch!");
}
else {
dbg("Verified, sending a %d B frame to slave.", (int) txmsg_len);
dbg_nrf("Verified, sending a %d B frame to slave.", (int) txmsg_len);
uint8_t pipe = NRF_Addr2PipeNum(txmsg_addr);
if (pipe == 0xFF) {
@ -102,10 +102,13 @@ void handle_txframe_chunk(const uint8_t *buffer, uint16_t size)
remain -= chunk;
if (!suc) {
dbg("Sending failed."); // (even with retransmission)
dbg("Sending failed, discard rest");
break; // skip rest of the frame
}
}
if (remain == 0) {
dbg_nrf("Sending completed. Is Rx ready? %d", (int)NRF_IsRxPacket());
}
}
}
@ -152,7 +155,7 @@ void gw_handle_usb_out(uint8_t *buffer)
}
start_slave_cmd(slave_addr, frame_len, cksum);
dbg("Collecting frame for slave %02x: %d bytes", (int)slave_addr, (int)frame_len);
dbg_nrf("Collecting frame for slave %02x: %d bytes", (int)slave_addr, (int)frame_len);
cmd_state = CMD_STATE_TXMSG;
// handle the rest as payload
@ -189,14 +192,14 @@ void handle_cmd_addnodes(PayloadParser *pp)
if (!suc) {
dbg("Failed to add node.");
} else {
dbg("Bound node %02x to pipe %d", node, pipenum);
dbg_nrf("Bound node %02x to pipe %d", node, pipenum);
}
}
}
void respond_gw_id(void)
{
dbg("> respond_gw_id");
dbg_nrf("> respond_gw_id");
struct msg_network_id m = {
.msg_type = MSG_TYPE_NETWORK_ID,
.bytes = {
@ -234,47 +237,35 @@ static void compute_network_id(void)
pb = pb_start(gex_network, 4, NULL);
pb_u32(&pb, ck);
dbg("Dongle network ID: %02X-%02X-%02X-%02X",
dbg("Gateway network ID: %02X-%02X-%02X-%02X",
gex_network[0], gex_network[1], gex_network[2], gex_network[3]);
}
void gw_setup_radio(void)
{
bool suc;
dbg("Init NRF");
NRF_Init(NRF_SPEED_2M);
compute_network_id();
NRF_SetBaseAddress(gex_network);
// TODO by config
uint8_t pipenum;
suc = NRF_AddPipe(0x01, &pipenum);
dbg("Pipe added? %d, num %d", (int)suc, (int)pipenum);
NRF_ModeRX(); // base state is RX
// dbg("Send a packet");
//
// suc = NRF_SendPacket(pipenum, (uint8_t *) "AHOJ", 5);
// dbg("Suc? %d", (int)suc);
}
void EXTI2_IRQHandler(void)
{
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_2);
struct msg_data m;
m.msg_type = MSG_TYPE_DATA;
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_2);
uint8_t pipenum;
m.length = NRF_ReceivePacket(m.data, &pipenum);
if (m.length == 0) {
dbg("IRQ but no msg!");
}
else {
dbg("Msg RXd from nordic!");
dbg_nrf("Msg RXd from nordic!");
m.dev_addr = NRF_PipeNum2Addr(pipenum);

@ -106,7 +106,7 @@ void MX_GPIO_Init(void)
EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_2;
EXTI_InitStruct.LineCommand = ENABLE;
EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING;
EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_FALLING;
LL_EXTI_Init(&EXTI_InitStruct);
NVIC_EnableIRQ(EXTI2_IRQn);

@ -82,6 +82,8 @@ void SystemClock_Config(void);
/* USER CODE END 0 */
extern void EXTI2_IRQHandler(void);
/**
* @brief The application entry point.
*
@ -130,16 +132,19 @@ int main(void)
/* Infinite loop */
/* USER CODE BEGIN WHILE */
int cnt = 0;
uint8_t buff[MQ_SLOT_LEN];
while (1) {
if (cnt++ > 500000) {
LL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
cnt = 0;
}
uint8_t buff[MQ_SLOT_LEN];
if (!usb_tx_busy && mq_can_read(&usb_inq)) {
mq_read(&usb_inq, buff);
CDC_Transmit_FS(buff, MQ_SLOT_LEN);
if (mq_can_read(&usb_inq)) {
if (!usb_tx_busy) {
mq_read(&usb_inq, buff);
CDC_Transmit_FS(buff, MQ_SLOT_LEN);
}
}
}
/* USER CODE END 3 */

@ -139,9 +139,6 @@ static uint8_t spi(uint8_t tx) {
RD_CONFIG_EN_CRC | \
RD_CONFIG_CRCO)
#define CEHIGH CE(1)
#define CELOW CE(0)
static inline uint8_t CS(uint8_t hl)
{
if (hl == 1) {
@ -169,7 +166,19 @@ static uint8_t NRF_WriteRegister(uint8_t reg, uint8_t value)
status = spi(CMD_WRITE_REG | reg);
spi(value);
}
dbg("Wr[0x%02x] := 0x%02x", (int)reg, (int) value);
dbg_nrf("Wr[0x%02x] := 0x%02x", (int)reg, (int) value);
uint8_t reg_val = 0;
CHIPSELECT {
spi(CMD_READ_REG | reg);
reg_val = spi(0);
}
dbg_nrf(" verify 0x%02x", (int)reg_val);
if (reg_val != value)
dbg_nrf(" !!!");
else
dbg_nrf(" OK");
return status;
}
@ -180,7 +189,7 @@ static uint8_t NRF_ReadRegister(uint8_t reg)
spi(CMD_READ_REG | reg);
reg_val = spi(0);
}
dbg("Rd[0x%02x] = 0x%02x", (int)reg, (int) reg_val);
dbg_nrf("Rd[0x%02x] = 0x%02x", (int)reg, (int) reg_val);
return reg_val;
}
@ -226,7 +235,7 @@ void NRF_SetBaseAddress(const uint8_t *Bytes4)
void NRF_SetRxAddress(uint8_t pipenum, uint8_t AddrByte)
{
if (pipenum > 5) {
dbg("!! bad pipe %d", pipenum);
dbg_nrf("!! bad pipe %d", pipenum);
return;
}
@ -234,13 +243,13 @@ void NRF_SetRxAddress(uint8_t pipenum, uint8_t AddrByte)
nrf_pipe_addr[pipenum] = AddrByte;
dbg("Set Rx addr (pipe %d) = 0x%02x", (int)pipenum, AddrByte);
dbg_nrf("Set Rx addr (pipe %d) = 0x%02x", (int)pipenum, AddrByte);
if (pipenum == 0) {
dbg("W ADDR_PA0: %02X-%02X-%02X-%02X-%02X", nrf_base_address[0], nrf_base_address[1], nrf_base_address[2], nrf_base_address[3], nrf_base_address[4]);
dbg_nrf("W ADDR_PA0: %02X-%02X-%02X-%02X-%02X", nrf_base_address[0], nrf_base_address[1], nrf_base_address[2], nrf_base_address[3], nrf_base_address[4]);
NRF_WriteBuffer(RG_RX_ADDR_P0, nrf_base_address, 5);
}
else if (pipenum == 1) {
dbg("W ADDR_PA1: %02X-%02X-%02X-%02X-%02X", nrf_base_address[0], nrf_base_address[1], nrf_base_address[2], nrf_base_address[3], nrf_base_address[4]);
dbg_nrf("W ADDR_PA1: %02X-%02X-%02X-%02X-%02X", nrf_base_address[0], nrf_base_address[1], nrf_base_address[2], nrf_base_address[3], nrf_base_address[4]);
NRF_WriteBuffer(RG_RX_ADDR_P1, nrf_base_address, 5);
}
else {
@ -278,6 +287,7 @@ uint8_t NRF_Addr2PipeNum(uint8_t addr)
void NRF_EnablePipe(uint8_t pipenum)
{
dbg_nrf("Enable pipe num %d", (int)pipenum);
uint8_t enabled = NRF_ReadRegister(RG_EN_RXADDR);
enabled |= 1 << pipenum;
NRF_WriteRegister(RG_EN_RXADDR, enabled);
@ -298,34 +308,39 @@ static void NRF_SetTxAddress(uint8_t SendTo)
{
nrf_base_address[4] = SendTo;
dbg("W Tx_ADDR + Rx0: %02X-%02X-%02X-%02X-%02X", nrf_base_address[0], nrf_base_address[1], nrf_base_address[2], nrf_base_address[3], nrf_base_address[4]);
dbg_nrf("W Tx_ADDR + Rx0: %02X-%02X-%02X-%02X-%02X",
nrf_base_address[0], nrf_base_address[1], nrf_base_address[2], nrf_base_address[3], nrf_base_address[4]);
NRF_WriteBuffer(RG_TX_ADDR, nrf_base_address, 5);
NRF_WriteBuffer(RG_RX_ADDR_P0, nrf_base_address, 5); // the ACK will come to pipe 0
}
void NRF_PowerDown(void)
{
dbg("PDn");
CELOW;
dbg_nrf("PDn");
CE(0);
NRF_WriteRegister(RG_CONFIG, ModeBits);
}
void NRF_ModeTX(void)
{
dbg("Tx Mode");
dbg_nrf("Tx Mode");
CELOW;
CE(0);
uint8_t m = NRF_ReadRegister(RG_CONFIG);
NRF_WriteRegister(RG_CONFIG, ModeBits | RD_CONFIG_PWR_UP);
if ((m & RD_CONFIG_PWR_UP) == 0) LL_mDelay(5);
if ((m & RD_CONFIG_PWR_UP) == 0) {
// switching on
LL_mDelay(5);
}
}
void NRF_ModeRX(void)
{
dbg("Rx Mode");
dbg_nrf("Rx Mode");
NRF_WriteRegister(RG_CONFIG, ModeBits | RD_CONFIG_PWR_UP | RD_CONFIG_PRIM_RX);
NRF_SetRxAddress(0, nrf_pipe_addr[0]); // set the P0 address - it was changed during Rx for ACK reception
CEHIGH;
CE(1);
//if ((m&2)==0) LL_mDelay()(5); You don't need to wait. Just nothing will come for 5ms or more
}
@ -363,7 +378,9 @@ uint8_t NRF_ReceivePacket(uint8_t *Packet, uint8_t *PipeNum)
uint8_t pw = 0, status;
if (!NRF_IsRxPacket()) return 0;
CELOW;
const uint8_t orig_conf = NRF_ReadRegister(RG_CONFIG);
CE(0); // quit Rx mode - go idle
CHIPSELECT {
status = spi(CMD_RD_RX_PL_WIDTH);
pw = spi(0);
@ -373,19 +390,25 @@ uint8_t NRF_ReceivePacket(uint8_t *Packet, uint8_t *PipeNum)
CHIPSELECT {
spi(CMD_FLUSH_RX);
}
NRF_WriteRegister(RG_STATUS, RD_STATUS_RX_DR);
return 0;
pw = 0;
} else {
// Read the reception pipe number
*PipeNum = ((status & RD_STATUS_RX_PNO) >> 1);
CHIPSELECT {
spi(CMD_RD_RX_PLD);
for (uint8_t i = 0; i < pw; i++) Packet[i] = spi(0);
}
}
NRF_WriteRegister(RG_STATUS, RD_STATUS_RX_DR); // Clear the RX_DR interrupt
// Read the reception pipe number
*PipeNum = (status & RD_STATUS_RX_PNO) >> 1;
CHIPSELECT {
spi(CMD_RD_RX_PLD);
for (uint8_t i = 0; i < pw; i++) Packet[i] = spi(0);
if ((orig_conf & RD_CONFIG_PWR_UP) == 0) {
dbg_nrf("going back PwrDn");
NRF_PowerDown();
}
else if ((orig_conf & RD_CONFIG_PRIM_RX) == RD_CONFIG_PRIM_RX) {
dbg_nrf("going back PwrUp+Rx");
NRF_ModeRX();
}
NRF_WriteRegister(RG_STATUS, RD_STATUS_RX_DR); // Clear the RX_DR interrupt
CEHIGH;
return pw;
}
@ -398,14 +421,14 @@ bool NRF_IsRxPacket(void)
bool NRF_SendPacket(uint8_t PipeNum, const uint8_t *Packet, uint8_t Length)
{
if (!nrf_pipe_enabled[PipeNum]) {
dbg("!! Pipe %d not enabled", PipeNum);
dbg_nrf("!! Pipe %d not enabled", PipeNum);
return 0;
}
const uint8_t orig_conf = NRF_ReadRegister(RG_CONFIG);
CELOW;
CE(0);
NRF_ModeTX(); // Make sure in TX mode
NRF_SetTxAddress(nrf_pipe_addr[PipeNum]);
NRF_SetTxAddress(nrf_pipe_addr[PipeNum]); // this sets the Tx addr and also pipe 0 addr for ACK
CHIPSELECT {
spi(CMD_FLUSH_TX);
@ -416,25 +439,27 @@ bool NRF_SendPacket(uint8_t PipeNum, const uint8_t *Packet, uint8_t Length)
for (uint8_t i = 0; i < Length; i++) spi(Packet[i]);
};
CEHIGH;
_delay_us(15); // At least 10 us
CELOW;
// CE pulse
CE(1);
_delay_us(20); // At least 10 us
CE(0);
uint8_t st = 0;
while ((st & (RD_STATUS_MAX_RT|RD_STATUS_TX_DS)) == 0) {
st = NRF_ReadStatus(); // Packet acked or timed out
}
dbg("Send status: MAX_RT %d, SENT %d", (st&RD_STATUS_MAX_RT) != 0, (st&RD_STATUS_TX_DS) != 0);
dbg_nrf("Send status: 0x%02x - MAX_RT %d, SENT %d", (int)st,
(st&RD_STATUS_MAX_RT) != 0, (st&RD_STATUS_TX_DS) != 0);
NRF_WriteRegister(RG_STATUS, st & (RD_STATUS_MAX_RT|RD_STATUS_TX_DS)); // Clear the bit
if ((orig_conf & RD_CONFIG_PWR_UP) == 0) {
dbg("going back PwrDn");
dbg_nrf("going back PwrDn");
NRF_PowerDown();
}
else if ((orig_conf & RD_CONFIG_PRIM_RX) == RD_CONFIG_PRIM_RX) {
dbg("going back PwrUp+Rx");
dbg_nrf("going back PwrUp+Rx");
NRF_ModeRX();
}
@ -455,27 +480,35 @@ void NRF_Init(uint8_t pSpeed)
{
// Set the required output pins
NSS(1);
CELOW;
CE(0);
LL_mDelay(200);
for (int i = 0; i < 6; i++) {
nrf_pipe_addr[i] = 0;
nrf_pipe_enabled[i] = 0;
}
// clear flags etc
NRF_PowerDown();
CHIPSELECT { spi(CMD_FLUSH_RX); }
CHIPSELECT { spi(CMD_FLUSH_TX); }
NRF_WriteRegister(RG_STATUS, 0x70);
NRF_WriteRegister(RG_CONFIG, ModeBits);
NRF_WriteRegister(RG_SETUP_AW, 0b11); // 5 byte addresses
// default
// NRF_EnablePipe(0);
NRF_WriteRegister(RG_EN_RXADDR, 0x00); // disable all
NRF_WriteRegister(RG_SETUP_RETR, 0x18); // 8 retries
NRF_WriteRegister(RG_RF_CH, 2); // channel 2 NO HIGHER THAN 83 in USA!
NRF_WriteRegister(RG_SETUP_RETR, 0x18); // 8 retries, 500 ms
NRF_WriteRegister(RG_RF_CH, 7); // channel 2 NO HIGHER THAN 83 in USA!
NRF_WriteRegister(RG_RF_SETUP, pSpeed);
NRF_WriteRegister(RG_DYNPD, 0b111111); // Dynamic packet length
NRF_WriteRegister(RG_FEATURE, 0b100); // Enable dynamic payload, and no payload in the ack.
for (int i = 0; i < 6; i++) {
NRF_WriteRegister(RG_RX_PW_P0+i, 32); // Receive 32 byte packets - XXX this is probably not needed with dynamic length
}
//NRFModePowerDown(); // Already in power down mode, dummy
// for (int i = 0; i < 6; i++) {
// NRF_WriteRegister(RG_RX_PW_P0+i, 32); // Receive 32 byte packets - XXX this is probably not needed with dynamic length
// }
}

@ -119,7 +119,7 @@ void MX_SPI1_Init(void)
SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;
SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;
SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;
SPI_InitStruct.ClockPhase = LL_SPI_PHASE_2EDGE;
SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE;
SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8;
SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;

Loading…
Cancel
Save