sterlinghughes closed pull request #865: hw/drivers/sx1272: Make driver shield compatible and fix driver issues. URL: https://github.com/apache/mynewt-core/pull/865
This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/hw/bsp/nrf52840pdk/src/hal_bsp.c b/hw/bsp/nrf52840pdk/src/hal_bsp.c index 29fdb42b7..8f3d7529c 100644 --- a/hw/bsp/nrf52840pdk/src/hal_bsp.c +++ b/hw/bsp/nrf52840pdk/src/hal_bsp.c @@ -313,3 +313,67 @@ assert(rc == 0); #endif } + +#if MYNEWT_VAL(BSP_USE_HAL_SPI) +void +bsp_spi_read_buf(uint8_t addr, uint8_t *buf, uint8_t size) +{ + int i; + uint8_t rxval; + NRF_SPI_Type *spi; + spi = NRF_SPI0; + + if (size == 0) { + return; + } + + i = -1; + spi->EVENTS_READY = 0; + spi->TXD = (uint8_t)addr; + while (size != 0) { + spi->TXD = 0; + while (!spi->EVENTS_READY) {} + spi->EVENTS_READY = 0; + rxval = (uint8_t)(spi->RXD); + if (i >= 0) { + buf[i] = rxval; + } + size -= 1; + ++i; + if (size == 0) { + while (!spi->EVENTS_READY) {} + spi->EVENTS_READY = 0; + buf[i] = (uint8_t)(spi->RXD); + } + } +} + +void +bsp_spi_write_buf(uint8_t addr, uint8_t *buf, uint8_t size) +{ + uint8_t i; + uint8_t rxval; + NRF_SPI_Type *spi; + + if (size == 0) { + return; + } + + spi = NRF_SPI0; + + spi->EVENTS_READY = 0; + + spi->TXD = (uint8_t)addr; + for (i = 0; i < size; ++i) { + spi->TXD = buf[i]; + while (!spi->EVENTS_READY) {} + rxval = (uint8_t)(spi->RXD); + spi->EVENTS_READY = 0; + } + + while (!spi->EVENTS_READY) {} + rxval = (uint8_t)(spi->RXD); + spi->EVENTS_READY = 0; + (void)rxval; +} +#endif diff --git a/hw/drivers/lora/sx1272/src/sx1272-board.c b/hw/drivers/lora/sx1272/src/sx1272-board.c index ca0e11e2c..9d99f7ad7 100644 --- a/hw/drivers/lora/sx1272/src/sx1272-board.c +++ b/hw/drivers/lora/sx1272/src/sx1272-board.c @@ -113,42 +113,42 @@ void SX1272IoIrqInit( DioIrqHandler **irqHandlers ) if (irqHandlers[0] != NULL) { rc = hal_gpio_irq_init(SX1272_DIO0, irqHandlers[0], NULL, - HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE); + HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_DOWN); assert(rc == 0); hal_gpio_irq_enable(SX1272_DIO0); } if (irqHandlers[1] != NULL) { rc = hal_gpio_irq_init(SX1272_DIO1, irqHandlers[1], NULL, - HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE); + HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_DOWN); assert(rc == 0); hal_gpio_irq_enable(SX1272_DIO1); } if (irqHandlers[2] != NULL) { rc = hal_gpio_irq_init(SX1272_DIO2, irqHandlers[2], NULL, - HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE); + HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_DOWN); assert(rc == 0); hal_gpio_irq_enable(SX1272_DIO2); } if (irqHandlers[3] != NULL) { rc = hal_gpio_irq_init(SX1272_DIO3, irqHandlers[3], NULL, - HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE); + HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_DOWN); assert(rc == 0); hal_gpio_irq_enable(SX1272_DIO3); } if (irqHandlers[4] != NULL) { rc = hal_gpio_irq_init(SX1272_DIO4, irqHandlers[4], NULL, - HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE); + HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_DOWN); assert(rc == 0); hal_gpio_irq_enable(SX1272_DIO4); } if (irqHandlers[5] != NULL) { rc = hal_gpio_irq_init(SX1272_DIO5, irqHandlers[5], NULL, - HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE); + HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_DOWN); assert(rc == 0); hal_gpio_irq_enable(SX1272_DIO5); } @@ -307,10 +307,36 @@ void SX1272SetAntSw( uint8_t opMode ) } OS_EXIT_CRITICAL(sr); } +#else +void SX1272SetAntSwLowPower( bool status ) +{ + (void)status; +} + +void SX1272AntSwInit( void ) +{ + /* + * XXX: consider doing this to save power. Currently the gpio are + * set to rx mode automatically in the IO init function. + */ +} + +void SX1272AntSwDeInit( void ) +{ + /* + * XXX: consider doing this to save power. Currently the gpio are + * set to rx mode automatically in the IO init function. + */ +} + +void SX1272SetAntSw( uint8_t opMode ) +{ + (void)opMode; +} +#endif bool SX1272CheckRfFrequency( uint32_t frequency ) { // Implement check. Currently all frequencies are supported return true; } -#endif diff --git a/hw/drivers/lora/sx1272/src/sx1272-board.h b/hw/drivers/lora/sx1272/src/sx1272-board.h index a4110e948..4c6db70d4 100644 --- a/hw/drivers/lora/sx1272/src/sx1272-board.h +++ b/hw/drivers/lora/sx1272/src/sx1272-board.h @@ -1,127 +1,152 @@ -/* - / _____) _ | | -( (____ _____ ____ _| |_ _____ ____| |__ - \____ \| ___ | (_ _) ___ |/ ___) _ \ - _____) ) ____| | | || |_| ____( (___| | | | -(______/|_____)_|_|_| \__)_____)\____)_| |_| - (C)2013 Semtech - -Description: SX1272 driver specific target board functions implementation - -License: Revised BSD License, see LICENSE.TXT file include in the project - -Maintainer: Miguel Luis and Gregory Cristian -*/ -#ifndef __SX1272_ARCH_H__ -#define __SX1272_ARCH_H__ - -#define RADIO_SPI_IDX MYNEWT_VAL(SX1272_SPI_IDX) - -#if RADIO_SPI_IDX == 0 -#define RADIO_NSS MYNEWT_VAL(SX1272_SPI_CS_PIN) -#else -#error "Invalid SX1272_SPI_IDX value" -#endif - -/*! - * \brief Radio hardware registers initialization definition - * - * \remark Can be automatically generated by the SX1272 GUI (not yet implemented) - */ -#define RADIO_INIT_REGISTERS_VALUE \ -{ \ - { MODEM_FSK , REG_LNA , 0x23 },\ - { MODEM_FSK , REG_RXCONFIG , 0x1E },\ - { MODEM_FSK , REG_RSSICONFIG , 0xD2 },\ - { MODEM_FSK , REG_AFCFEI , 0x01 },\ - { MODEM_FSK , REG_PREAMBLEDETECT , 0xAA },\ - { MODEM_FSK , REG_OSC , 0x07 },\ - { MODEM_FSK , REG_SYNCCONFIG , 0x12 },\ - { MODEM_FSK , REG_SYNCVALUE1 , 0xC1 },\ - { MODEM_FSK , REG_SYNCVALUE2 , 0x94 },\ - { MODEM_FSK , REG_SYNCVALUE3 , 0xC1 },\ - { MODEM_FSK , REG_PACKETCONFIG1 , 0xD8 },\ - { MODEM_FSK , REG_FIFOTHRESH , 0x8F },\ - { MODEM_FSK , REG_IMAGECAL , 0x02 },\ - { MODEM_FSK , REG_DIOMAPPING1 , 0x00 },\ - { MODEM_FSK , REG_DIOMAPPING2 , 0x30 },\ - { MODEM_LORA, REG_LR_DETECTOPTIMIZE , 0x43 },\ - { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },\ -} \ - -/*! - * \brief Initializes the radio I/Os pins interface - */ -void SX1272IoInit( void ); - -/*! - * \brief Initializes DIO IRQ handlers - * - * \param [IN] irqHandlers Array containing the IRQ callback functions - */ -void SX1272IoIrqInit( DioIrqHandler **irqHandlers ); - -/*! - * \brief De-initializes the radio I/Os pins interface. - * - * \remark Useful when going in MCU low power modes - */ -void SX1272IoDeInit( void ); - -/*! - * \brief Sets the radio output power. - * - * \param [IN] power Sets the RF output power - */ -void SX1272SetRfTxPower( int8_t power ); - -/*! - * \brief Gets the board PA selection configuration - * - * \param [IN] channel Channel frequency in Hz - * \retval PaSelect RegPaConfig PaSelect value - */ -uint8_t SX1272GetPaSelect( uint32_t channel ); - -/*! - * \brief Set the RF Switch I/Os pins in Low Power mode - * - * \param [IN] status enable or disable - */ -void SX1272SetAntSwLowPower( bool status ); - -/*! - * \brief Initializes the RF Switch I/Os pins interface - */ -void SX1272AntSwInit( void ); - -/*! - * \brief De-initializes the RF Switch I/Os pins interface - * - * \remark Needed to decrease the power consumption in MCU low power modes - */ -void SX1272AntSwDeInit( void ); - -/*! - * \brief Controls the antenna switch if necessary. - * - * \remark see errata note - * - * \param [IN] opMode Current radio operating mode - */ -void SX1272SetAntSw( uint8_t opMode ); - -/*! - * \brief Checks if the given RF frequency is supported by the hardware - * - * \param [IN] frequency RF frequency to be checked - * \retval isSupported [true: supported, false: unsupported] - */ -bool SX1272CheckRfFrequency( uint32_t frequency ); - -/*! - * Radio hardware and global parameters - */ -extern SX1272_t SX1272; - -#endif // __SX1272_ARCH_H__ +/* + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + +Description: SX1272 driver specific target board functions implementation + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis and Gregory Cristian +*/ +#ifndef __SX1272_ARCH_H__ +#define __SX1272_ARCH_H__ + +#define RADIO_SPI_IDX MYNEWT_VAL(SX1272_SPI_IDX) +#if RADIO_SPI_IDX != 0 +#error "Invalid SX1272_SPI_IDX value. Must be zero" +#endif + +#if MYNEWT_VAL(SX1272_SPI_CS_PIN) == -1 +#error "Must set SX1272_SPI_CS_PIN pin (spi slave select)" +#else +#define RADIO_NSS MYNEWT_VAL(SX1272_SPI_CS_PIN) +#endif + +#define SX1272_DIO0 MYNEWT_VAL(SX1272_DIO0_PIN) +#define SX1272_DIO1 MYNEWT_VAL(SX1272_DIO1_PIN) +#define SX1272_DIO2 MYNEWT_VAL(SX1272_DIO2_PIN) +#define SX1272_DIO3 MYNEWT_VAL(SX1272_DIO3_PIN) +#define SX1272_DIO4 MYNEWT_VAL(SX1272_DIO4_PIN) +#define SX1272_DIO5 MYNEWT_VAL(SX1272_DIO5_PIN) + +#if MYNEWT_VAL(SX1272_RESET_PIN) == -1 +#error "Must set SX1272_RESET_PIN pin (spi slave select)" +#else +#define SX1272_NRESET MYNEWT_VAL(SX1272_RESET_PIN) +#endif + +#if MYNEWT_VAL(SX1272_HAS_ANT_SW) +#define SX1272_RXTX MYNEWT_VAL(SX1272_RXTX_PIN) +#endif + +#if MYNEWT_VAL(SX1272_HAS_COMP_ANT_SW) +#define SX1272_RXTX MYNEWT_VAL(SX1272_RXTX_PIN) +#define SX1272_N_RXTX MYNEWT_VAL(SX1272_N_RXTX_PIN) +#endif + +/*! + * \brief Radio hardware registers initialization definition + * + * \remark Can be automatically generated by the SX1272 GUI (not yet implemented) + */ +#define RADIO_INIT_REGISTERS_VALUE \ +{ \ + { MODEM_FSK , REG_LNA , 0x23 },\ + { MODEM_FSK , REG_RXCONFIG , 0x1E },\ + { MODEM_FSK , REG_RSSICONFIG , 0xD2 },\ + { MODEM_FSK , REG_AFCFEI , 0x01 },\ + { MODEM_FSK , REG_PREAMBLEDETECT , 0xAA },\ + { MODEM_FSK , REG_OSC , 0x07 },\ + { MODEM_FSK , REG_SYNCCONFIG , 0x12 },\ + { MODEM_FSK , REG_SYNCVALUE1 , 0xC1 },\ + { MODEM_FSK , REG_SYNCVALUE2 , 0x94 },\ + { MODEM_FSK , REG_SYNCVALUE3 , 0xC1 },\ + { MODEM_FSK , REG_PACKETCONFIG1 , 0xD8 },\ + { MODEM_FSK , REG_FIFOTHRESH , 0x8F },\ + { MODEM_FSK , REG_IMAGECAL , 0x02 },\ + { MODEM_FSK , REG_DIOMAPPING1 , 0x00 },\ + { MODEM_FSK , REG_DIOMAPPING2 , 0x30 },\ + { MODEM_LORA, REG_LR_DETECTOPTIMIZE , 0x43 },\ + { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },\ +} \ + +/*! + * \brief Initializes the radio I/Os pins interface + */ +void SX1272IoInit( void ); + +/*! + * \brief Initializes DIO IRQ handlers + * + * \param [IN] irqHandlers Array containing the IRQ callback functions + */ +void SX1272IoIrqInit( DioIrqHandler **irqHandlers ); + +/*! + * \brief De-initializes the radio I/Os pins interface. + * + * \remark Useful when going in MCU low power modes + */ +void SX1272IoDeInit( void ); + +/*! + * \brief Sets the radio output power. + * + * \param [IN] power Sets the RF output power + */ +void SX1272SetRfTxPower( int8_t power ); + +/*! + * \brief Gets the board PA selection configuration + * + * \param [IN] channel Channel frequency in Hz + * \retval PaSelect RegPaConfig PaSelect value + */ +uint8_t SX1272GetPaSelect( uint32_t channel ); + +/*! + * \brief Set the RF Switch I/Os pins in Low Power mode + * + * \param [IN] status enable or disable + */ +void SX1272SetAntSwLowPower( bool status ); + +/*! + * \brief Initializes the RF Switch I/Os pins interface + */ +void SX1272AntSwInit( void ); + +/*! + * \brief De-initializes the RF Switch I/Os pins interface + * + * \remark Needed to decrease the power consumption in MCU low power modes + */ +void SX1272AntSwDeInit( void ); + +/*! + * \brief Controls the antenna switch if necessary. + * + * \remark see errata note + * + * \param [IN] opMode Current radio operating mode + */ +void SX1272SetAntSw( uint8_t opMode ); + +/*! + * \brief Checks if the given RF frequency is supported by the hardware + * + * \param [IN] frequency RF frequency to be checked + * \retval isSupported [true: supported, false: unsupported] + */ +bool SX1272CheckRfFrequency( uint32_t frequency ); + +/*! + * Radio hardware and global parameters + */ +extern SX1272_t SX1272; + +#endif // __SX1272_ARCH_H__ diff --git a/hw/drivers/lora/sx1272/src/sx1272.c b/hw/drivers/lora/sx1272/src/sx1272.c index 2c6074c59..326eab25b 100644 --- a/hw/drivers/lora/sx1272/src/sx1272.c +++ b/hw/drivers/lora/sx1272/src/sx1272.c @@ -14,6 +14,7 @@ Maintainer: Miguel Luis and Gregory Cristian */ #include <math.h> #include <string.h> +#include <stdlib.h> #include "sysinit/sysinit.h" #include "syscfg/syscfg.h" #include "hal/hal_gpio.h" @@ -31,6 +32,13 @@ Maintainer: Miguel Luis and Gregory Cristian #define SX1272_TIMER_NUM MYNEWT_VAL(LORA_MAC_TIMER_NUM) #endif +/* XXX: dummy for now to read sx1272 */ +#if MYNEWT_VAL(BSP_USE_HAL_SPI) +void bsp_spi_read_buf(uint8_t addr, uint8_t *buf, uint8_t size); +void bsp_spi_write_buf(uint8_t addr, uint8_t *buf, uint8_t size); +#endif + + /* * Local types definition */ @@ -204,9 +212,17 @@ SX1272_t SX1272; /*! * Hardware DIO IRQ callback initialization */ -DioIrqHandler *DioIrq[] = { SX1272OnDio0Irq, SX1272OnDio1Irq, - SX1272OnDio2Irq, SX1272OnDio3Irq, - SX1272OnDio4Irq, NULL }; +DioIrqHandler *DioIrq[] = { + SX1272OnDio0Irq, + SX1272OnDio1Irq, + SX1272OnDio2Irq, + SX1272OnDio3Irq, +#if (SX1272_DIO4 >= 0) + SX1272OnDio4Irq, +#else + NULL, +#endif + NULL }; /*! * Tx and Rx timers @@ -242,7 +258,6 @@ round(double d) /* * Radio driver functions implementation */ - void SX1272Init( RadioEvents_t *events ) { uint8_t i; @@ -254,12 +269,11 @@ void SX1272Init( RadioEvents_t *events ) hal_timer_set_cb(SX1272_TIMER_NUM, &RxTimeoutTimer, SX1272OnTimeoutIrq, NULL); hal_timer_set_cb(SX1272_TIMER_NUM, &RxTimeoutSyncWord, SX1272OnTimeoutIrq, NULL); + SX1272IoInit( ); + SX1272IoIrqInit( DioIrq ); SX1272Reset( ); - SX1272SetOpMode( RF_OPMODE_SLEEP ); - SX1272IoIrqInit( DioIrq ); - for( i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ ) { SX1272SetModem( RadioRegsInit[i].Modem ); @@ -1038,18 +1052,22 @@ int16_t SX1272ReadRssi( RadioModems_t modem ) return rssi; } +/** + * SX1272Reset + * + * As per Semtech, the reset sequence should be: + * - Drive reset pin high + * - Wait at least 100 usecs + * - Put pin in High-Z state (make it an input) + * - Wait at least 5 msecs + * + */ void SX1272Reset( void ) { - // Set RESET pin to 0 - hal_gpio_init_out(SX1272_NRESET, 0); - // Wait 1 ms + hal_gpio_init_out(SX1272_NRESET, 1); hal_timer_delay(SX1272_TIMER_NUM, 1000); - - // Drive reset high - hal_gpio_write(SX1272_NRESET, 1); - - // Wait 6 ms + hal_gpio_init_in(SX1272_NRESET, HAL_GPIO_PULL_NONE); hal_timer_delay(SX1272_TIMER_NUM, 6000); } @@ -1118,32 +1136,40 @@ uint8_t SX1272Read( uint8_t addr ) void SX1272WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size ) { +#if MYNEWT_VAL(BSP_USE_HAL_SPI) == 1 + hal_gpio_write(RADIO_NSS, 0); + bsp_spi_write_buf(addr | 0x80, buffer, size); + hal_gpio_write(RADIO_NSS, 1); +#else uint8_t i; hal_gpio_write(RADIO_NSS, 0); - hal_spi_tx_val(RADIO_SPI_IDX, addr | 0x80); for( i = 0; i < size; i++ ) { hal_spi_tx_val(RADIO_SPI_IDX, buffer[i]); } - hal_gpio_write(RADIO_NSS, 1); +#endif } void SX1272ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size ) { +#if MYNEWT_VAL(BSP_USE_HAL_SPI) == 1 + hal_gpio_write(RADIO_NSS, 0); + bsp_spi_read_buf(addr & 0x7f, buffer, size); + hal_gpio_write(RADIO_NSS, 1); +#else uint8_t i; hal_gpio_write(RADIO_NSS, 0); - - hal_spi_tx_val(RADIO_SPI_IDX, addr | 0x80); + hal_spi_tx_val(RADIO_SPI_IDX, addr & 0x7f); for( i = 0; i < size; i++ ) { hal_spi_tx_val(RADIO_SPI_IDX, buffer[i]); } - hal_gpio_write(RADIO_NSS, 1); +#endif } void SX1272WriteFifo( uint8_t *buffer, uint8_t size ) diff --git a/hw/drivers/lora/sx1272/syscfg.yml b/hw/drivers/lora/sx1272/syscfg.yml index e3da9a34f..19b6f8a8f 100644 --- a/hw/drivers/lora/sx1272/syscfg.yml +++ b/hw/drivers/lora/sx1272/syscfg.yml @@ -40,5 +40,44 @@ syscfg.defs: description: 'Set to 1 if board has complementary antenna switch' restrictions: - "!SX1272_HAS_ANT_SW" - value: 1 + value: 0 + + SX1272_RESET_PIN: + description: 'SX1272 reset pin number' + value: -1 + + SX1272_DIO0_PIN: + description: 'SPI chip select pin number' + value: -1 + + SX1272_DIO1_PIN: + description: 'SPI chip select pin number' + value: -1 + + SX1272_DIO2_PIN: + description: 'SPI chip select pin number' + value: -1 + + SX1272_DIO3_PIN: + description: 'SPI chip select pin number' + value: -1 + SX1272_DIO4_PIN: + description: 'SPI chip select pin number' + value: -1 + + SX1272_DIO5_PIN: + description: 'SPI chip select pin number' + value: -1 + + SX1272_RXTX_PIN: + description: 'RxTx switch control pin number' + value: -1 + + SX1272_N_RXTX_PIN: + description: 'Complement RxTx switch control pin number' + value: -1 + + BSP_USE_HAL_SPI: + description: 'Use alternate spi read/write buffer routines' + value: 0 ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services