From 99904eec7c6c3e5f5faebf0325d4b6e9ba852162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sun, 8 Apr 2018 21:22:45 +0200 Subject: [PATCH] working version - communication with a single client tested, works --- Inc/nrf.h | 3 ++ Src/gex_gateway.c | 35 +++++-------- Src/gpio.c | 2 +- Src/main.c | 13 +++-- Src/nrf.c | 127 +++++++++++++++++++++++++++++----------------- Src/spi.c | 2 +- 6 files changed, 107 insertions(+), 75 deletions(-) diff --git a/Inc/nrf.h b/Inc/nrf.h index 8c282b9..527b76a 100644 --- a/Inc/nrf.h +++ b/Inc/nrf.h @@ -21,6 +21,9 @@ #include "main.h" +#define dbg_nrf(...) do{}while(0) +//#define dbg_nrf(...) dbg(##__VA_ARGS__) + // Initialize SPI and the Nordic /** diff --git a/Src/gex_gateway.c b/Src/gex_gateway.c index 70508bf..229a982 100644 --- a/Src/gex_gateway.c +++ b/Src/gex_gateway.c @@ -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); diff --git a/Src/gpio.c b/Src/gpio.c index b45c7cc..5ac4fe6 100644 --- a/Src/gpio.c +++ b/Src/gpio.c @@ -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); diff --git a/Src/main.c b/Src/main.c index 37c17fb..cf8f8cc 100644 --- a/Src/main.c +++ b/Src/main.c @@ -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 */ diff --git a/Src/nrf.c b/Src/nrf.c index a2049b1..73c86fd 100644 --- a/Src/nrf.c +++ b/Src/nrf.c @@ -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 +// } } diff --git a/Src/spi.c b/Src/spi.c index 51ba696..d9293ec 100644 --- a/Src/spi.c +++ b/Src/spi.c @@ -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;