| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- /*!
- * \file sx1262mbxcas-board.c
- *
- * \brief Target board SX1262MBXCAS shield driver implementation
- *
- * \copyright Revised BSD License, see section \ref LICENSE.
- *
- * \code
- * ______ _
- * / _____) _ | |
- * ( (____ _____ ____ _| |_ _____ ____| |__
- * \____ \| ___ | (_ _) ___ |/ ___) _ \
- * _____) ) ____| | | || |_| ____( (___| | | |
- * (______/|_____)_|_|_| \__)_____)\____)_| |_|
- * (C)2013-2017 Semtech
- *
- * \endcode
- *
- * \author Miguel Luis ( Semtech )
- *
- * \author Gregory Cristian ( Semtech )
- */
- #include <stdlib.h>
- #include "project_config.h"
- #include "delay.h"
- #include "radio.h"
- #include "sx126x-board.h"
- #include "HAL_SPI.h"
- #include "stdio.h"
- typedef struct __softTimer_s{
- uint8_t isRun; //0停止,1运行
- uint32_t delayMs; //定时器需要多长时间后唤醒
- uint32_t startMs; //定时器开始时间
- }SoftTimer_t;
- static DioIrqHandler *dio1IrqCallback=NULL; //记录DIO1的回调函数句柄
- static uint32_t timer_count=0;
- static SoftTimer_t txTimerHandle,rxTimerHandle;
- /* 初始化sx126x需要用到的GPIO初始化,将 BUSY 引脚设置为输入模式
- */
- void SX126xIoInit( void )
- {
- uint8_t u8_ret=255;
- GPIO_InitTypeDef GPIO_InitStructure;
- //初始化BUSY为上拉输入模式
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE, ENABLE); //使能指定端口时钟
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz,这里不用传参,直接写死用最大速度50MHZ
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入
- GPIO_InitStructure.GPIO_Pin = RADIO_DIO4_BUSY_PIN;
- GPIO_Init(RADIO_DIO4_BUSY_PORT, &GPIO_InitStructure); //初始化GPIO
-
- //下面这几个引脚没用用到,设置为浮空输入模式
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入
-
- GPIO_InitStructure.GPIO_Pin = RADIO_DIO0_TXEN_PIN;
- GPIO_Init(RADIO_DIO0_TXEN_PORT, &GPIO_InitStructure); //初始化GPIO
- GPIO_InitStructure.GPIO_Pin = RADIO_DIO2_PIN;
- GPIO_Init(RADIO_DIO2_PORT, &GPIO_InitStructure); //初始化GPIO
-
- GPIO_InitStructure.GPIO_Pin = RADIO_DIO3_PIN;
- GPIO_Init(RADIO_DIO3_PORT, &GPIO_InitStructure); //初始化GPIO
-
- GPIO_InitStructure.GPIO_Pin = RADIO_DIO5_RXEN_PIN;
- GPIO_Init(RADIO_DIO5_RXEN_PORT, &GPIO_InitStructure); //初始化GPIO
-
- u8_ret=Spi1Init();
- if(u8_ret){
- printf("spi1 init error\r\n");
- }else{
- printf("SX126xIoInit init sucess\r\n");
- }
- }
- /* 初始化 DIO1
- * 将DIO1设置为外部中断(上升沿触发),并且回调函数为 dioIrq 函数原型 void RadioOnDioIrq( void* context )
- */
- void SX126xIoIrqInit( DioIrqHandler dioIrq )
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- EXTI_InitTypeDef EXTI_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
-
- dio1IrqCallback=dioIrq;
-
- //gpio(DIO1)初始化为下拉输入模式
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOB, ENABLE); //使能指定端口时钟
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz,这里不用传参,直接写死用最大速度50MHZ
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//下拉输入
- GPIO_InitStructure.GPIO_Pin = RADIO_DIO1_PIN;
- GPIO_Init(RADIO_DIO1_PORT, &GPIO_InitStructure); //初始化GPIO
-
- //中断配置
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟
- //GPIOE.2 中断线以及中断初始化配置 上升沿触发
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource8);
- EXTI_InitStructure.EXTI_Line=EXTI_Line8;
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
- EXTI_InitStructure.EXTI_LineCmd = ENABLE;
- EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
- //设置中断优先级
- NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能按键WK_UP所在的外部中断通道
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; //子优先级3
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
- NVIC_Init(&NVIC_InitStructure);
- EXTI_ClearITPendingBit(EXTI_Line8); //清除LINE11上的中断标志位
- }
- //在中断回调函数中回调 void SX126xIoIrqInit( DioIrqHandler dioIrq ) 中注册的 dioIrq 回调
- void EXTI9_5_IRQHandler(void){
- // printf("enter irq\r\n");
- if(GPIO_ReadInputDataBit(RADIO_DIO1_PORT,RADIO_DIO1_PIN)){
- // printf("DIO1 irq\r\n");
- if(NULL!=dio1IrqCallback){
- dio1IrqCallback(NULL);
- }
- EXTI_ClearITPendingBit(EXTI_Line8);//清除中断标志位
- }
- }
- void SX126xIoDeInit( void )
- {
- //GPIO去初始化代码
- }
- //复位按键功能
- void SX126xReset( void )
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- SX126xDelayMs( 10 );
-
- //将RST输出低电平
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能指定端口时钟
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz,这里不用传参,直接写死用最大速度50MHZ
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出
- GPIO_InitStructure.GPIO_Pin = RADIO_nRESET_PIN;
- GPIO_Init(RADIO_nRESET_PORT, &GPIO_InitStructure); //初始化GPIO
- GPIO_WriteBit( RADIO_nRESET_PORT, RADIO_nRESET_PIN,Bit_RESET); //RST设为低电平输出
-
- SX126xDelayMs( 20 );
-
- //将RST设置为上拉输入模式
- GPIO_WriteBit( RADIO_nRESET_PORT, RADIO_nRESET_PIN,Bit_SET); //RST设为低电平输出
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
- GPIO_Init(RADIO_nRESET_PORT, &GPIO_InitStructure); //初始化GPIO
-
- SX126xDelayMs( 10 );
- }
- //读取Busy引脚电平状态
- void SX126xWaitOnBusy( void )
- {
- uint32_t u32_count=0;
-
- while( GPIO_ReadInputDataBit(RADIO_DIO4_BUSY_PORT,RADIO_DIO4_BUSY_PIN) == 1 ){
- if(u32_count++>1000){
- printf("wait busy pin timeout\r\n");
- u32_count=0;
- }
- SX126xDelayMs(1);
- }
- }
- //设置SPI的NSS引脚电平,0低电平,非零高电平
- void SX126xSetNss(uint8_t lev ){
- if(lev){
- GPIO_SetBits(RADIO_NSS_PORT,RADIO_NSS_PIN); //输出高电平
- }else{
- GPIO_ResetBits(RADIO_NSS_PORT,RADIO_NSS_PIN); //输出低电平
- }
- }
- //spi传输一个字节的数据
- uint8_t SX126xSpiInOut(uint8_t data){
- return HALSpi1InOut(data);
- }
- //检查频率是否符合要求,如果不需要判断则可以直接返回true
- bool SX126xCheckRfFrequency( uint32_t frequency )
- {
- // Implement check. Currently all frequencies are supported
- return true;
- }
- //毫秒延时
- void SX126xDelayMs(uint32_t ms){
- delay_ms(ms);
- }
- //tx/rx定时器操作
- //定时器3中断服务程序
- //tx定时结束需要回调 RadioOnTxTimeoutIrq
- //rx定时结束需要回调 RadioOnRxTimeoutIrq
- void TIM3_IRQHandler(void) //TIM3中断
- {
- uint32_t diffMs=0;
-
- if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){
- timer_count++;
- TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx更新中断标志
-
- //printf("timer_count=%d\r\n",timer_count);
-
- //处理tx定时器
- if(txTimerHandle.isRun){
- if(timer_count>=txTimerHandle.startMs){
- diffMs=timer_count-txTimerHandle.startMs;
- }else{//溢出了
- diffMs=0xffffffff - txTimerHandle.startMs + timer_count;
- }
- if(diffMs>txTimerHandle.delayMs){
- //计时结束
- //printf("----------------- tx timer irq ---------------\r\n");
- SX126xTxTimerStop();
- txTimerHandle.startMs=timer_count;
- RadioOnTxTimeoutIrq(NULL); //tx定时结束需要回调 RadioOnTxTimeoutIrq
- }
- }
-
- //处理rx定时器
- if(rxTimerHandle.isRun){
- if(timer_count>=rxTimerHandle.startMs){
- diffMs=timer_count-rxTimerHandle.startMs;
- }else{//溢出了
- diffMs=0xffffffff - rxTimerHandle.startMs + timer_count;
- }
- if(diffMs>rxTimerHandle.delayMs){
- //计时结束
- //printf("----------------- rx timer irq ---------------\r\n");
- SX126xRxTimerStop();
- rxTimerHandle.startMs=timer_count;
- RadioOnRxTimeoutIrq(NULL); //rx定时结束需要回调 RadioOnRxTimeoutIrq
- }
- }
- }
- }
- //初始化定时器(这里用TIM3定时器模拟出了两个ms定时器)
- //tx定时结束需要回调 RadioOnTxTimeoutIrq
- //rx定时结束需要回调 RadioOnRxTimeoutIrq
- void SX126xTimerInit(void){
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- //使能TIM3
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
-
- //TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
- //中断优先级NVIC设置
- NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
- NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
-
- //定时器TIM3初始化
- TIM_TimeBaseStructure.TIM_Period = 10; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
- TIM_TimeBaseStructure.TIM_Prescaler =SystemCoreClock/10000; //设置用来作为TIMx时钟频率除数的预分频值(1s10000次,也就是1次0.1ms)
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
-
- //关闭软件定时器
- txTimerHandle.isRun=0;
- rxTimerHandle.isRun=0;
-
- TIM_Cmd(TIM3, ENABLE); //使能TIMx
- TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx更新中断标志
- TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM2中断,允许更新中断
- }
- void SX126xSetTxTimerValue(uint32_t nMs){
- //printf("[%s()-%d]set timer out %d ms\r\n",__func__,__LINE__,nMs);
- txTimerHandle.delayMs=nMs;
- }
- void SX126xTxTimerStart(void){
- //printf("[%s()-%d]start timer\r\n",__func__,__LINE__);
- txTimerHandle.startMs=timer_count;
- txTimerHandle.isRun=1;
- }
- void SX126xTxTimerStop(void){
- //printf("[%s()-%d]stop timer\r\n",__func__,__LINE__);
- txTimerHandle.isRun=0;
- }
- void SX126xSetRxTimerValue(uint32_t nMs){
- //printf("[%s()-%d]set timer out %d ms\r\n",__func__,__LINE__,nMs);
- rxTimerHandle.delayMs=nMs;
- }
- void SX126xRxTimerStart(void){
- //printf("[%s()-%d]start timer\r\n",__func__,__LINE__);
- rxTimerHandle.startMs=timer_count;
- rxTimerHandle.isRun=1;
- }
- void SX126xRxTimerStop(void){
- //printf("[%s()-%d]stop timer\r\n",__func__,__LINE__);
- rxTimerHandle.isRun=0;
- }
|