SX126xSTM32F103-board.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /*!
  2. * \file sx1262mbxcas-board.c
  3. *
  4. * \brief Target board SX1262MBXCAS shield driver implementation
  5. *
  6. * \copyright Revised BSD License, see section \ref LICENSE.
  7. *
  8. * \code
  9. * ______ _
  10. * / _____) _ | |
  11. * ( (____ _____ ____ _| |_ _____ ____| |__
  12. * \____ \| ___ | (_ _) ___ |/ ___) _ \
  13. * _____) ) ____| | | || |_| ____( (___| | | |
  14. * (______/|_____)_|_|_| \__)_____)\____)_| |_|
  15. * (C)2013-2017 Semtech
  16. *
  17. * \endcode
  18. *
  19. * \author Miguel Luis ( Semtech )
  20. *
  21. * \author Gregory Cristian ( Semtech )
  22. */
  23. #include <stdlib.h>
  24. #include "project_config.h"
  25. #include "delay.h"
  26. #include "radio.h"
  27. #include "sx126x-board.h"
  28. #include "HAL_SPI.h"
  29. #include "stdio.h"
  30. typedef struct __softTimer_s{
  31. uint8_t isRun; //0停止,1运行
  32. uint32_t delayMs; //定时器需要多长时间后唤醒
  33. uint32_t startMs; //定时器开始时间
  34. }SoftTimer_t;
  35. static DioIrqHandler *dio1IrqCallback=NULL; //记录DIO1的回调函数句柄
  36. static uint32_t timer_count=0;
  37. static SoftTimer_t txTimerHandle,rxTimerHandle;
  38. /* 初始化sx126x需要用到的GPIO初始化,将 BUSY 引脚设置为输入模式
  39. */
  40. void SX126xIoInit( void )
  41. {
  42. uint8_t u8_ret=255;
  43. GPIO_InitTypeDef GPIO_InitStructure;
  44. //初始化BUSY为上拉输入模式
  45. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE, ENABLE); //使能指定端口时钟
  46. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz,这里不用传参,直接写死用最大速度50MHZ
  47. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入
  48. GPIO_InitStructure.GPIO_Pin = RADIO_DIO4_BUSY_PIN;
  49. GPIO_Init(RADIO_DIO4_BUSY_PORT, &GPIO_InitStructure); //初始化GPIO
  50. //下面这几个引脚没用用到,设置为浮空输入模式
  51. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入
  52. GPIO_InitStructure.GPIO_Pin = RADIO_DIO0_TXEN_PIN;
  53. GPIO_Init(RADIO_DIO0_TXEN_PORT, &GPIO_InitStructure); //初始化GPIO
  54. GPIO_InitStructure.GPIO_Pin = RADIO_DIO2_PIN;
  55. GPIO_Init(RADIO_DIO2_PORT, &GPIO_InitStructure); //初始化GPIO
  56. GPIO_InitStructure.GPIO_Pin = RADIO_DIO3_PIN;
  57. GPIO_Init(RADIO_DIO3_PORT, &GPIO_InitStructure); //初始化GPIO
  58. GPIO_InitStructure.GPIO_Pin = RADIO_DIO5_RXEN_PIN;
  59. GPIO_Init(RADIO_DIO5_RXEN_PORT, &GPIO_InitStructure); //初始化GPIO
  60. u8_ret=Spi1Init();
  61. if(u8_ret){
  62. printf("spi1 init error\r\n");
  63. }else{
  64. printf("SX126xIoInit init sucess\r\n");
  65. }
  66. }
  67. /* 初始化 DIO1
  68. * 将DIO1设置为外部中断(上升沿触发),并且回调函数为 dioIrq 函数原型 void RadioOnDioIrq( void* context )
  69. */
  70. void SX126xIoIrqInit( DioIrqHandler dioIrq )
  71. {
  72. GPIO_InitTypeDef GPIO_InitStructure;
  73. EXTI_InitTypeDef EXTI_InitStructure;
  74. NVIC_InitTypeDef NVIC_InitStructure;
  75. dio1IrqCallback=dioIrq;
  76. //gpio(DIO1)初始化为下拉输入模式
  77. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOB, ENABLE); //使能指定端口时钟
  78. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz,这里不用传参,直接写死用最大速度50MHZ
  79. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//下拉输入
  80. GPIO_InitStructure.GPIO_Pin = RADIO_DIO1_PIN;
  81. GPIO_Init(RADIO_DIO1_PORT, &GPIO_InitStructure); //初始化GPIO
  82. //中断配置
  83. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟
  84. //GPIOE.2 中断线以及中断初始化配置 上升沿触发
  85. GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource8);
  86. EXTI_InitStructure.EXTI_Line=EXTI_Line8;
  87. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  88. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
  89. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  90. EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
  91. //设置中断优先级
  92. NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能按键WK_UP所在的外部中断通道
  93. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,
  94. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; //子优先级3
  95. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
  96. NVIC_Init(&NVIC_InitStructure);
  97. EXTI_ClearITPendingBit(EXTI_Line8); //清除LINE11上的中断标志位
  98. }
  99. //在中断回调函数中回调 void SX126xIoIrqInit( DioIrqHandler dioIrq ) 中注册的 dioIrq 回调
  100. void EXTI9_5_IRQHandler(void){
  101. // printf("enter irq\r\n");
  102. if(GPIO_ReadInputDataBit(RADIO_DIO1_PORT,RADIO_DIO1_PIN)){
  103. // printf("DIO1 irq\r\n");
  104. if(NULL!=dio1IrqCallback){
  105. dio1IrqCallback(NULL);
  106. }
  107. EXTI_ClearITPendingBit(EXTI_Line8);//清除中断标志位
  108. }
  109. }
  110. void SX126xIoDeInit( void )
  111. {
  112. //GPIO去初始化代码
  113. }
  114. //复位按键功能
  115. void SX126xReset( void )
  116. {
  117. GPIO_InitTypeDef GPIO_InitStructure;
  118. SX126xDelayMs( 10 );
  119. //将RST输出低电平
  120. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能指定端口时钟
  121. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz,这里不用传参,直接写死用最大速度50MHZ
  122. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出
  123. GPIO_InitStructure.GPIO_Pin = RADIO_nRESET_PIN;
  124. GPIO_Init(RADIO_nRESET_PORT, &GPIO_InitStructure); //初始化GPIO
  125. GPIO_WriteBit( RADIO_nRESET_PORT, RADIO_nRESET_PIN,Bit_RESET); //RST设为低电平输出
  126. SX126xDelayMs( 20 );
  127. //将RST设置为上拉输入模式
  128. GPIO_WriteBit( RADIO_nRESET_PORT, RADIO_nRESET_PIN,Bit_SET); //RST设为低电平输出
  129. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
  130. GPIO_Init(RADIO_nRESET_PORT, &GPIO_InitStructure); //初始化GPIO
  131. SX126xDelayMs( 10 );
  132. }
  133. //读取Busy引脚电平状态
  134. void SX126xWaitOnBusy( void )
  135. {
  136. uint32_t u32_count=0;
  137. while( GPIO_ReadInputDataBit(RADIO_DIO4_BUSY_PORT,RADIO_DIO4_BUSY_PIN) == 1 ){
  138. if(u32_count++>1000){
  139. printf("wait busy pin timeout\r\n");
  140. u32_count=0;
  141. }
  142. SX126xDelayMs(1);
  143. }
  144. }
  145. //设置SPI的NSS引脚电平,0低电平,非零高电平
  146. void SX126xSetNss(uint8_t lev ){
  147. if(lev){
  148. GPIO_SetBits(RADIO_NSS_PORT,RADIO_NSS_PIN); //输出高电平
  149. }else{
  150. GPIO_ResetBits(RADIO_NSS_PORT,RADIO_NSS_PIN); //输出低电平
  151. }
  152. }
  153. //spi传输一个字节的数据
  154. uint8_t SX126xSpiInOut(uint8_t data){
  155. return HALSpi1InOut(data);
  156. }
  157. //检查频率是否符合要求,如果不需要判断则可以直接返回true
  158. bool SX126xCheckRfFrequency( uint32_t frequency )
  159. {
  160. // Implement check. Currently all frequencies are supported
  161. return true;
  162. }
  163. //毫秒延时
  164. void SX126xDelayMs(uint32_t ms){
  165. delay_ms(ms);
  166. }
  167. //tx/rx定时器操作
  168. //定时器3中断服务程序
  169. //tx定时结束需要回调 RadioOnTxTimeoutIrq
  170. //rx定时结束需要回调 RadioOnRxTimeoutIrq
  171. void TIM3_IRQHandler(void) //TIM3中断
  172. {
  173. uint32_t diffMs=0;
  174. if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){
  175. timer_count++;
  176. TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx更新中断标志
  177. //printf("timer_count=%d\r\n",timer_count);
  178. //处理tx定时器
  179. if(txTimerHandle.isRun){
  180. if(timer_count>=txTimerHandle.startMs){
  181. diffMs=timer_count-txTimerHandle.startMs;
  182. }else{//溢出了
  183. diffMs=0xffffffff - txTimerHandle.startMs + timer_count;
  184. }
  185. if(diffMs>txTimerHandle.delayMs){
  186. //计时结束
  187. //printf("----------------- tx timer irq ---------------\r\n");
  188. SX126xTxTimerStop();
  189. txTimerHandle.startMs=timer_count;
  190. RadioOnTxTimeoutIrq(NULL); //tx定时结束需要回调 RadioOnTxTimeoutIrq
  191. }
  192. }
  193. //处理rx定时器
  194. if(rxTimerHandle.isRun){
  195. if(timer_count>=rxTimerHandle.startMs){
  196. diffMs=timer_count-rxTimerHandle.startMs;
  197. }else{//溢出了
  198. diffMs=0xffffffff - rxTimerHandle.startMs + timer_count;
  199. }
  200. if(diffMs>rxTimerHandle.delayMs){
  201. //计时结束
  202. //printf("----------------- rx timer irq ---------------\r\n");
  203. SX126xRxTimerStop();
  204. rxTimerHandle.startMs=timer_count;
  205. RadioOnRxTimeoutIrq(NULL); //rx定时结束需要回调 RadioOnRxTimeoutIrq
  206. }
  207. }
  208. }
  209. }
  210. //初始化定时器(这里用TIM3定时器模拟出了两个ms定时器)
  211. //tx定时结束需要回调 RadioOnTxTimeoutIrq
  212. //rx定时结束需要回调 RadioOnRxTimeoutIrq
  213. void SX126xTimerInit(void){
  214. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  215. NVIC_InitTypeDef NVIC_InitStructure;
  216. //使能TIM3
  217. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
  218. //TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
  219. //中断优先级NVIC设置
  220. NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
  221. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
  222. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
  223. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  224. NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
  225. //定时器TIM3初始化
  226. TIM_TimeBaseStructure.TIM_Period = 10; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
  227. TIM_TimeBaseStructure.TIM_Prescaler =SystemCoreClock/10000; //设置用来作为TIMx时钟频率除数的预分频值(1s10000次,也就是1次0.1ms)
  228. TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
  229. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
  230. TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
  231. //关闭软件定时器
  232. txTimerHandle.isRun=0;
  233. rxTimerHandle.isRun=0;
  234. TIM_Cmd(TIM3, ENABLE); //使能TIMx
  235. TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx更新中断标志
  236. TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM2中断,允许更新中断
  237. }
  238. void SX126xSetTxTimerValue(uint32_t nMs){
  239. //printf("[%s()-%d]set timer out %d ms\r\n",__func__,__LINE__,nMs);
  240. txTimerHandle.delayMs=nMs;
  241. }
  242. void SX126xTxTimerStart(void){
  243. //printf("[%s()-%d]start timer\r\n",__func__,__LINE__);
  244. txTimerHandle.startMs=timer_count;
  245. txTimerHandle.isRun=1;
  246. }
  247. void SX126xTxTimerStop(void){
  248. //printf("[%s()-%d]stop timer\r\n",__func__,__LINE__);
  249. txTimerHandle.isRun=0;
  250. }
  251. void SX126xSetRxTimerValue(uint32_t nMs){
  252. //printf("[%s()-%d]set timer out %d ms\r\n",__func__,__LINE__,nMs);
  253. rxTimerHandle.delayMs=nMs;
  254. }
  255. void SX126xRxTimerStart(void){
  256. //printf("[%s()-%d]start timer\r\n",__func__,__LINE__);
  257. rxTimerHandle.startMs=timer_count;
  258. rxTimerHandle.isRun=1;
  259. }
  260. void SX126xRxTimerStop(void){
  261. //printf("[%s()-%d]stop timer\r\n",__func__,__LINE__);
  262. rxTimerHandle.isRun=0;
  263. }