From 0bce53403f8d37427f0dc6b65fed6b11d04950d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Fri, 4 May 2018 22:18:52 +0200 Subject: [PATCH] gex zero support, also nrf remapping based on platform and optional disable --- TinyFrame/TF_Integration.c | 2 + comm/iface_nordic.c | 23 ++++++++-- comm/iface_nordic.h | 4 ++ comm/interfaces.c | 10 ++++- comm/nrf.c | 19 +++++++- comm/nrf.h | 10 ++++- comm/nrf_pins.h | 86 +++++++++++++++++++++++++++---------- framework/system_settings.c | 4 ++ platform/debug_uart.c | 2 +- platform/irq_dispatcher.c | 7 ++- platform/plat_compat.h | 19 ++++++++ platform/platform.c | 10 ++++- 12 files changed, 164 insertions(+), 32 deletions(-) diff --git a/TinyFrame/TF_Integration.c b/TinyFrame/TF_Integration.c index 31d982f..b1ebd2b 100644 --- a/TinyFrame/TF_Integration.c +++ b/TinyFrame/TF_Integration.c @@ -28,9 +28,11 @@ void TF_WriteImpl(TinyFrame *tf, const uint8_t *buff, uint32_t len) else if (gActiveComport == COMPORT_USART) { iface_uart_transmit(buff, len); } +#if SUPPORT_NRF else if (gActiveComport == COMPORT_NORDIC) { iface_nordic_transmit(buff, len); } +#endif // SUPPORT_NRF else { // TODO other transports trap("not implemented."); diff --git a/comm/iface_nordic.c b/comm/iface_nordic.c index 3bef6bf..d73bac7 100644 --- a/comm/iface_nordic.c +++ b/comm/iface_nordic.c @@ -11,6 +11,8 @@ #include "system_settings.h" #include "utils/hexdump.h" +#if SUPPORT_NRF + extern osSemaphoreId semVcomTxReadyHandle; #define RX_PIPE_NUM 0 @@ -70,15 +72,17 @@ bool iface_nordic_init(void) hw_periph_clock_enable(NRF_SPI); // SPI pins - assert_param(E_SUCCESS == hw_configure_gpiorsc_af(NRF_R_SCK, NRF_SPI_AF)); - assert_param(E_SUCCESS == hw_configure_gpiorsc_af(NRF_R_MOSI, NRF_SPI_AF)); - assert_param(E_SUCCESS == hw_configure_gpiorsc_af(NRF_R_MISO, NRF_SPI_AF)); + assert_param(E_SUCCESS == hw_configure_gpiorsc_af(NRF_R_SCK, NRF_SCK_AF)); + assert_param(E_SUCCESS == hw_configure_gpiorsc_af(NRF_R_MOSI, NRF_MOSI_AF)); + assert_param(E_SUCCESS == hw_configure_gpiorsc_af(NRF_R_MISO, NRF_MISO_AF)); // Manual pins LL_GPIO_SetPinMode(NRF_NSS_GPIO_Port, NRF_NSS_Pin, LL_GPIO_MODE_OUTPUT); LL_GPIO_SetPinMode(NRF_CE_GPIO_Port, NRF_CE_Pin, LL_GPIO_MODE_OUTPUT); + LL_GPIO_SetPinMode(NRF_RST_GPIO_Port, NRF_RST_Pin, LL_GPIO_MODE_OUTPUT); LL_GPIO_SetPinMode(NRF_IRQ_GPIO_Port, NRF_IRQ_Pin, LL_GPIO_MODE_INPUT); + // set up SPI LL_SPI_Disable(NRF_SPI); { LL_SPI_SetBaudRatePrescaler(NRF_SPI, LL_SPI_BAUDRATEPRESCALER_DIV32); @@ -97,11 +101,19 @@ bool iface_nordic_init(void) } LL_SPI_Enable(NRF_SPI); + // reset the radio / enable its power supply + NRF_Reset(1); + LL_mDelay(5); + NRF_Reset(0); dbg("configure nrf module"); // Now configure the radio - NRF_Init(NRF_SPEED_2M); // TODO configurable speed + if (!NRF_Init(NRF_SPEED_2M)) {// TODO configurable speed - also maybe better to use slower + dbg("--- NRF not present!"); + return false; + } + NRF_SetChannel(SystemSettings.nrf_channel); NRF_SetBaseAddress(SystemSettings.nrf_network); NRF_SetRxAddress(RX_PIPE_NUM, SystemSettings.nrf_address); @@ -133,6 +145,7 @@ void iface_nordic_deinit(void) hw_deinit_pin_rsc(NRF_R_NSS); hw_deinit_pin_rsc(NRF_R_CE); hw_deinit_pin_rsc(NRF_R_IRQ); + hw_deinit_pin_rsc(NRF_R_RST); } // FIXME @@ -173,3 +186,5 @@ void iface_nordic_transmit(const uint8_t *buff, uint32_t len) // give when it's done xSemaphoreGive(semVcomTxReadyHandle); // similar to how it's done in USB - this is called in the Tx Done handler } + +#endif // SUPPORT_NRF diff --git a/comm/iface_nordic.h b/comm/iface_nordic.h index c07d739..1e09d6f 100644 --- a/comm/iface_nordic.h +++ b/comm/iface_nordic.h @@ -7,6 +7,8 @@ #include "platform.h" +#if SUPPORT_NRF + void iface_nordic_claim_resources(void); void iface_nordic_free_resources(void); @@ -17,4 +19,6 @@ bool iface_nordic_init(void); void iface_nordic_transmit(const uint8_t *buff, uint32_t len); +#endif // SUPPORT_NRF + #endif //GEX_F072_IFACE_NORDIC_H diff --git a/comm/interfaces.c b/comm/interfaces.c index 0ab281c..28e6b4a 100644 --- a/comm/interfaces.c +++ b/comm/interfaces.c @@ -16,6 +16,7 @@ #include "iface_usb.h" #include "iface_nordic.h" +// those correspond to the ENUM values const char * COMPORT_NAMES[] = { "NONE", "USB", @@ -24,7 +25,6 @@ const char * COMPORT_NAMES[] = { "LORA", }; - enum ComportSelection gActiveComport = COMPORT_USB; // start with USB so the handlers work correctly initially static uint32_t last_switch_time = 0; // started with USB @@ -86,9 +86,11 @@ void com_claim_resources_for_alt_transfers(void) iface_uart_claim_resources(); } +#if SUPPORT_NRF if (SystemSettings.use_comm_nordic) { iface_nordic_claim_resources(); } +#endif // SUPPORT_NRF } /** Release resources allocated for alternate transfers */ @@ -98,9 +100,11 @@ void com_release_resources_for_alt_transfers(void) iface_uart_free_resources(); } +#if SUPPORT_NRF if (SystemSettings.use_comm_nordic) { iface_nordic_free_resources(); } +#endif // SUPPORT_NRF } @@ -115,9 +119,11 @@ static bool configure_interface(enum ComportSelection iface) else if (gActiveComport == COMPORT_USART) { iface_uart_deinit(); } +#if SUPPORT_NRF else if (gActiveComport == COMPORT_NORDIC) { iface_nordic_deinit(); } +#endif // SUPPORT_NRF gActiveComport = iface; @@ -130,9 +136,11 @@ static bool configure_interface(enum ComportSelection iface) else if (iface == COMPORT_USART) { return iface_uart_init(); } +#if SUPPORT_NRF else if (iface == COMPORT_NORDIC) { return iface_nordic_init(); } +#endif // SUPPORT_NRF #if 0 else if (iface == COMPORT_LORA) { // Try to configure nordic diff --git a/comm/nrf.c b/comm/nrf.c index 45670e2..00a7768 100644 --- a/comm/nrf.c +++ b/comm/nrf.c @@ -73,6 +73,17 @@ static uint8_t spi(uint8_t tx) { return LL_SPI_ReceiveData8(NRF_SPI); } +void NRF_Reset(bool enable_reset) +{ + if (enable_reset) { + // go HIGH - this closes the PMOS + LL_GPIO_SetOutputPin(NRF_RST_GPIO_Port, NRF_RST_Pin); + } else { + // LOW - open PMOS, enable power + LL_GPIO_ResetOutputPin(NRF_RST_GPIO_Port, NRF_RST_Pin); + } +} + //------- /* @@ -492,7 +503,7 @@ bool NRF_SendPacket(uint8_t PipeNum, const uint8_t *Packet, uint8_t Length) return 0 != (st & RD_STATUS_TX_DS); // success } -void NRF_Init(uint8_t pSpeed) +bool NRF_Init(uint8_t pSpeed) { // Set the required output pins NSS(1); @@ -505,6 +516,10 @@ void NRF_Init(uint8_t pSpeed) nrf_pipe_enabled[i] = 0; } + // this is a test if there's anything present + uint8_t awreg = NRF_ReadRegister(RG_SETUP_AW); + if (awreg == 0 || awreg > 3) return false; + // clear flags etc NRF_PowerDown(); CHIPSELECT { spi(CMD_FLUSH_RX); } @@ -527,4 +542,6 @@ void NRF_Init(uint8_t pSpeed) // 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 // } + + return true; } diff --git a/comm/nrf.h b/comm/nrf.h index e671d71..2f0b2bf 100644 --- a/comm/nrf.h +++ b/comm/nrf.h @@ -32,13 +32,21 @@ * Initialize the NRF module * * @param pSpeed + * @return success (0 if device not detected) */ -void NRF_Init(uint8_t pSpeed); +bool NRF_Init(uint8_t pSpeed); #define NRF_SPEED_500k 0b00100110 #define NRF_SPEED_2M 0b00001110 #define NRF_SPEED_1M 0b00000110 +/** + * Set the reset pin (this is a PMOS controlling its power) + * + * @param enable_reset 1 to go into reset, 0 to enter operational state (will need some time to become ready) + */ +void NRF_Reset(bool enable_reset); + /** * Set reception address * @param pipenum - pipe to set diff --git a/comm/nrf_pins.h b/comm/nrf_pins.h index c30b4aa..f1702da 100644 --- a/comm/nrf_pins.h +++ b/comm/nrf_pins.h @@ -7,27 +7,69 @@ #include "platform.h" -// TODO move those to plat_compat? -#define NRF_SPI SPI1 -#define NRF_R_SPI R_SPI1 - -#define NRF_IRQ_Pin LL_GPIO_PIN_10 -#define NRF_IRQ_GPIO_Port GPIOB -#define NRF_R_IRQ R_PB10 -#define NRF_EXTI_LINENUM 10 -#define NRF_SYSCFG_EXTI_PORT LL_SYSCFG_EXTI_PORTB - -#define NRF_NSS_Pin LL_GPIO_PIN_11 -#define NRF_NSS_GPIO_Port GPIOB -#define NRF_R_NSS R_PB11 - -#define NRF_CE_Pin LL_GPIO_PIN_12 -#define NRF_CE_GPIO_Port GPIOB -#define NRF_R_CE R_PB12 - -#define NRF_R_SCK R_PA5 -#define NRF_R_MISO R_PA6 -#define NRF_R_MOSI R_PA7 -#define NRF_SPI_AF LL_GPIO_AF_0 +#if defined(GEX_PLAT_F072_DISCOVERY) || defined(GEX_PLAT_F072_HUB) + + // This config was used only for development when NRF was enabled for those platforms. It is normally disabled. + #define NRF_SPI SPI1 + #define NRF_R_SPI R_SPI1 + + #define NRF_IRQ_Pin LL_GPIO_PIN_10 + #define NRF_IRQ_GPIO_Port GPIOB + #define NRF_R_IRQ R_PB10 + #define NRF_EXTI_LINENUM 10 + #define NRF_SYSCFG_EXTI_PORT LL_SYSCFG_EXTI_PORTB + + #define NRF_NSS_Pin LL_GPIO_PIN_11 + #define NRF_NSS_GPIO_Port GPIOB + #define NRF_R_NSS R_PB11 + + #define NRF_CE_Pin LL_GPIO_PIN_12 + #define NRF_CE_GPIO_Port GPIOB + #define NRF_R_CE R_PB12 + + #define NRF_RST_Pin LL_GPIO_PIN_13 + #define NRF_RST_GPIO_Port GPIOB + #define NRF_R_RST R_PB13 + + #define NRF_R_SCK R_PA5 + #define NRF_SCK_AF LL_GPIO_AF_0 + #define NRF_R_MISO R_PA6 + #define NRF_MISO_AF LL_GPIO_AF_0 + #define NRF_R_MOSI R_PA7 + #define NRF_MOSI_AF LL_GPIO_AF_0 + +#elif defined(GEX_PLAT_F072_ZERO) + + #define NRF_SPI SPI2 + #define NRF_R_SPI R_SPI2 + + #define NRF_IRQ_Pin LL_GPIO_PIN_15 + #define NRF_IRQ_GPIO_Port GPIOC + #define NRF_R_IRQ R_PC15 + #define NRF_EXTI_LINENUM 15 + #define NRF_SYSCFG_EXTI_PORT LL_SYSCFG_EXTI_PORTC + + #define NRF_NSS_Pin LL_GPIO_PIN_13 + #define NRF_NSS_GPIO_Port GPIOC + #define NRF_R_NSS R_PC13 + + #define NRF_CE_Pin LL_GPIO_PIN_14 + #define NRF_CE_GPIO_Port GPIOC + #define NRF_R_CE R_PC14 + + #define NRF_RST_Pin LL_GPIO_PIN_12 + #define NRF_RST_GPIO_Port GPIOC + #define NRF_R_RST R_PC12 + + #define NRF_R_SCK R_PB13 + #define NRF_SCK_AF LL_GPIO_AF_0 + #define NRF_R_MISO R_PC2 + #define NRF_MISO_AF LL_GPIO_AF_1 + #define NRF_R_MOSI R_PC3 + #define NRF_MOSI_AF LL_GPIO_AF_1 + +#else + #error "Missing NRF config for this platform." +#endif #endif //GEX_F072_NRF_PINS_H diff --git a/framework/system_settings.c b/framework/system_settings.c index affead3..4767211 100644 --- a/framework/system_settings.c +++ b/framework/system_settings.c @@ -196,6 +196,7 @@ void systemsettings_build_ini(IniWriter *iw) iw_entry_s(iw, "com-uart", str_yn(SystemSettings.use_comm_uart)); iw_entry_d(iw, "com-uart-baud", SystemSettings.comm_uart_baud); +#if SUPPORT_NRF iw_cmt_newline(iw); iw_comment(iw, "nRF24L01+ radio"); iw_entry_s(iw, "com-nrf", str_yn(SystemSettings.use_comm_nordic)); @@ -212,6 +213,7 @@ void systemsettings_build_ini(IniWriter *iw) iw_comment(iw, "Node address (1-255)"); iw_entry(iw, "nrf-address", "%d", (int)SystemSettings.nrf_address); +#endif // SUPPORT_NRF // those aren't implement yet, don't tease the user // TODO show pin-out, extra settings if applicable @@ -274,6 +276,7 @@ bool systemsettings_load_ini(const char *restrict key, const char *restrict valu if (suc) SystemSettings.comm_uart_baud = baud; } +#if SUPPORT_NRF if (streq(key, "com-nrf")) { bool yn = cfg_bool_parse(value, &suc); if (suc) SystemSettings.use_comm_nordic = yn; @@ -290,6 +293,7 @@ bool systemsettings_load_ini(const char *restrict key, const char *restrict valu if (streq(key, "nrf-network")) { cfg_hex_parse(&SystemSettings.nrf_network[0], 4, value, &suc); } +#endif // SUPPORT_NRF #if 0 if (streq(key, "com-lora")) { diff --git a/platform/debug_uart.c b/platform/debug_uart.c index 241f1ac..d0a3ef4 100644 --- a/platform/debug_uart.c +++ b/platform/debug_uart.c @@ -13,7 +13,7 @@ #define DEBUG_USART_BAUD 115200 -#if GEX_PLAT_F072_DISCOVERY || GEX_PLAT_F072_HUB +#if GEX_PLAT_F072_DISCOVERY || GEX_PLAT_F072_HUB || GEX_PLAT_F072_ZERO #define DEBUG_USART USART1 #define DEBUG_USART_RSC R_USART1 diff --git a/platform/irq_dispatcher.c b/platform/irq_dispatcher.c index 068e812..36dd8da 100644 --- a/platform/irq_dispatcher.c +++ b/platform/irq_dispatcher.c @@ -246,7 +246,12 @@ void* irqd_detach(void *periph, IrqCallback callback) return oldArg; } else { - trap("Detach IRQ %p() from %p but %p() bound instead", callback, periph, slot->callback); + // catch bugs, but ignore an attempt to unbind when not bound + if (slot->callback != NULL) { + trap("Detach IRQ %p() from %p but %p() bound instead", callback, periph, slot->callback); + } else { + return NULL; // the arg - none + } } } diff --git a/platform/plat_compat.h b/platform/plat_compat.h index 729de04..aeb44f7 100644 --- a/platform/plat_compat.h +++ b/platform/plat_compat.h @@ -72,6 +72,8 @@ // PLAT_NO_AFNUM - legacy platform without numbered AF alternatives // PLAT_FULL_XTAL - use two-wire xtal attachment +// SUPPORT_NRF + #if defined(GEX_PLAT_F103_BLUEPILL) // platform name for the version string @@ -189,6 +191,23 @@ // Status LED config #define STATUS_LED_PORT 'A' #define STATUS_LED_PIN 15 // RED LED "UP" + #elif defined(GEX_PLAT_F072_ZERO) + // platform name for the version string + #define GEX_PLATFORM "STM32F072-ZERO" + + #define PLAT_FULL_XTAL 1 + + // Lock jumper config + #define LOCK_JUMPER_PORT 'D' + #define LOCK_JUMPER_PIN 2 + #define PLAT_LOCK_BTN 1 // toggle button instead of a jumper + #define PLAT_LOCK_1CLOSED 1 // toggle button active in log. 1 + + // Status LED config + #define STATUS_LED_PORT 'A' + #define STATUS_LED_PIN 15 // RED LED "UP" + + #define SUPPORT_NRF 1 #else #error Bad platform #endif diff --git a/platform/platform.c b/platform/platform.c index b4dda15..e1459a1 100644 --- a/platform/platform.c +++ b/platform/platform.c @@ -27,9 +27,11 @@ void plat_init_resources(void) { + // we use |= here, even though return values are not booleans - success is 0, + // thus any problem results in nonzero and the assert will trip. uint32_t rv = 0; - // enable clock for units we use + // periphs available everywhere - enable clock hw_periph_clock_enable(DMA1); #ifdef DMA2 hw_periph_clock_enable(DMA2); @@ -142,6 +144,12 @@ void plat_init_resources(void) // USB rv |= rsc_claim(&UNIT_SYSTEM, R_PA11); rv |= rsc_claim(&UNIT_SYSTEM, R_PA12); + + #if defined(GEX_PLAT_F072_ZERO) + // unconnected pins + rv |= rsc_claim_range(&UNIT_PLATFORM, R_PC0, R_PC1); + rv |= rsc_claim_range(&UNIT_PLATFORM, R_PC4, R_PC9); + #endif } #elif defined(GEX_PLAT_F303_DISCOVERY) // Platform STM32F303VCT