/*! * \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 #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("\r\n timer 3 IrqErrorCode_t\r\n"); //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; }