之前提及的LoRa调试过程分享,一直由于工作出差耽误,没来得及写帖子分享一下,今天它终于来啦~~~~
#include "board.h"
#include "spi-board.h"
#define SPI_INSTANCE 0 /**< SPI instance index. */
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */
void SpiInit( Spi_t *obj, PinNames mosi, PinNames miso, PinNames sclk, PinNames nss )
{
//SPI Gpio_t
obj->Mosi.mode = PIN_OUTPUT;
obj->Mosi.pull = PIN_PULL_UP;
obj->Mosi.pin = mosi;
obj->Miso.mode = PIN_INPUT;
obj->Miso.pull = PIN_PULL_UP;
obj->Miso.pin = miso;
obj->Sclk.mode = PIN_OUTPUT;
obj->Sclk.pull = PIN_PULL_UP;
obj->Sclk.pin = sclk;
obj->Nss.mode = PIN_OUTPUT;
obj->Nss.pull = PIN_PULL_UP;
obj->Nss.pin = nss;
//spi interface config
obj->config.irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY;
obj->config.orc = 0xFF;
obj->config.frequency = NRF_DRV_SPI_FREQ_1M;
obj->config.mode = NRF_DRV_SPI_MODE_0;
obj->config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
obj->config.mosi_pin = mosi;
obj->config.miso_pin = miso;
obj->config.sck_pin = sclk;
#if (HW_SPI == 1)
obj->config.ss_pin = nss;
#else
obj->config.ss_pin = NC;
#endif
#if (SPI_INSTANCE == 0)
obj->spi = NRF_SPI0;
#elif (SPI_INSTANCE == 1)
obj->spi = NRF_SPI1;
#elif (SPI_INSTANCE == 2)
obj->spi = NRF_SPI2;
#else
#error "no spi interface"
#endif
APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &obj->config, NULL, NULL));
//sw gpio => nss config
GpioInit( &obj->Nss, obj->Nss.pin, obj->Nss.mode, PIN_PUSH_PULL, obj->Nss.pull, 1 );
nrf_spi_int_disable(obj->spi, NRF_SPI_INT_READY_MASK);
nrf_spi_enable(obj->spi);
}
void SpiDeInit( Spi_t *obj )
{
nrf_drv_spi_uninit(&spi);
GpioInit( &obj->Mosi, obj->Mosi.pin, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
GpioInit( &obj->Miso, obj->Miso.pin, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
GpioInit( &obj->Sclk, obj->Sclk.pin, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
GpioInit( &obj->Nss, obj->Nss.pin, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_PULL_UP, 1 );
}
uint16_t SpiInOut( Spi_t *obj, uint16_t outData )
{
uint8_t rxData = 0;
nrf_spi_event_clear(obj->spi, NRF_SPI_EVENT_READY);
nrf_spi_txd_set(obj->spi, outData);
while (!nrf_spi_event_check(obj->spi, NRF_SPI_EVENT_READY)) {}
nrf_spi_event_clear(obj->spi, NRF_SPI_EVENT_READY);
rxData = nrf_spi_rxd_get(obj->spi);
return( rxData );
}
#include "board.h"
#include "gpio-board.h"
static GpioIrqHandler *GpioIrq[31];
void GpioMcuInit( Gpio_t *obj, PinNames pin, PinModes mode, PinConfigs config, PinTypes type, uint32_t value )
{
obj->pin = pin;
if( pin == NC )
{
return;
}
obj->mode = mode;
obj->pull = type;
if( mode == PIN_INPUT ) //gpio input
{
if( config == PIN_PUSH_PULL )
{
if (type == PIN_PULL_UP)
{
nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_PULLUP);
} else if (type == PIN_PULL_DOWN)
{
nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_PULLDOWN);
} else {
nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_NOPULL);
}
}
else
{
nrf_gpio_cfg_default(pin);
}
}
else if( mode == PIN_ANALOGIC ) //adc
{
nrf_gpio_cfg_default(pin);
}
else if( mode == PIN_OUTPUT ) //gpio output
{
nrf_gpio_cfg_output(pin);
GpioMcuWrite( obj, value );
}
return;
}
void HAL_Gpio_Interrupt_Handle(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
if (pin > 31)
{
return;
}
if (GpioIrq[pin] != NULL)
{
GpioIrq[pin]();
}
}
void GpioMcuSetInterrupt( Gpio_t *obj, IrqModes irqMode, IrqPriorities irqPriority, GpioIrqHandler *irqHandler )
{
uint32_t priority = 0;
if( irqHandler == NULL )
{
return;
}
ret_code_t err_code;
if (!nrf_drv_gpiote_is_init())
{
err_code = nrf_drv_gpiote_init();
APP_ERROR_CHECK(err_code);
}
if( irqMode == IRQ_RISING_EDGE )
{
nrf_drv_gpiote_in_config_t rising_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);
if (obj->pull == PIN_PULL_UP)
{
rising_config.pull = NRF_GPIO_PIN_PULLUP;
} else if (obj->pull == PIN_PULL_DOWN) {
rising_config.pull = NRF_GPIO_PIN_PULLDOWN;
} else {
rising_config.pull = NRF_GPIO_PIN_NOPULL;
}
err_code = nrf_drv_gpiote_in_init(obj->pin, &rising_config, HAL_Gpio_Interrupt_Handle);
APP_ERROR_CHECK(err_code);
}
else if( irqMode == IRQ_FALLING_EDGE )
{
nrf_drv_gpiote_in_config_t falling_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
if (obj->pull == PIN_PULL_UP)
{
falling_config.pull = NRF_GPIO_PIN_PULLUP;
} else if (obj->pull == PIN_PULL_DOWN) {
falling_config.pull = NRF_GPIO_PIN_PULLDOWN;
} else {
falling_config.pull = NRF_GPIO_PIN_NOPULL;
}
err_code = nrf_drv_gpiote_in_init(obj->pin, &falling_config, HAL_Gpio_Interrupt_Handle);
APP_ERROR_CHECK(err_code);
}
else
{
nrf_drv_gpiote_in_config_t toggle_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
if (obj->pull == PIN_PULL_UP)
{
toggle_config.pull = NRF_GPIO_PIN_PULLUP;
} else if (obj->pull == PIN_PULL_DOWN) {
toggle_config.pull = NRF_GPIO_PIN_PULLDOWN;
} else {
toggle_config.pull = NRF_GPIO_PIN_NOPULL;
}
err_code = nrf_drv_gpiote_in_init(obj->pin, &toggle_config, HAL_Gpio_Interrupt_Handle);
APP_ERROR_CHECK(err_code);
}
switch( irqPriority )
{
case IRQ_VERY_LOW_PRIORITY:
case IRQ_LOW_PRIORITY:
priority = 3;
break;
case IRQ_MEDIUM_PRIORITY:
priority = 2;
break;
case IRQ_HIGH_PRIORITY:
priority = 1;
break;
case IRQ_VERY_HIGH_PRIORITY:
default:
priority = 0;
break;
}
GpioIrq[obj->pin] = irqHandler;
nrf_drv_gpiote_in_event_enable(obj->pin, true);
}
void GpioMcuRemoveInterrupt( Gpio_t *obj )
{
nrf_drv_gpiote_in_event_enable(obj->pin, false);
}
void GpioMcuWrite( Gpio_t *obj, uint32_t value )
{
if( obj == NULL )
{
assert_param( FAIL );
}
// Check if pin is not connected
if( obj->pin == NC )
{
return;
}
nrf_gpio_pin_write(obj->pin, value);
}
void GpioMcuToggle( Gpio_t *obj )
{
if( obj == NULL )
{
assert_param( FAIL );
}
// Check if pin is not connected
if( obj->pin == NC )
{
return;
}
nrf_gpio_pin_toggle(obj->pin);
}
uint32_t GpioMcuRead( Gpio_t *obj )
{
uint8_t pinstate = 0;
if( obj == NULL )
{
assert_param( FAIL );
}
// Check if pin is not connected
if( obj->pin == NC )
{
return 0;
}
#if 1
if(nrf_gpio_pin_dir_get(obj->pin) == NRF_GPIO_PIN_DIR_INPUT)
{
pinstate = nrf_gpio_pin_read(obj->pin);
}
else
{
pinstate = nrf_gpio_pin_out_read(obj->pin);
}
return pinstate;
#else
return nrf_gpio_pin_read(obj->pin);
#endif
}
#include <math.h>
#include "board.h"
#include "timer-board.h"
const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(2); /**< Declaring an instance of nrf_drv_rtc for RTC2. */
void TIMER_IRQHandler(nrf_drv_rtc_int_type_t int_type);
/*!
* Hardware Time base in ms
*/
#define HW_TIMER_TIME_BASE 1 //ms
/*!
* Hardware Timer tick counter
*/
volatile TimerTime_t TimerTickCounter = 1;
/*!
* Saved value of the Tick counter at the start of the next event
*/
static TimerTime_t TimerTickCounterContext = 0;
/*!
* Value trigging the IRQ
*/
volatile TimerTime_t TimeoutCntValue = 0;
/*!
* Increment the Hardware Timer tick counter
*/
void TimerIncrementTickCounter(void);
/*!
* Counter used for the Delay operations
*/
volatile uint32_t TimerDelayCounter = 0;
/*!
* Retunr the value of the counter used for a Delay
*/
uint32_t TimerHwGetDelayValue(void);
/*!
* Increment the value of TimerDelayCounter
*/
void TimerIncrementDelayCounter(void);
void TimerHwInit(void)
{
/* TIMER clock enable */
//LFCLK Initial
/* TIMER interrupt Init */
uint32_t err_code;
//Initialize RTC instance
nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG;
#if 1
config.prescaler = 31;
#else
config.prescaler = 0;
#endif
err_code = nrf_drv_rtc_init(&rtc, &config, TIMER_IRQHandler);
APP_ERROR_CHECK(err_code);
#if 1
//Enable tick event & interrupt
nrf_drv_rtc_tick_enable(&rtc, true);
#else
//Set compare channel to trigger interrupt after COMPARE_COUNTERTIME seconds
err_code = nrf_drv_rtc_cc_set(&rtc, 0, RTC_DEFAULT_CONFIG_FREQUENCY/1000, true);
APP_ERROR_CHECK(err_code);
#endif
}
void TimerHwDeInit(void)
{
/* TIMER clock enable */
//Power uninit RTC instance
nrf_drv_rtc_uninit(&rtc);
}
uint32_t TimerHwGetMinimumTimeout(void)
{
return (ceil(2 * HW_TIMER_TIME_BASE));
}
void TimerHwStart(uint32_t val)
{
TimerTickCounterContext = TimerHwGetTimerValue();
if (val <= HW_TIMER_TIME_BASE + 1)
{
TimeoutCntValue = TimerTickCounterContext + 1;
}
else
{
TimeoutCntValue = TimerTickCounterContext + ((val - 1) / HW_TIMER_TIME_BASE);
}
//Power on RTC instance
nrf_drv_rtc_enable(&rtc);
}
void TimerHwStop(void)
{
//Power on RTC instance
nrf_drv_rtc_disable(&rtc);
}
TimerTime_t TimerHwGetElapsedTime(void)
{
return (((TimerHwGetTimerValue() - TimerTickCounterContext) + 1) * HW_TIMER_TIME_BASE);
}
TimerTime_t TimerHwGetTimerValue(void)
{
TimerTime_t val = 0;
__disable_irq();
val = TimerTickCounter;
__enable_irq();
return (val);
}
TimerTime_t TimerHwComputeElapsedTime(TimerTime_t eventInTime)
{
TimerTime_t elapsedTime = 0;
// Needed at boot, cannot compute with 0 or elapsed time will be equal to current time
if( eventInTime == 0 )
{
return 0;
}
elapsedTime = TimerHwGetTimerValue( );
if( elapsedTime < eventInTime )
{ // roll over of the counter
return( elapsedTime + ( 0xFFFFFFFF - eventInTime ) );
}
else
{
return( elapsedTime - eventInTime );
}
}
TimerTime_t TimerHwGetTime(void)
{
return TimerHwGetTimerValue() * HW_TIMER_TIME_BASE;
}
uint32_t TimerHwGetDelayValue(void)
{
uint32_t val = 0;
__disable_irq();
val = TimerDelayCounter;
__enable_irq();
return (val);
}
void TimerIncrementTickCounter(void)
{
__disable_irq();
TimerTickCounter++;
__enable_irq();
}
void TimerIncrementDelayCounter(void)
{
__disable_irq();
TimerDelayCounter++;
__enable_irq();
}
/*!
* Timer IRQ handler
*/
void TIMER_IRQHandler(nrf_drv_rtc_int_type_t int_type)
{
if (int_type == NRF_DRV_RTC_INT_TICK)
{
TimerIncrementTickCounter();
if (TimerTickCounter == TimeoutCntValue)
{
TimerIrqHandler();
}
}
else if (int_type == NRF_DRV_RTC_INT_COMPARE0)
{
TimerIncrementTickCounter();
if (TimerTickCounter == TimeoutCntValue)
{
TimerIrqHandler();
}
}
}
#include "task_lora.h"
#include "board.h"
void lora_rx_handler(uint8_t *payload)
{
switch(payload[4])
{
case 'r':
BoardLed_Flashing(RGBLED_RED);
Radio.Send("red flashing", sizeof("red flashing"));
//Radio.Send("led_red", sizeof("led_red"));
break;
case 'g':
BoardLed_Flashing(RGBLED_GREEN);
Radio.Send("green flashing", sizeof("green flashing"));
break;
case 'b':
BoardLed_Flashing(RGBLED_BLUE);
Radio.Send("blue flashing", sizeof("blue flashing"));
break;
default:
break;
}
}
void OnTxDone( void )
{
printf("function: %s", __FUNCTION__);
NRF_LOG_DEBUG("function: %s", __FUNCTION__);
Radio.Standby();
Radio.Rx(0xFFFFFF);
}
void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
{
printf("function: %s", __FUNCTION__);
NRF_LOG_DEBUG("function: %s", __FUNCTION__);
printf("receive:%s, rssi:%d, snr%d\r\n", payload, rssi, snr);
lora_rx_handler(payload);
// Radio.Standby();
// Radio.Rx(0xFFFFFF);
}
void OnTxTimeout( void )
{
printf("function: %s", __FUNCTION__);
NRF_LOG_INFO("function: %s", __FUNCTION__);
Radio.Standby();
Radio.Rx(0xFFFFFF);
}
void OnRxTimeout( void )
{
printf("function: %s", __FUNCTION__);
NRF_LOG_INFO("function: %s", __FUNCTION__);
Radio.Standby();
Radio.Rx(0xFFFFFF);
}
void OnRxError( void )
{
printf("function: %s", __FUNCTION__);
NRF_LOG_INFO("function: %s", __FUNCTION__);
Radio.Standby();
Radio.Rx(0xFFFFFF);
}
static RadioEvents_t RadioEvents;
void lora_init(void)
{
RadioEvents.TxDone = OnTxDone;
RadioEvents.RxDone = OnRxDone;
RadioEvents.TxTimeout = OnTxTimeout;
RadioEvents.RxTimeout = OnRxTimeout;
RadioEvents.RxError = OnRxError;
Radio.Init( &RadioEvents );
Radio.SetMaxPayloadLength(MODEM_LORA, MAX_PAYLOADLENGTH);
Radio.SetTxConfig( MODEM_LORA, LORA_TX_POWER, 0, LORA_BW, LORA_SF, LORA_CR, LORA_PREAMBLE,
LORA_FIX_LENGTH_PAYLOAD_ON, true, 0, 0, LORA_IQ_INVERSION_ON, TX_TIMEOUT_VALUE );
Radio.SetRxConfig( MODEM_LORA, LORA_BW, LORA_SF,
LORA_CR, 0, LORA_PREAMBLE,
LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
0, true, 0, 0, LORA_IQ_INVERSION_ON, true );
Radio.SetChannel( LORA_RX_FREQ );
Radio.Rx(0xFFFFFF);
}
void lora_process(void)
{
//if receive from uart
//if DIO1 irq
Radio.IrqProcess();
}
/**[url=home.php?mod=space&uid=159083]@brief[/url] Application main function.
*/
int main(void)
{
// Initialize.
uart_init();
log_init();
timers_init();
power_management_init();
ble_stack_init();
gap_params_init();
gatt_init();
services_init();
advertising_init();
conn_params_init();
// Start execution.
printf("\r\nBLE-LoRa Init...\r\n");
NRF_LOG_INFO("Debug logging for UART over RTT started.");
#if BLE_ENABLE
advertising_start();
#endif
board_lora_init();
// Enter main loop.
for (;;)
{
lora_process();
idle_state_handle();
}
}
接着需要调试SPI部分驱动,由于nRF52832的SDK里面在nrfx SPI驱动。
这个芯片,现在用得多吗?
引用: lugl4313820 发表于 2022-9-17 22:58 接着需要调试SPI部分驱动,由于nRF52832的SDK里面在nrfx SPI驱动。 这个芯片,现在用得多吗? ...
BLE应用里面挺常见的。。。。但是芯片涨价/缺货这一波也影响挺大的。。。。