pan_rf.c 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969
  1. /**
  2. * @file pan_rf.c
  3. * @brief PAN3029/PAN3060 driver implementation
  4. * @version V1.0.1
  5. * @date 2025-08-18
  6. * @copyright Panchip Microelectronics Co., Ltd. All rights reserved.
  7. * @code
  8. * ____ ____ _ _
  9. * | _ \ __ _ _ __ / ___| |__ (_)_ __
  10. * | |_) / _` | '_ \| | | '_ \| | '_ \
  11. * | __/ (_| | | | | |___| | | | | |_) |
  12. * |_| \__,_|_| |_|\____|_| |_|_| .__/
  13. * |_|
  14. * (C)2009-2025 PanChip
  15. * @endcode
  16. * @author PanChip
  17. * @note The encoding of this file is utf-8.
  18. */
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include "pan_param.h"
  22. #include "pan_rf.h"
  23. /**
  24. * @brief PAN3029/3060接收数据包结构体
  25. * @note 该结构体用于存储接收到的数据包,包括数据长度、数据缓冲区、SNR和RSSI等信息
  26. */
  27. volatile RfRxPkt_t g_RfRxPkt = {0};
  28. /**
  29. * @brief PAN3029/3060配置参数结构体
  30. * @note 该结构体用于存储PAN3029/3060的配置参数,包括发射功率、频率、扩频因子、带宽、编码率等
  31. */
  32. static volatile RfConfig_t g_RfCfgParams = {0};
  33. /**
  34. * @brief 保存当前的RF操作状态
  35. */
  36. static volatile RfOpState_t g_RfOperatetate;
  37. #pragma push /* 保存编译器优化设置 */
  38. #pragma O0 /* !!!禁止编译器优化延时函数,以确保延时的准确性!!! */
  39. /**
  40. * @brief 微秒级延时函数
  41. * @param us 延时的微秒数
  42. * @note 该函数具体的实现需要根据实际硬件平台进行修改。
  43. * @note 须保证RF_DelayUs(1)大于等于1us。
  44. */
  45. void RF_DelayUs(uint32_t us)
  46. {
  47. std_delayus(us);
  48. }
  49. /**
  50. * @brief 毫秒级延时函数
  51. * @param ms 延时的毫秒数
  52. * @note 该函数具体的实现需要根据实际硬件平台进行修改。
  53. * @note 须保证RF_DelayMs(1)大于等于1ms。
  54. */
  55. void RF_DelayMs(uint32_t ms)
  56. {
  57. RF_DelayUs(ms * 1000); /* 调用微秒延时函数 */
  58. }
  59. #pragma pop /* 恢复编译器优化设置 */
  60. /**
  61. * @brief SPI 写入单个字节
  62. * @param Value 要写入的单字节数据
  63. * @note 此接口为软件SPI实现,具体实现方式可能因MCU平台而异。
  64. * @note 调用该函数前,必须先调用 SPI_CS_LOW() 函数拉低 CS 引脚。
  65. * @note 该函数会将 SPI_MOSI 引脚设置为输出模式,并在传输完成后将其设置为输入模式。
  66. * @note PAN3029/3060 SPI 接口使用的是 3 线 SPI 模式。
  67. * @note PAN3029/3060 SPI 配置为:
  68. * 时钟极性:低电平有效
  69. * 时钟相位:第一个边沿采样数据
  70. * 数据传输顺序:MSB优先
  71. * @note 以发送0xCC数据为例,时序图如下:
  72. * SPI_CS: ____________________________________________________
  73. * SPI_CLK: ____|‾‾|__|‾‾|__|‾‾|__|‾‾|__|‾‾|__|‾‾|__|‾‾|__|‾‾|__
  74. * SPI_MOSI: ___|‾‾‾‾‾‾‾‾‾‾|___________|‾‾‾‾‾‾‾‾‾‾‾|_____________
  75. * BIT DATA: 1 1 0 0 1 1 0 0
  76. */
  77. void SPI_WriteByte(uint8_t Value)
  78. {
  79. myRadioSpi_rwByte(Value);
  80. }
  81. /**
  82. * @brief SPI 读取单个字节
  83. * @return unsigned char 读取的数据字节
  84. * @note 此接口为软件SPI实现,具体实现方式可能因MCU平台而异。
  85. * @note 调用该函数前,必须先调用 SPI_CS_LOW() 函数拉低 CS 引脚。
  86. * @note 该函数会将 SPI_MOSI 引脚设置为输出模式,并在传输完成后将其设置为输入模式。
  87. * @note PAN3029/3060 SPI 接口使用的是 3 线 SPI 模式。
  88. * @note PAN3029/3060 SPI 配置为:
  89. * 时钟极性:低电平有效
  90. * 时钟相位:第一个边沿采样数据
  91. * 数据传输顺序:MSB优先
  92. * @note 以发送0x33数据为例,时序图如下:
  93. * SPI_CS: ___________________________________________________
  94. * SPI_CLK: ___|‾‾|__|‾‾|__|‾‾|__|‾‾|__|‾‾|__|‾‾|__|‾‾|__|‾‾|__
  95. * SPI_MISO: _____________|‾‾‾‾‾‾‾‾‾‾‾|___________|‾‾‾‾‾‾‾‾‾‾‾‾‾
  96. * BIT DATA: 0 0 1 1 0 0 1 1
  97. */
  98. unsigned char SPI_ReadByte(void)
  99. {
  100. return myRadioSpi_rwByte(0xFF);
  101. }
  102. /**
  103. * @brief Get the number of trailing zeros in a byte
  104. * @param Value The value to check
  105. * @return The number of trailing zeros
  106. */
  107. uint8_t __ctz(uint8_t Value)
  108. {
  109. int i;
  110. for (i = 0; i < 8; ++i)
  111. {
  112. if ((Value >> i) & 1)
  113. return (uint8_t)i;
  114. }
  115. return 0;
  116. }
  117. /**
  118. * @brief 从指定的寄存器读取单个字节
  119. * @param Addr 要读取的寄存器地址
  120. * @return uint8_t 从寄存器读取的值
  121. * @note 该函数的SPI_CS_LOW()、SPI_CS_HIGH()、SPI_WriteByte()
  122. * 和SPI_ReadByte()函数需要根据实际硬件实现进行修改。
  123. */
  124. uint8_t RF_ReadReg(uint8_t Addr)
  125. {
  126. uint8_t Temp;
  127. SPI_CS_LOW(); /* 片选信号拉低,开始SPI传输 */
  128. SPI_WriteByte((Addr << 1) & 0xFE); /* Bit7:0为地址,Bit0为读写位,Bit0=0表示读操作 */
  129. Temp = SPI_ReadByte(); /* 读取寄存器值 */
  130. SPI_CS_HIGH(); /* 片选信号拉高,结束SPI传输 */
  131. return Temp;
  132. }
  133. /**
  134. * @brief 写入单个字节到指定寄存器
  135. * @param Addr 要写入的寄存器地址
  136. * @param Value 要写入寄存器的单字节数据
  137. * @return RF_Err_t 返回操作结果
  138. * - RF_OK: 操作成功
  139. * - RF_FAIL: 操作失败
  140. * @note 该函数的SPI_CS_LOW()、SPI_CS_HIGH()、SPI_WriteByte()
  141. * 和SPI_ReadByte()函数需要根据实际硬件实现进行修改。
  142. */
  143. RF_Err_t RF_WriteReg(uint8_t Addr, uint8_t Value)
  144. {
  145. SPI_CS_LOW(); /* 片选信号拉低,开始SPI传输 */
  146. SPI_WriteByte((Addr << 1) | 0x01); /* Bit7:1为地址,Bit0为读写位,Bit0=1表示写操作 */
  147. SPI_WriteByte(Value); /* 写入寄存器值 */
  148. SPI_CS_HIGH(); /* 片选信号拉高,结束SPI传输 */
  149. #if USE_RF_REG_CHECK /* 是否使用寄存器回读确认功能 */
  150. /**
  151. * 该部分代码的作用是读取寄存器的值,并与写入的值进行比较,如果不相等则打印错误信息
  152. * 代码调试完成后可以注释掉或者删除掉。
  153. */
  154. {
  155. uint8_t Temp = RF_ReadReg(Addr);
  156. if (Temp == Value)
  157. {
  158. // printf("Write reg ok: 0x%02x, 0x%02x, 0x%02x\n", Addr, Value, Temp);
  159. return RF_OK; /* 写入的值与读取的值相等,返回操作成功 */
  160. }
  161. else
  162. {
  163. /* 读取的值与写入的值不相等,返回错误 */
  164. printf("Write reg fail: 0x%02x, 0x%02x, 0x%02x\n", Addr, Value, Temp);
  165. return RF_FAIL;
  166. }
  167. }
  168. #else
  169. return RF_OK;
  170. #endif
  171. }
  172. /**
  173. * @brief 连续写入多个字节到指定寄存器区
  174. * @param Addr 要写入的寄存器区的起始地址
  175. * @param Buffer 要写入寄存器的缓冲区指针
  176. * @param Size 要写入的字节数
  177. * @note 该函数的SPI_CS_LOW()、SPI_CS_HIGH()、SPI_WriteByte()函数需要根据实际硬件实现进行修改。
  178. */
  179. void RF_WriteRegs(uint8_t Addr, uint8_t *Buffer, uint8_t Size)
  180. {
  181. unsigned char i;
  182. SPI_CS_LOW(); /** 片选信号拉低,开始SPI传输 */
  183. SPI_WriteByte((Addr << 1) | 0x01); /** Bit7:1为地址,Bit0为读写位,Bit0=1表示写操作 */
  184. for (i = 0; i < Size; i++)
  185. {
  186. SPI_WriteByte(Buffer[i]); /** 写入寄存器值 */
  187. }
  188. SPI_CS_HIGH(); /** 片选信号拉高,结束SPI传输 */
  189. }
  190. /**
  191. * @brief 从指定的寄存器连续读取多个字节
  192. * @param Addr 要读取的寄存器地址
  193. * @param Buffer 存储读取数据的缓冲区指针
  194. * @param Size 要读取的字节数
  195. * @note 该函数的SPI_CS_LOW()、SPI_CS_HIGH()、SPI_WriteByte()
  196. * 和SPI_ReadByte()函数需要根据实际硬件实现进行修改。
  197. */
  198. void RF_ReadRegs(uint8_t Addr, uint8_t *Buffer, uint8_t Size)
  199. {
  200. unsigned char i;
  201. SPI_CS_LOW(); /* 片选信号拉低,开始SPI传输 */
  202. SPI_WriteByte((Addr << 1) & 0xFE); /* Bit7:0为地址,Bit0为读写位,Bit0=0表示读操作 */
  203. for (i = 0; i < Size; i++)
  204. {
  205. Buffer[i] = SPI_ReadByte(); /* 读取寄存器值 */
  206. }
  207. SPI_CS_HIGH(); /* 片选信号拉高,结束SPI传输 */
  208. }
  209. /**
  210. * @brief 选择寄存器页
  211. * @param Page 要选择的寄存器页,页范围0~3
  212. * @return RF_Err_t 返回操作结果
  213. * - RF_OK: 操作成功
  214. * - RF_FAIL: 操作失败
  215. * @note 如果当前页已经是所需页,则无需再配置寄存器
  216. */
  217. RF_Err_t RF_SetPage(uint8_t Page)
  218. {
  219. static uint8_t gCurrPage = 0xFF;
  220. if(gCurrPage == Page)
  221. {
  222. return RF_OK;
  223. }
  224. gCurrPage = Page;
  225. RF_ASSERT(RF_WriteReg(0x00, gCurrPage)); /* 选择寄存器页 */
  226. return RF_OK;
  227. }
  228. /**
  229. * @brief 写入单个字节到指定页的寄存器
  230. * @param Page 要写入的寄存器页,页范围0~3
  231. * @param Addr 要写入的寄存器地址
  232. * @param Value 要写入寄存器的单字节数据
  233. * @return RF_Err_t 返回操作结果
  234. * - RF_OK: 操作成功
  235. * - RF_FAIL: 操作失败
  236. */
  237. RF_Err_t RF_WritePageReg(uint8_t Page, uint8_t Addr, uint8_t Value)
  238. {
  239. RF_SetPage(Page);
  240. RF_WriteReg(Addr, Value);
  241. return RF_OK;
  242. }
  243. /**
  244. * @brief 写入多个字节到指定页的寄存器区间
  245. * @param Page 要写入的寄存器页,页范围0~3
  246. * @param Addr 要写入的寄存器地址
  247. * @param Buffer 要写入寄存器的缓冲区指针
  248. * @param Size 要写入的字节数
  249. */
  250. void RF_WritePageRegs(uint8_t Page, uint8_t Addr, uint8_t *Buffer, uint8_t Size)
  251. {
  252. RF_SetPage(Page); /* 选择寄存器页 */
  253. RF_WriteRegs(Addr, Buffer, Size); /* 写入寄存器值 */
  254. }
  255. /**
  256. * @brief 从指定页的寄存器读取单个字节
  257. * @param Page 要读取的寄存器页,页范围0~3
  258. * @param Addr 要读取的寄存器地址
  259. * @return uint8_t 从寄存器读取的值
  260. */
  261. uint8_t RF_ReadPageReg(uint8_t Page, uint8_t Addr)
  262. {
  263. RF_SetPage(Page);
  264. return RF_ReadReg(Addr);
  265. }
  266. /**
  267. * @brief 从指定页的寄存器区间读取多个字节
  268. * @param Page 要读取的寄存器页,页范围0~3
  269. * @param Addr 要读取的寄存器地址
  270. * @param Buffer 存储读取数据的缓冲区指针
  271. * @param Size 要读取的字节数
  272. */
  273. void RF_ReadPageRegs(uint8_t Page, uint8_t Addr, uint8_t *Buffer, uint8_t Size)
  274. {
  275. RF_SetPage(Page); /* 选择寄存器页 */
  276. RF_ReadRegs(Addr, Buffer, Size); /* 读取寄存器值 */
  277. }
  278. /**
  279. * @brief 置位指定页的寄存器位
  280. * @param Page 要读取的寄存器页,页范围0~3
  281. * @param Addr 要设置的寄存器地址
  282. * @param Mask 要设置的位掩码
  283. * @return RF_Err_t 返回操作结果
  284. * - RF_OK: 操作成功
  285. * - RF_FAIL: 操作失败
  286. */
  287. RF_Err_t RF_SetPageRegBits(uint8_t Page, uint8_t Addr, uint8_t Mask)
  288. {
  289. uint8_t Temp;
  290. RF_SetPage(Page);
  291. Temp = RF_ReadReg(Addr);
  292. RF_WriteReg(Addr, Temp | Mask);
  293. return RF_OK;
  294. }
  295. /**
  296. * @brief 复位指定页的寄存器位
  297. * @param Page 要读取的寄存器页,页范围0~3
  298. * @param Addr 要重置的寄存器地址
  299. * @param Mask 要重置的位掩码
  300. * @return RF_Err_t 返回操作结果
  301. * - RF_OK: 操作成功
  302. * - RF_FAIL: 操作失败
  303. */
  304. RF_Err_t RF_ResetPageRegBits(uint8_t Page, uint8_t Addr, uint8_t Mask)
  305. {
  306. uint8_t Temp;
  307. RF_SetPage(Page); /* 选择寄存器页 */
  308. Temp = RF_ReadReg(Addr); /* 读取寄存器值 */
  309. RF_WriteReg(Addr, Temp & (~Mask)); /* 清除寄存器中与掩码对应的位 */
  310. return RF_OK;
  311. }
  312. /**
  313. * @brief 写入指定页的寄存器位
  314. * @param Page 要读取的寄存器页,页范围0~3
  315. * @param Addr 要写入的寄存器地址
  316. * @param Value 要写入的值
  317. * @param Mask 要写入的位掩码
  318. * @return RF_Err_t 返回操作结果
  319. * - RF_OK: 操作成功
  320. * - RF_FAIL: 操作失败
  321. * @note 该函数会先清除寄存器中与掩码对应的位,然后再设置新的值
  322. * @note 比如要设置第1页0x08寄存器的第2位和第3位为0b10,其他位不变,可以调用
  323. * RF_WritePageRegBits(1, 0x08, 0x02, 0x0C);
  324. * 其中Value = 0x02, Mask = 0x0C,Value不需要左移,因为掩码已经指定了要设置的位
  325. */
  326. RF_Err_t RF_WritePageRegBits(uint8_t Page, uint8_t Addr, uint8_t Value, uint8_t Mask)
  327. {
  328. uint8_t Temp;
  329. uint8_t shift = __ctz(Mask); /* 获取掩码的位移值 */
  330. Value <<= shift; /* 将值左移到掩码对应的位置 */
  331. Value &= Mask; /* 将值与掩码进行与操作,确保只设置掩码对应的位 */
  332. RF_SetPage(Page); /* 选择寄存器页 */
  333. Temp = RF_ReadReg(Addr); /* 读取寄存器值 */
  334. RF_WriteReg(Addr, (Temp & (~Mask)) | Value); /* 清除寄存器中与掩码对应的位,然后设置新的值 */
  335. return RF_OK;
  336. }
  337. /**
  338. * @brief 配置GPIO模式
  339. * @param <GpioPin> 引脚号
  340. * <GpioMode> GPIO模式
  341. * - RF_GPIO_MODE_INPUT: 输入模式
  342. * - RF_GPIO_MODE_OUTPUT: 输出模式
  343. * @return RF_Err_t 返回操作结果
  344. * - RF_OK: 操作成功
  345. * - RF_FAIL: 操作失败
  346. */
  347. RF_Err_t RF_ConfigGpio(uint8_t GpioPin, uint8_t GpioMode)
  348. {
  349. if(GpioMode == RF_GPIO_MODE_INPUT)
  350. {
  351. if(GpioPin < 8)
  352. {
  353. RF_ASSERT(RF_SetPageRegBits(0, 0x63, (1 << GpioPin)));
  354. }
  355. else
  356. {
  357. RF_ASSERT(RF_SetPageRegBits(0, 0x64, (1 << (GpioPin - 8))));
  358. }
  359. }
  360. else if(GpioMode == RF_GPIO_MODE_OUTPUT)
  361. {
  362. if(GpioPin < 8)
  363. {
  364. RF_SetPageRegBits(0, 0x65, (1 << GpioPin));
  365. }
  366. else
  367. {
  368. RF_SetPageRegBits(0, 0x66, (1 << (GpioPin - 8)));
  369. }
  370. }
  371. else
  372. {
  373. return RF_FAIL;
  374. }
  375. return RF_OK;
  376. }
  377. /**
  378. * @brief 控制GPIO输出电平
  379. * @param <GpioPin> 引脚号
  380. * <Level> GPIO电平
  381. * - 0: 低电平
  382. * - 1: 高电平
  383. * @return RF_Err_t 返回操作结果
  384. * - RF_OK: 操作成功
  385. * - RF_FAIL: 操作失败
  386. */
  387. RF_Err_t RF_WriteGpioLevel(uint8_t GpioPin, uint8_t Level)
  388. {
  389. if(GpioPin < 8)
  390. {
  391. RF_WritePageRegBits(0, 0x67, Level, (1 << GpioPin));
  392. }
  393. else
  394. {
  395. RF_WritePageRegBits(0, 0x68, Level, (1 << (GpioPin - 8)));
  396. }
  397. return RF_OK;
  398. }
  399. /**
  400. * @brief 读取GPIO电平
  401. * @param <GpioPin> 引脚号
  402. * @return 读取的GPIO电平
  403. * - 0: 低电平
  404. * - 1: 高电平
  405. */
  406. uint8_t RF_ReadGpioLevel(uint8_t GpioPin)
  407. {
  408. uint8_t Temp;
  409. if(GpioPin < 6)
  410. {
  411. Temp = RF_ReadPageReg(0, 0x74);
  412. }
  413. else
  414. {
  415. Temp = RF_ReadPageReg(0, 0x75);
  416. GpioPin -= 6;
  417. }
  418. return (bool)((Temp >> GpioPin) & 0x01);
  419. }
  420. /**
  421. * @brief 初始化PAN3029/3060的天线控制GPIO
  422. * @note 该函数用于初始化PAN3029/3060的天线控制GPIO,将其配置为输出模式,并设置初始电平为低
  423. * @note 如果使用MCU的GPIO控制天线开关时,则需要重新适配该函数
  424. */
  425. void RF_InitAntGpio(void)
  426. {
  427. RF_ConfigGpio(MODULE_GPIO_RX, RF_GPIO_MODE_OUTPUT);
  428. RF_ConfigGpio(MODULE_GPIO_TX, RF_GPIO_MODE_OUTPUT);
  429. RF_WriteGpioLevel(MODULE_GPIO_RX, 0);
  430. RF_WriteGpioLevel(MODULE_GPIO_TX, 0);
  431. }
  432. /**
  433. * @brief 打开PAN3029/3060的发射天线
  434. * @note 该函数用于打开PAN3029/3060的发射天线,将TX引脚设置为高电平,RX引脚设置为低电平
  435. * @note 如果使用MCU的GPIO控制天线开关时,则需要重新适配该函数
  436. */
  437. void RF_TurnonTxAnt(void)
  438. {
  439. RF_WriteGpioLevel(MODULE_GPIO_RX, 0);
  440. RF_WriteGpioLevel(MODULE_GPIO_TX, 1);
  441. }
  442. /**
  443. * @brief 打开PAN3029/3060的接收天线
  444. * @note 该函数用于打开PAN3029/3060的接收天线,将RX引脚设置为高电平,TX引脚设置为低电平
  445. * @note 如果使用MCU的GPIO控制天线开关时,则需要重新适配该函数
  446. */
  447. void RF_TurnonRxAnt(void)
  448. {
  449. RF_WriteGpioLevel(MODULE_GPIO_TX, 0);
  450. RF_WriteGpioLevel(MODULE_GPIO_RX, 1);
  451. }
  452. /**
  453. * @brief 关闭PAN3029/3060的天线
  454. * @note 该函数用于关闭PAN3029/3060的天线,将RX和TX引脚都设置为低电平
  455. * @note 如果使用MCU的GPIO控制天线开关时,则需要重新适配该函数
  456. */
  457. void RF_ShutdownAnt(void)
  458. {
  459. RF_WriteGpioLevel(MODULE_GPIO_RX, 0);
  460. RF_WriteGpioLevel(MODULE_GPIO_TX, 0);
  461. }
  462. /**
  463. * @brief 初始化TCXO控制GPIO
  464. * @note 该函数用于初始化PAN3029/3060的TCXO控制GPIO,将其配置为输出模式,并设置初始电平为高
  465. * @note 如果使用MCU的GPIO控制TCXO开关时,则需要重新适配该函数
  466. */
  467. void RF_InitTcxoGpio(void)
  468. {
  469. RF_ConfigGpio(MODULE_GPIO_TCXO, RF_GPIO_MODE_OUTPUT);
  470. RF_WriteGpioLevel(MODULE_GPIO_TCXO, 1);
  471. }
  472. /**
  473. * @brief 打开TCXO的供电电源
  474. * @note 该函数用于打开PAN3029/3060的TCXO,将TCXO引脚设置为高电平
  475. * @note 如果使用MCU的GPIO控制TCXO开关时,则需要重新适配该函数
  476. */
  477. void RF_TurnonTcxo(void)
  478. {
  479. RF_WriteGpioLevel(MODULE_GPIO_TCXO, 1);
  480. }
  481. /**
  482. * @brief 关闭TCXO的供电电源
  483. * @note 该函数用于关闭PAN3029/3060的TCXO,将TCXO引脚设置为低电平
  484. * @note 如果使用MCU的GPIO控制TCXO开关时,则需要重新适配该函数
  485. */
  486. void RF_TurnoffTcxo(void)
  487. {
  488. RF_WriteGpioLevel(MODULE_GPIO_TCXO, 0);
  489. }
  490. /**
  491. * @brief Enable LDO PA
  492. */
  493. void RF_TurnonLdoPA(void)
  494. {
  495. RF_SetPageRegBits(0, 0x4F, 0x08);
  496. }
  497. /*
  498. * @brief Disable LDO PA
  499. */
  500. void RF_TurnoffLdoPA(void)
  501. {
  502. RF_ResetPageRegBits(0, 0x4F, 0x08);
  503. }
  504. /**
  505. * @brief 关闭内部和外部PA
  506. */
  507. void RF_TurnoffPA(void)
  508. {
  509. RF_TurnoffLdoPA(); /* 关闭内部PA */
  510. RF_ShutdownAnt(); /* 关闭外部PA */
  511. /* 发射完成后,若配置为DCDC电源模式,则需要切换回DCDC电源模式 */
  512. if(g_RfCfgParams.RegulatorMode == USE_DCDC)
  513. {
  514. RF_WritePageReg(3, 0x24, 0x08);
  515. }
  516. }
  517. /**
  518. * @brief 打开内部和外部PA
  519. */
  520. void RF_TurnonPA(void)
  521. {
  522. /* 若当前为DCDC电源模式,发射前须切换至LDO电源模式 */
  523. if(g_RfCfgParams.RegulatorMode == USE_DCDC)
  524. {
  525. RF_WritePageReg(3, 0x24, 0x00);
  526. }
  527. RF_TurnonLdoPA(); /* 打开内部PA */
  528. RF_TurnonTxAnt(); /* 打开外部PA */
  529. }
  530. /**
  531. * @brief 设置芯片模式
  532. * @param <ChipMode> 芯片模式
  533. * - CHIPMODE_MODE0
  534. * - CHIPMODE_MODE1
  535. */
  536. void RF_SetChipMode(RfChipMode_t ChipMode)
  537. {
  538. if(ChipMode == CHIPMODE_MODE0)
  539. {
  540. /* Mode0 config */
  541. RF_WritePageRegBits(1, 0x25, 0, 0xF0);
  542. RF_WritePageRegBits(1, 0x25, 0, 0x08);
  543. RF_WritePageRegBits(3, 0x12, 1, 0x04);
  544. RF_WritePageRegBits(3, 0x12, 1, 0x10);
  545. RF_WritePageRegBits(0, 0x58, 1, 0x04); /* Enable crc interrupt */
  546. }
  547. else
  548. {
  549. /* Mode1 config */
  550. RF_WritePageRegBits(1, 0x25, 4, 0xF0);
  551. RF_WritePageRegBits(1, 0x25, 1, 0x08);
  552. RF_WritePageRegBits(3, 0x12, 0, 0x04);
  553. RF_WritePageRegBits(3, 0x12, 0, 0x10);
  554. RF_WritePageRegBits(0, 0x58, 0, 0x04); /* Disable crc interrupt */
  555. }
  556. g_RfCfgParams.ChipMode = ChipMode;
  557. }
  558. /**
  559. * @brief 获取芯片模式
  560. * @param -
  561. */
  562. RfChipMode_t RF_GetChipMode(void)
  563. {
  564. return g_RfCfgParams.ChipMode;
  565. }
  566. /**
  567. * @brief 从信息区读取字节
  568. * @param <Addr> 寄存器地址
  569. * <Pattern> 模式匹配值
  570. * <InfoAddr> 信息区地址
  571. * @return 从信息区读取的字节值
  572. */
  573. uint8_t RF_ReadInfoByte(uint8_t Addr, uint16_t Pattern, uint8_t InfoAddr)
  574. {
  575. uint8_t Value;
  576. uint8_t Buffer[3];
  577. uint16_t Timeout = 10000;
  578. Buffer[0] = Pattern >> 8;
  579. Buffer[1] = Pattern & 0xFF;
  580. Buffer[2] = InfoAddr << 1;
  581. RF_WritePageRegs(2, Addr, Buffer, sizeof(Buffer));
  582. do
  583. {
  584. if (RF_ReadPageReg(0, 0x6C) & 0x80)
  585. {
  586. break;
  587. }
  588. } while (Timeout--);
  589. Value = RF_ReadPageReg(2, Addr);
  590. return Value;
  591. }
  592. /**
  593. * @brief 校准RF相关参数
  594. * @return RF_Err_t 返回操作结果
  595. * - RF_OK: 操作成功
  596. * - RF_FAIL: 操作失败
  597. */
  598. RF_Err_t RF_Calibrate(void)
  599. {
  600. int i;
  601. uint8_t Temp[3] = {0};
  602. /* Temp[0]: efuse[0x1E] - DCDCIMAX
  603. Temp[1]: efuse[0x1F] - DCDCREF
  604. Temp[2]: efuse[0x20] - PABIAS */
  605. RF_ResetPageRegBits(2, 0x3E, 0x08); // Unlock info
  606. for (i = 0; i < sizeof(Temp); i++)
  607. {
  608. Temp[i] = RF_ReadInfoByte(0x3B, 0x5AA5, 0x1E + i);
  609. }
  610. if (RF_ReadInfoByte(0x3B, 0x5AA5, 0x1C) == 0x5A)
  611. {
  612. RF_WritePageReg(2, 0x3D, 0xFD);
  613. if (Temp[2] != 0)
  614. {
  615. /* Write PABIAS */
  616. RF_WritePageReg(0, 0x45, Temp[2]);
  617. }
  618. RF_WritePageReg(3, 0x1C, (0xC0 | (Temp[0] & 0x1F))); /* Write DCDCIMAX */
  619. RF_WritePageReg(3, 0x1D, Temp[1]); /* Write DCDCREF */
  620. }
  621. RF_ASSERT(RF_SetPageRegBits(2, 0x3E, 0x08)); // Lock info
  622. return RF_OK;
  623. }
  624. /**
  625. * @brief Configure AGC function
  626. * @return RF_Err_t 返回操作结果
  627. * - RF_OK: 操作成功
  628. * - RF_FAIL: 操作失败
  629. */
  630. RF_Err_t RF_ConfigAgc(void)
  631. {
  632. /* Enable AGC function
  633. - [Page2][0x06][Bit0] equal to 0 means enable AGC function
  634. - [Page2][0x06][Bit1] equal to 1 means disable AGC function */
  635. RF_ASSERT(RF_ResetPageRegBits(2, 0x06, 0x01));
  636. #if REGION_DEFAULT == REGION_CN470_510
  637. RF_WritePageRegs(2, 0x0A, (uint8_t *)g_LowFreqAgcCfg, 40);
  638. #elif REGION_DEFAULT == REGION_EU_863_870 || REGION_DEFAULT == REGION_US_902_928
  639. RF_WritePageRegs(2, 0x0A, (uint8_t *)g_HighFreqAgcCfg, 40);
  640. #endif
  641. RF_ASSERT(RF_WritePageReg(2, 0x34, 0xEF));
  642. return RF_OK;
  643. }
  644. /**
  645. * @brief 配置RF寄存器的默认参数
  646. * @return RF_Err_t 返回操作结果
  647. * - RF_OK: 操作成功
  648. * - RF_FAIL: 操作失败
  649. */
  650. RF_Err_t RF_ConfigDefaultParams(void)
  651. {
  652. int i;
  653. for(i = 0; i < sizeof(g_RfDefaultConfig)/sizeof(PAN_RegCfg_t); i++)
  654. {
  655. RF_WritePageReg(g_RfDefaultConfig[i].Page, g_RfDefaultConfig[i].Addr, g_RfDefaultConfig[i].Value);
  656. }
  657. return RF_OK;
  658. }
  659. /**
  660. * @brief 上电后初始化RF收发器到STB3状态
  661. * @return RF_Err_t 返回操作结果
  662. * - RF_OK: 操作成功
  663. * - RF_FAIL: 操作失败
  664. * @note 调用此函数前需要先配置好MCU的SPI和相关GPIO引脚
  665. */
  666. RF_Err_t RF_Init(void)
  667. {
  668. #if USE_RF_RST_GPIO == 1
  669. RF_RESET_PIN_LOW(); /* 拉低芯片复位引脚,开始复位 */
  670. RF_DelayUs(100); /* 保证实际延时在100us以上 */
  671. RF_RESET_PIN_High(); /* 拉高芯片复位引脚,释放复位 */
  672. RF_DelayUs(100); /* 保证实际延时在100us以上 */
  673. #endif
  674. /* [Pagex][0x04][BIT4]为复位控制,为0时复位芯片,为1时复位释放 */
  675. RF_WriteReg(0x04, 0x06); /* 开始POR复位芯片*/
  676. RF_DelayUs(100); /* 保证实际延时在100us以上 */
  677. #if INTERFACE_MODE == USE_SPI_4LINE
  678. RF_WriteReg(0x00, 0x03); /* 选择寄存器页3 */
  679. RF_WriteReg(0x1A, 0x03); /* 使能4line SPI */
  680. #elif INTERFACE_MODE == USE_SPI_3LINE
  681. RF_WriteReg(0x00, 0x03); /* 选择寄存器页3 */
  682. RF_WriteReg(0x1A, 0x83); /* 使能3ine SPI */
  683. #endif
  684. RF_SetPage(0); /* 选择寄存器页0 */
  685. RF_ASSERT(RF_WriteReg(0x02, RF_STATE_DEEPSLEEP)); /* 进入deepsleep状态 */
  686. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  687. RF_ASSERT(RF_WriteReg(0x02, RF_STATE_SLEEP)); /* 进入sleep状态 */
  688. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  689. RF_ASSERT(RF_WritePageReg(3, 0x06, 0x20)); /* 使能ISO */
  690. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  691. RF_ASSERT(RF_WriteReg(0x02, RF_STATE_STB1)); /* 进入stb1状态 */
  692. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  693. #if USE_ACTIVE_CRYSTAL == 1 /* 如果使用有源晶振,则需要配置TCXO GPIO引脚 */
  694. RF_ASSERT(RF_WritePageReg(3, 0x26, 0xA0)); /* 使能内核电源,并打开有源晶振通道 */
  695. RF_DelayUs(100); /* 保证实际延时在100us以上 */
  696. RF_ASSERT(RF_WriteReg(0x04, 0x36)); /* 使能LFT并释放POR复位 */
  697. RF_DelayMs(1); /* 保证实际延时在1ms以上 */
  698. RF_InitTcxoGpio(); /* 初始化TCXO GPIO引脚 */
  699. #else
  700. RF_ASSERT(RF_WritePageReg(3, 0x26, 0x20)); /* 使能内核电源 */
  701. RF_DelayUs(100); /* 保证实际延时在100us以上 */
  702. RF_ASSERT(RF_WriteReg(0x04, 0x36)); /* 使能LFT并释放POR复位 */
  703. RF_DelayMs(1); /* 保证实际延时在1ms以上 */
  704. #endif
  705. RF_ASSERT(RF_WriteReg(0x02, RF_STATE_STB2)); /* 进入stb2状态 */
  706. RF_DelayMs(1); /* 保证实际延时在1ms以上 */
  707. RF_ASSERT(RF_WriteReg(0x02, RF_STATE_STB3)); /* 进入stb3状态 */
  708. RF_DelayUs(100); /* 保证实际延时在100us以上 */
  709. RF_ASSERT(RF_ConfigDefaultParams()); /* 配置RF寄存器的默认参数 */
  710. RF_ASSERT(RF_Calibrate()); /* 校准RF相关参数 */
  711. RF_ASSERT(RF_ConfigAgc()); /* 配置AGC功能 */
  712. RF_InitAntGpio(); /* 初始化天线GPIO引脚 */
  713. g_RfOperatetate = RF_STATE_STB3; /* 设置当前工作状态为STB3 */
  714. return RF_OK;
  715. }
  716. /**
  717. * @brief 配置RF芯片的用户参数
  718. */
  719. void RF_ConfigUserParams(void)
  720. {
  721. RF_SetTxPower(22); /* 设置功率档位 */
  722. RF_SetFreq(RF_FREQ_DEFAULT); /* 设置频率 */
  723. RF_SetBW(RF_BW_DEFAULT); /* 设置带宽 */
  724. RF_SetSF(RF_SF_DEFAULT); /* 设置扩频因子 */
  725. RF_SetCR(RF_CR_DEFAULT); /* 设置信道编码率 */
  726. RF_SetCRC(RF_CRC_DEFAULT); /* 设置CRC校验 */
  727. RF_SetLDR(RF_LDR_DEFAULT); /* 设置低速率模式 */
  728. RF_SetPreamLen(RF_PREAMBLE_DEFAULT); /* 设置前导码长度 */
  729. RF_SetInvertIQ(RF_IQ_INVERT_DEFAULT); /* 设置IQ不反转 */
  730. RF_SetRegulatorMode(USE_LDO); /* 设置芯片为LDO电源模式 */
  731. RF_SetChipMode(CHIPMODE_MODE0); /* 设置芯片模式为MODE0 */
  732. }
  733. /**
  734. * @brief 软件复位RF芯片控制逻辑
  735. */
  736. void RF_ResetLogic(void)
  737. {
  738. RF_WriteReg(0x00, 0x80);
  739. RF_WriteReg(0x00, 0x00);
  740. (void)RF_ReadReg(0x00); /* 需要空读一次寄存器0x00,才能使复位生效 */
  741. }
  742. /**
  743. * @brief 获取RF芯片的工作状态
  744. * @return RfOpState_t 当前工作状态
  745. * - RF_STATE_SLEEP: 芯片处于睡眠模式
  746. * - RF_STATE_STB3: 芯片处于待机模式
  747. * - RF_STATE_TX: 芯片处于发射模式
  748. * - RF_STATE_RX: 芯片处于接收模式
  749. */
  750. RfOpState_t RF_GetOperateState(void)
  751. {
  752. return g_RfOperatetate;
  753. }
  754. /**
  755. * @brief 设置RF芯片的工作状态
  756. * @param <RfState> 工作状态
  757. * - RF_STATE_SLEEP: 芯片处于睡眠模式
  758. * - RF_STATE_STB3: 芯片处于待机模式
  759. * - RF_STATE_TX: 芯片处于发射模式
  760. * - RF_STATE_RX: 芯片处于接收模式
  761. */
  762. void RF_SetOperateState(RfOpState_t RfState)
  763. {
  764. g_RfOperatetate = RfState;
  765. }
  766. /**
  767. * @brief 设置RF芯片的工作状态
  768. * @param <RfState>
  769. * - RF_STATE_DEEPSLEEP
  770. * - RF_STATE_SLEEP
  771. * - RF_STATE_STB3
  772. * - RF_STATE_TX
  773. * - RF_STATE_RX
  774. */
  775. void RF_SetRfState(uint8_t RfState)
  776. {
  777. RF_WriteReg(0x02, RfState);
  778. g_RfOperatetate = (RfOpState_t)RfState;
  779. }
  780. /**
  781. * @brief 进入深度睡眠模式
  782. * @note 该函数用于将RF芯片置于深度睡眠模式,关闭天线供电和TCXO电源
  783. * @note 该函数会将芯片的工作状态设置为MODE_DEEPSLEEP
  784. * @note 执行该函数后,如需唤醒RF芯片,需要调用RF_Init()函数唤醒芯片
  785. */
  786. void RF_EnterDeepsleepState(void)
  787. {
  788. RF_ShutdownAnt(); /* 关闭天线 */
  789. RF_WriteReg(0x02, RF_STATE_STB3); /* 进入STB3状态 */
  790. RF_DelayUs(150); /* 保证实际延时在150us以上 */
  791. RF_WriteReg(0x02, RF_STATE_STB2); /* 进入STB2状态 */
  792. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  793. RF_WriteReg(0x02, RF_STATE_STB1); /* 进入STB1状态 */
  794. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  795. #if USE_ACTIVE_CRYSTAL == 1 /* 如果使用有源晶振,则需要关闭TCXO电源 */
  796. RF_TurnoffTcxo(); /* 关闭TCXO电源 */
  797. #endif
  798. RF_WriteReg(0x04, 0x06); /* 关闭LFT */
  799. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  800. RF_WriteReg(0x02, RF_STATE_SLEEP); /* 进入SLEEP状态 */
  801. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  802. RF_WritePageReg(3, 0x06, 0x00); /* 关闭ISO */
  803. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  804. RF_WritePageReg(3, 0x26, 0x00); /* 关闭内部电源 */
  805. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  806. RF_WriteReg(0x02, RF_STATE_DEEPSLEEP); /* 进入DEEPSLEEP状态 */
  807. g_RfOperatetate = RF_STATE_DEEPSLEEP;
  808. }
  809. /**
  810. * @brief 进入睡眠模式
  811. * @note 该函数用于将RF芯片置于睡眠模式,关闭天线供电和TCXO电源
  812. * @note 该函数会将芯片的工作状态设置为MODE_SLEEP
  813. * @note 执行该函数后,如需唤醒RF芯片,需要调用RF_ExitSleepState()函数
  814. */
  815. void RF_EnterSleepState(void)
  816. {
  817. RF_ShutdownAnt(); /* 关闭天线 */
  818. RF_WriteReg(0x02, RF_STATE_STB3); /* 进入STB3状态 */
  819. RF_DelayUs(150); /* 保证实际延时在150us以上 */
  820. RF_WriteReg(0x02, RF_STATE_STB2); /* 进入STB2状态 */
  821. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  822. RF_WriteReg(0x02, RF_STATE_STB1); /* 进入STB1状态 */
  823. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  824. #if USE_ACTIVE_CRYSTAL == 1 /* 如果使用有源晶振,则需要关闭TCXO电源 */
  825. RF_TurnoffTcxo(); /* 关闭TCXO电源 */
  826. #endif
  827. RF_WriteReg(0x04, 0x16); /* 关闭LFT */
  828. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  829. RF_WriteReg(0x02, RF_STATE_SLEEP); /* 进入SLEEP状态 */
  830. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  831. RF_ResetPageRegBits(3, 0x06, 0x20); /* 关闭ISO */
  832. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  833. RF_WritePageReg(3, 0x26, 0x00); /* 关闭内部电源 */
  834. g_RfOperatetate = RF_STATE_SLEEP;
  835. }
  836. /**
  837. * @brief 退出睡眠模式
  838. * @note 该函数用于将RF芯片退出睡眠模式,打开天线供电和TCXO电源
  839. * @note 该函数会将芯片的工作状态设置为MODE_STDBY
  840. */
  841. void RF_ExitSleepState(void)
  842. {
  843. RF_SetPageRegBits(3, 0x06, 0x20); /* 使能ISO */
  844. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  845. RF_WriteReg(0x02, RF_STATE_STB1); /* 进入STB1状态 */
  846. RF_DelayUs(10); /* 保证实际延时在10us以上 */
  847. #if USE_ACTIVE_CRYSTAL == 1
  848. RF_WritePageReg(3, 0x26, 0xA0); /* 使能内核电源,并打开有源晶振通道 */
  849. RF_DelayUs(100); /* 保证实际延时在100us以上 */
  850. RF_WriteReg(0x04, 0x36); /* 使能LFT */
  851. RF_DelayUs(100); /* 保证实际延时在100us以上 */
  852. RF_TurnonTcxo(); /* 打开TCXO */
  853. #else
  854. RF_WritePageReg(3, 0x26, 0x20); /* 使能内核电源 */
  855. RF_DelayUs(100); /* 保证实际延时在100us以上 */
  856. RF_WriteReg(0x04, 0x36); /* 使能LFT */
  857. RF_DelayUs(100); /* 保证实际延时在100us以上 */
  858. #endif
  859. RF_WriteReg(0x02, RF_STATE_STB2); /* 进入STB2状态 */
  860. RF_DelayMs(1); /* 保证实际延时在1ms以上 */
  861. RF_WriteReg(0x02, RF_STATE_STB3); /* 进入STB3状态 */
  862. RF_DelayUs(100); /* 保证实际延时在100us以上 */
  863. g_RfOperatetate = RF_STATE_STB3;
  864. }
  865. /**
  866. * @brief 进入待机模式
  867. * @note 该函数会将芯片的工作状态设置为MODE_STDBY
  868. */
  869. void RF_EnterStandbyState(void)
  870. {
  871. RF_SetRfState(RF_STATE_STB3);
  872. RF_SetOperateState(RF_STATE_STB3);
  873. }
  874. /**
  875. * @brief 检查RF芯片是否处于休眠状态
  876. * @note 该函数用于检查RF芯片是否处于休眠状态,
  877. * @note 如果处于睡眠状态,则退出睡眠状态进入待机状态
  878. * @note 该函数会将芯片的工作状态设置为MODE_STDBY
  879. */
  880. void RF_CheckDeviceReady(void)
  881. {
  882. if (RF_GetOperateState() == RF_STATE_SLEEP)
  883. {
  884. RF_ExitSleepState();
  885. }
  886. }
  887. /**
  888. * @brief 设置芯片的供电模式
  889. * @param <RegulatorMode> 供电模式
  890. * - USE_LDO: 使用LDO供电
  891. * - USE_DCDC: 使用DCDC供电
  892. * @note 在发射状态下,RF必须使用LDO电源模式,
  893. * 其它状态下可任意选择电源供电模式。
  894. */
  895. void RF_SetRegulatorMode(RfRegulatorMode_t RegulatorMode)
  896. {
  897. RF_WritePageReg(3, 0x24, (RegulatorMode == USE_DCDC) ? 0x08 : 0x00);
  898. g_RfCfgParams.RegulatorMode = RegulatorMode;
  899. }
  900. /**
  901. * @brief 设置RF芯片的频率
  902. * @param <Frequency> 通信频率(Hz)
  903. * @note 支持的频率范围为:
  904. * 低频段:
  905. * - 138.33MHz ~ 282.5MHz
  906. * - 405.00MHz ~ 565.00MHz
  907. * 高频段:
  908. * - 810.00MHz ~ 1080.00MHz
  909. */
  910. RF_Err_t RF_SetFreq(uint32_t Frequency)
  911. {
  912. int i;
  913. uint32_t Fa, Fb;
  914. uint32_t Temp = 0;
  915. uint32_t IntegerPart;
  916. uint8_t FreqReg[4], Fab[3];
  917. uint32_t FreqTableNum = (sizeof(g_RfFreqTable) / sizeof(RadioFreqTable_t));
  918. if (Frequency < g_RfFreqTable[0].StartFreq || Frequency > g_RfFreqTable[FreqTableNum - 1].StopFreq)
  919. {
  920. return RF_FAIL;
  921. }
  922. /* 遍历频率表,找到匹配的频率段 */
  923. for (i = 0; i < FreqTableNum; i++)
  924. {
  925. if (Frequency > g_RfFreqTable[i].StartFreq && Frequency <= g_RfFreqTable[i].StopFreq)
  926. {
  927. uint8_t LoMux = (g_RfFreqTable[i].LoParam & 0x70) >> 4;
  928. Temp = Frequency * g_VcoDivTable[LoMux];
  929. RF_WritePageRegs(0, 0x40, (uint8_t *)&g_RfFreqTable[i].VcoParam, 2);
  930. RF_WriteReg(0x3D, g_RfFreqTable[i].LoParam);
  931. break;
  932. }
  933. }
  934. /* No frequency range matched */
  935. if (i >= FreqTableNum)
  936. {
  937. return RF_FAIL;
  938. }
  939. IntegerPart = Temp / 32000000;
  940. Fa = IntegerPart - 20;
  941. Fb = (Temp % 32000000) / 40000;
  942. FreqReg[0] = (uint8_t)Frequency;
  943. FreqReg[1] = (uint8_t)(Frequency >> 8);
  944. FreqReg[2] = (uint8_t)(Frequency >> 16);
  945. FreqReg[3] = (uint8_t)(Frequency >> 24);
  946. RF_WritePageRegs(3, 0x09, FreqReg, 4);
  947. Fab[0] = (uint8_t)(Fa);
  948. Fab[1] = (uint8_t)(Fb);
  949. Fab[2] = (uint8_t)((Fb >> 8) & 0x0F);
  950. RF_WritePageRegs(3, 0x15, Fab, 3);
  951. g_RfCfgParams.Frequency = Frequency;
  952. return RF_OK;
  953. }
  954. /**
  955. * @brief 设置IQ反转
  956. * @param <NewState> 使能或禁用IQ反转
  957. * - true: 使能IQ反转
  958. * - false: 禁用IQ反转
  959. */
  960. void RF_SetInvertIQ(bool NewState)
  961. {
  962. if (NewState)
  963. {
  964. /*
  965. * BIT6 = 0: invert rx IQ
  966. * BIT5 = 1: invert tx IQ
  967. */
  968. RF_WritePageRegBits(1, 0x0E, 0x01, 0x40 | 0x20);
  969. g_RfCfgParams.InvertIQ = RF_IQ_INVERTED;
  970. }
  971. else
  972. {
  973. /*
  974. * BIT6 = 1: non-invert rx IQ
  975. * BIT5 = 0: non-invert tx IQ
  976. */
  977. RF_WritePageRegBits(1, 0x0E, 0x02, 0x40 | 0x20);
  978. g_RfCfgParams.InvertIQ = RF_IQ_NORMAL;
  979. }
  980. }
  981. /**
  982. * @brief 设置前导码长度
  983. * @param <PreamLen> 前导码长度值
  984. * 范围为4 - 65535
  985. */
  986. void RF_SetPreamLen(uint16_t PreamLen)
  987. {
  988. uint8_t Temp[2] = {(uint8_t)(PreamLen), (uint8_t)((PreamLen >> 8))};
  989. RF_WritePageRegs(3, 0x13, Temp, 2);
  990. g_RfCfgParams.PreambleLen = PreamLen;
  991. }
  992. /**
  993. * @brief 设置同步字
  994. * @param <syncWord> 同步字值
  995. * @note PAN3029/3060支持的同步字大小为1字节
  996. * @note 同步字用于接收数据包时的同步检测,通常在发送和接收数据包时需要设置相同的同步字
  997. * 例如,如果发送数据包时设置了同步字为0x12,则在接收数据包时也需要设置同步字为0x12
  998. */
  999. void RF_SetSyncWord(uint8_t SyncWord)
  1000. {
  1001. RF_WritePageReg(3, 0x0F, SyncWord);
  1002. g_RfCfgParams.SyncWord = SyncWord;
  1003. }
  1004. /**
  1005. * @brief 设置发射功率
  1006. * @param <TxPower> 发射档位,档位范围:1-22
  1007. * @note 功率档位对应的功率值如下表所示:
  1008. *|------|------------------|------------------|------------------|------------------|
  1009. *| 档位 | 410MHz 功率(dBm) | 430MHz 功率(dBm) | 450MHz 功率(dBm) | 460MHz 功率(dBm) |
  1010. *|------|------------------|------------------|------------------|------------------|
  1011. *| 1 | -18.7 | -18.2 | -18.8 | -19.7 |
  1012. *| 2 | -8.3 | -7.9 | -8.6 | -9.5 |
  1013. *| 3 | 1.6 | 1.7 | 0.9 | -0.1 |
  1014. *| 4 | 3.9 | 4.5 | 4.1 | 3.3 |
  1015. *| 5 | 4.9 | 5.3 | 4.8 | 3.9 |
  1016. *| 6 | 5.4 | 5.5 | 4.8 | 3.8 |
  1017. *| 7 | 7.1 | 7.6 | 7.3 | 6.8 |
  1018. *| 8 | 7.7 | 8.2 | 8.0 | 7.5 |
  1019. *| 9 | 8.6 | 9.2 | 8.8 | 8.1 |
  1020. *| 10 | 9.0 | 9.3 | 9.1 | 8.9 |
  1021. *| 11 | 10.3 | 10.7 | 10.6 | 10.3 |
  1022. *| 12 | 10.8 | 11.0 | 10.8 | 10.6 |
  1023. *| 13 | 11.6 | 11.8 | 11.6 | 11.5 |
  1024. *| 14 | 12.8 | 13.2 | 13.1 | 12.9 |
  1025. *| 15 | 13.8 | 14.3 | 14.2 | 14.0 |
  1026. *| 16 | 14.9 | 15.4 | 15.4 | 15.0 |
  1027. *| 17 | 15.4 | 16.0 | 15.8 | 15.3 |
  1028. *| 18 | 16.1 | 16.6 | 16.5 | 16.3 |
  1029. *| 19 | 16.5 | 17.0 | 16.9 | 16.7 |
  1030. *| 20 | 17.4 | 17.9 | 17.8 | 17.6 |
  1031. *| 21 | 18.2 | 18.3 | 18.0 | 17.7 |
  1032. *| 22 | 19.4 | 19.4 | 19.1 | 18.7 |
  1033. *|------|------------------|------------------|------------------|------------------|
  1034. */
  1035. void RF_SetTxPower(uint8_t TxPower)
  1036. {
  1037. int Index;
  1038. uint8_t Temp1, Temp2;
  1039. static bool PaBiasReadFlag = false; // for read efuse only once
  1040. static uint8_t PaBiasVal = 0;
  1041. TxPower = (TxPower > RF_MAX_RAMP ? RF_MAX_RAMP : TxPower);
  1042. TxPower = (TxPower < RF_MIN_RAMP ? RF_MIN_RAMP : TxPower);
  1043. Index = TxPower - 1;
  1044. /* Modulate wave ramp mode */
  1045. RF_WritePageReg(3, 0x22, g_RfPowerRampCfg[Index].Ldo & 0x01);
  1046. RF_WritePageReg(0, 0x1E, g_RfPowerRampCfg[Index].Ramp);
  1047. RF_WritePageReg(0, 0x4B, g_RfPowerRampCfg[Index].Ldo >> 4);
  1048. if (g_RfPowerRampCfg[Index].PAbias != 0x70)
  1049. {
  1050. RF_SetPageRegBits(0, 0x46, 0x04); // page0, reg0x46, bit2=1
  1051. }
  1052. else
  1053. {
  1054. RF_ResetPageRegBits(0, 0x46, 0x04); // page0, reg0x46, bit2=0
  1055. }
  1056. if(!PaBiasReadFlag)
  1057. {
  1058. PaBiasReadFlag = true;
  1059. RF_ResetPageRegBits(2, 0x3E, 0x08); /* RF unlock info */
  1060. PaBiasVal = RF_ReadInfoByte(0x3B, 0x5AA5, 0x20);
  1061. RF_SetPageRegBits(2, 0x3E, 0x08); /* RF lock info */
  1062. if (PaBiasVal == 0)
  1063. {
  1064. PaBiasVal = 8;
  1065. }
  1066. }
  1067. Temp1 = PaBiasVal - (g_RfPowerRampCfg[Index].PAbias & 0x0F);
  1068. Temp2 = (g_RfPowerRampCfg[Index].PAbias & 0xF0) | Temp1;
  1069. RF_WritePageReg(0, 0x45, Temp2);
  1070. g_RfCfgParams.TxPower = TxPower; /* save current TxPower value */
  1071. }
  1072. /**
  1073. * @brief 设置调制带宽
  1074. * @param <BandWidth> 调制带宽值
  1075. * - RF_BW_062K / RF_BW_125K / RF_BW_250K / RF_BW_500K
  1076. * @note 调制带宽越大,数据速率越高,但传输距离越短
  1077. * @note PAN3029芯片的调制带宽范围为RF_BW_062K - RF_BW_500K
  1078. * @note PAN3060芯片的调制带宽范围为RF_BW_125K - RF_BW_500K
  1079. */
  1080. void RF_SetBW(uint8_t BandWidth)
  1081. {
  1082. /* Page 3, Reg 0x0D, Bit[7:4] = BandWidth */
  1083. RF_WritePageRegBits(3, 0x0D, BandWidth, 0xF0);
  1084. if (BandWidth != RF_BW_500K)
  1085. {
  1086. RF_SetPageRegBits(2, 0x3F, 0x02);
  1087. }
  1088. else
  1089. {
  1090. RF_ResetPageRegBits(2, 0x3F, 0x02);
  1091. }
  1092. g_RfCfgParams.Bandwidth = (RfBandwidths_t)BandWidth; // save current BW value
  1093. }
  1094. /**
  1095. * @brief 设置扩频因子
  1096. * @param <SpreadFactor> 扩频因子值
  1097. * - RF_SF5 / RF_SF6 / RF_SF7 / RF_SF8 / RF_SF9 / RF_SF10 / RF_SF11 / RF_SF12
  1098. * @note 扩频因子越大,传输距离越远,但数据速率越低
  1099. * @note PAN3029芯片的扩频因子范围为RF_SF5 - RF_SF12
  1100. * @note PAN3060芯片的扩频因子范围为RF_SF5 - RF_SF9
  1101. */
  1102. void RF_SetSF(uint8_t SpreadFactor)
  1103. {
  1104. /* Page 3, Reg 0x0E, Bit[7:4] = SpreadFactor */
  1105. RF_WritePageRegBits(3, 0x0E, SpreadFactor, 0xF0);
  1106. g_RfCfgParams.SpreadingFactor = (RfSpreadFactor_t)SpreadFactor; // save current SF value
  1107. }
  1108. /**
  1109. * @brief 设置信道编码率
  1110. * @param <CodingRate> 信道编码率值
  1111. * - RF_CR_4_5 / RF_CR_4_6 / RF_CR_4_7 / RF_CR_4_8
  1112. */
  1113. void RF_SetCR(uint8_t CodingRate)
  1114. {
  1115. /* Page 3, Reg 0x0D, Bit[3:1] = CodingRate */
  1116. RF_WritePageRegBits(3, 0x0D, CodingRate, 0x0E);
  1117. g_RfCfgParams.CodingRate = (RfCodingRates_t)CodingRate; // save current CR value
  1118. }
  1119. /**
  1120. * @brief 设置CRC校验
  1121. * @param <CrcMode> 使能或禁用CRC校验
  1122. * - RF_CRC_ON: 使能CRC校验
  1123. * - RF_CRC_OFF: 禁用CRC校验
  1124. */
  1125. void RF_SetCRC(uint8_t CrcMode)
  1126. {
  1127. /* Page 3, Reg 0x0D, Bit[0] = CRC */
  1128. RF_WritePageRegBits(3, 0x0E, CrcMode, 0x08);
  1129. g_RfCfgParams.CrcMode = (RfCrcModes_t)CrcMode; // save current CRC value
  1130. }
  1131. /**
  1132. * @brief 设置低速率模式
  1133. * @param <LdrMode> 低速率模式值
  1134. * - RF_LDR_ON: 使能低速率模式
  1135. * - RF_LDR_OFF:禁用低速率模式
  1136. */
  1137. void RF_SetLDR(uint8_t LdrMode)
  1138. {
  1139. /* Page 3, Reg 0x12, Bit[3] = LDR */
  1140. RF_WritePageRegBits(3, 0x12, LdrMode, 0x08);
  1141. g_RfCfgParams.LowDatarateOptimize = LdrMode; // save current LDR value
  1142. }
  1143. /**
  1144. * @brief Set modem mode
  1145. * @param <modem_mode>
  1146. * - MODEM_MODE_NORMAL
  1147. * - MODEM_MODE_MULTI_SECTOR
  1148. * @note This function should be called after RF_SetSF(uint8_t SpreadFactor)
  1149. */
  1150. void RF_SetModemMode(uint8_t ModemMode)
  1151. {
  1152. if (ModemMode == MODEM_MODE_NORMAL)
  1153. {
  1154. RF_WritePageReg(1, 0x0B, 0x08);
  1155. }
  1156. else if (ModemMode == MODEM_MODE_MULTI_SECTOR)
  1157. {
  1158. RF_WritePageReg(1, 0x0B, 0x18);
  1159. if( g_RfCfgParams.SpreadingFactor <= RF_SF6 )
  1160. {
  1161. RF_WritePageReg(1, 0x2F, 0x74);
  1162. RF_WritePageReg(1, 0x30, 0x01);
  1163. }
  1164. else
  1165. {
  1166. RF_WritePageReg(1, 0x2F, 0x54);
  1167. RF_WritePageReg(1, 0x30, 0x40);
  1168. }
  1169. }
  1170. }
  1171. /**
  1172. * @brief 设置发送模式
  1173. * @param Buffer 要发送的数据缓冲区
  1174. * @param Size 要发送的数据字节数
  1175. * @note 保证在调用此函数前,RF已经处于待机(STB3)模式
  1176. * @note 此函数为单次发送模式,发送完成后会自动进入待机(STB3)模式
  1177. * @note 发送完成后会触发TX_DONE中断
  1178. */
  1179. void RF_SetTx(uint8_t *Buffer, uint8_t Size)
  1180. {
  1181. RF_TxSinglePkt(Buffer, Size);
  1182. g_RfOperatetate = RF_STATE_TX;
  1183. }
  1184. /**
  1185. * @brief 设置接收模式
  1186. * @param TimeoutMs 接收超时时间,单位为毫秒
  1187. * - 0: 连续接收模式
  1188. * - >0: 单次接收模式,超时后报超时中断并自动进入待机(STB3)模式
  1189. * @note 保证在调用此函数前,RF已经处于待机(STB3)模式
  1190. */
  1191. void RF_SetRx(uint32_t TimeoutMs)
  1192. {
  1193. if (TimeoutMs == 0)
  1194. {
  1195. RF_EnterContinousRxState();
  1196. }
  1197. else
  1198. {
  1199. RF_EnterSingleRxWithTimeout(TimeoutMs);
  1200. }
  1201. g_RfOperatetate = RF_STATE_RX;
  1202. }
  1203. /**
  1204. * @brief 启动CAD检测
  1205. * @param <Threshold>
  1206. - RF_CAD_THRESHOLD_0A
  1207. - RF_CAD_THRESHOLD_10
  1208. - RF_CAD_THRESHOLD_15
  1209. - RF_CAD_THRESHOLD_20
  1210. <Chirps>
  1211. - RF_CAD_01_SYMBOL
  1212. - RF_CAD_02_SYMBOL
  1213. - RF_CAD_03_SYMBOL
  1214. - RF_CAD_04_SYMBOL
  1215. */
  1216. void RF_StartCad(uint8_t Threshold, uint8_t Chirps)
  1217. {
  1218. /* Configure GPIO11 as output for CAD indication */
  1219. RF_ConfigGpio(MODULE_GPIO_CAD_IRQ, RF_GPIO_MODE_OUTPUT);
  1220. /* [Page0][Reg0x5E][Bit6] = 0, enable GPIO11 CAD indication */
  1221. RF_ResetPageRegBits(0, 0x5E, 0x40);
  1222. RF_WritePageReg(1, 0x0F, Threshold); /* [Page1][Reg0x0F] = Threshold */
  1223. RF_WritePageRegBits(1, 0x25, Chirps - 1, 0x03); /* [Page1][Reg0x25][Bit[1:0]] = Chirps - 1 */
  1224. RF_WritePageReg(1, 0x35, 0xFE); /* [Page1][Reg0x35] payload cad config */
  1225. RF_EnterContinousRxState(); /* Enter continous RX state */
  1226. }
  1227. /**
  1228. * @brief 设置CAD检测阈值
  1229. * @param <Threshold> CAD检测阈值
  1230. * - RF_CAD_THRESHOLD_0A
  1231. * - RF_CAD_THRESHOLD_10
  1232. * - RF_CAD_THRESHOLD_15
  1233. * - RF_CAD_THRESHOLD_20
  1234. */
  1235. void RF_SetCadThreshold(uint8_t Threshold)
  1236. {
  1237. RF_WritePageReg(1, 0x0F, Threshold);
  1238. }
  1239. /**
  1240. * @brief 设置CAD检测符号数
  1241. * @param <Chirps> CAD检测符号数
  1242. * - RF_CAD_01_SYMBOL
  1243. * - RF_CAD_02_SYMBOL
  1244. * - RF_CAD_03_SYMBOL
  1245. * - RF_CAD_04_SYMBOL
  1246. */
  1247. void RF_SetCadChirps(uint8_t Chirps)
  1248. {
  1249. RF_WritePageRegBits(1, 0x25, Chirps - 1, 0x03); /* [Page1][Reg0x25][Bit[1:0]] = Chirps */
  1250. }
  1251. /**
  1252. * @brief 停止CAD检测
  1253. */
  1254. void RF_StopCad(void)
  1255. {
  1256. RF_SetPageRegBits(0, 0x5E, 0x40); /* [Page0][Reg0x5E][Bit6] = 1, disable GPIO11 CAD indication */
  1257. RF_WritePageReg(1, 0x0F, 0x0A); /* Reset CAD threshold */
  1258. RF_WritePageReg(1, 0x35, 0xF4); /* Reset payload cad config */
  1259. RF_SetRfState(RF_STATE_STB3); /* Enter standby state */
  1260. RF_ResetLogic(); /* Soft reset the RF chip, clear cad state */
  1261. g_RfOperatetate = RF_STATE_STB3;
  1262. }
  1263. /**
  1264. * @brief 设置发射模式
  1265. * @param <TxMode>
  1266. * - RF_TX_SINGLE:单次发送模式
  1267. * - RF_TX_CONTINOUS:连续发送模式
  1268. * @note 该函数仅用于设置发射模式,并不改变芯片的工作状态
  1269. */
  1270. void RF_SetTxMode(uint8_t TxMode)
  1271. {
  1272. RF_WritePageRegBits(3, 0x06, TxMode, 0x04); /* [Page3][Reg0x06][Bit[2]] = TxMode */
  1273. }
  1274. /**
  1275. * @brief 发送单个数据包
  1276. * @param <Buffer> 要发送的数据缓冲区
  1277. * @param <Size> 要发送的数据字节数
  1278. * @note 发送完成后会触发TX_DONE中断
  1279. * @note 在发送完成中断中,需调用RF_TurnoffPA()函数来关闭芯片内部和外部PA
  1280. */
  1281. void RF_TxSinglePkt(uint8_t *Buffer, uint8_t Size)
  1282. {
  1283. RF_WriteReg(0x02, RF_STATE_STB3); /* 进入待机状态 */
  1284. RF_SetTxMode(RF_TX_MODE_SINGLE); /* 设置单次发送模式 */
  1285. RF_WritePageReg(1, 0x0C, Size); /* 设置发送数据长度 */
  1286. RF_TurnonPA(); /* 发射数据前须打开PA */
  1287. RF_SetRfState(RF_STATE_TX); /* 设置芯片为发射状态 */
  1288. RF_WriteRegs(0x01, Buffer, Size); /* 写入数据到FIFO, 写完数据后,芯片开始发射数据, 其中0x01为FIFO寄存器地址 */
  1289. }
  1290. /**
  1291. * @brief 设置接收模式
  1292. * @param <RxMode>
  1293. * - RF_RX_SINGLE: 单次接收模式,接收到一包数据后自动进入待机模式
  1294. * - RF_RX_SINGLE_TIMEOUT:单次带超时接收模式,超时后自动进入待机模式
  1295. * - RF_RX_CONTINOUS:连续接收模式,接收到一包数据后继续接收
  1296. * @note 该函数仅用于设置接收模式,并不改变芯片的工作状态
  1297. */
  1298. void RF_SetRxMode(uint8_t RxMode)
  1299. {
  1300. RF_WritePageRegBits(3, 0x06, RxMode, 0x03); /* [Page3][Reg0x06][Bit[1:0]] = RxMode */
  1301. }
  1302. /**
  1303. * @brief 让芯片进入连续接收状态
  1304. * @note 调用此函数后,芯片会进入连续接收状态
  1305. * @note 该函数会将芯片的工作状态设置为MODE_RX
  1306. */
  1307. void RF_EnterContinousRxState(void)
  1308. {
  1309. RF_SetRfState(RF_STATE_STB3); /* 进入待机状态 */
  1310. RF_TurnonRxAnt(); /* 打开接收天线开关 */
  1311. RF_TurnoffLdoPA(); /* 关闭内部PA */
  1312. RF_SetRxMode(RF_RX_MODE_CONTINOUS); /* 设置接收模式为连续接收 */
  1313. RF_SetRfState(RF_STATE_RX); /* 进入接收状态 */
  1314. }
  1315. /**
  1316. * @brief 设置接收超时时间
  1317. * @param <TimeoutMs> 超时时间,单位为ms
  1318. * 超时时间范围:0~65535ms
  1319. * @note 该函数仅用于设置接收超时时间,并不改变芯片的工作状态
  1320. */
  1321. void RF_SetRxTimeout(uint16_t TimeoutMs)
  1322. {
  1323. uint8_t Temp[2] = {(uint8_t)TimeoutMs, (uint8_t)(TimeoutMs >> 8)};
  1324. RF_WritePageRegs(3, 0x07, Temp, 2);
  1325. }
  1326. /**
  1327. * @brief 让芯片进入带超时的单次接收状态
  1328. * @param <TimeoutMs> 超时时间,单位为ms
  1329. * 超时时间范围:1~65535ms
  1330. * @note 调用此函数后,芯片会进入带超时的单次接收状态
  1331. * @note 该函数会将芯片的工作状态设置为MODE_RX
  1332. */
  1333. void RF_EnterSingleRxWithTimeout(uint16_t TimeoutMs)
  1334. {
  1335. RF_SetRfState(RF_STATE_STB3); /* 进入待机状态 */
  1336. RF_TurnonRxAnt(); /* 打开接收天线开关 */
  1337. RF_TurnoffLdoPA(); /* 关闭内部PA */
  1338. RF_SetRxTimeout(TimeoutMs); /* 设置接收超时时间 */
  1339. RF_SetRxMode(RF_RX_MODE_SINGLE_TIMEOUT); /* 设置接收模式为单次接收模式 */
  1340. RF_SetRfState(RF_STATE_RX); /* 进入接收状态 */
  1341. }
  1342. /**
  1343. * @brief 获取接收数据长度
  1344. * @return 接收数据长度
  1345. * @note 此函数须在接收中断被清除前调用,因为清除接收中断会将接收长度寄存器清零
  1346. */
  1347. uint8_t RF_GetRxPayloadLen(void)
  1348. {
  1349. return RF_ReadPageReg(1, 0x7D);
  1350. }
  1351. /**
  1352. * @brief 函数用于获取接收数据长度及内容
  1353. * @param *Buffer 待接收数据区指针地址
  1354. * @return 接收到的数据长度
  1355. * @note 此函数须在接收中断被清除前调用,因为清除接收中断会将接收长度寄存器清零
  1356. */
  1357. uint8_t RF_GetRecvPayload(uint8_t *Buffer)
  1358. {
  1359. uint8_t Size;
  1360. Size = RF_GetRxPayloadLen(); /* 获取接收数据长度 */
  1361. RF_ReadRegs(0x01, Buffer, Size); /* 从FIFO中读取接收到的数据, 其中0x01为FIFO寄存器地址 */
  1362. return Size;
  1363. }
  1364. /**
  1365. * @brief 获取接收数据包的RSSI值
  1366. * @return RSSI值
  1367. * @note RSSI值范围:-125~-10,单位dBm,RSSI值小于等于灵敏度值
  1368. * @note 此函数须在接收中断被清除前调用,因为清除接收中断会将信号强度寄存器清零
  1369. */
  1370. int8_t RF_GetPktRssi(void)
  1371. {
  1372. return RF_ReadPageReg(1, 0x7F);
  1373. }
  1374. /**
  1375. * @brief 获取实时RSSI值
  1376. * @return RSSI值
  1377. * @note RSSI值范围:-125~-10,单位dBm
  1378. * @note 调用此函数前需须保证RF处于接收状态
  1379. */
  1380. int8_t RF_GetRealTimeRssi(void)
  1381. {
  1382. /* 将寄存器0x06的Bit[2]清零再置为1,即可更新[Page1][Reg0x7E]的值 */
  1383. RF_ResetPageRegBits(2, 0x06, 0x04);
  1384. RF_SetPageRegBits(2, 0x06, 0x04);
  1385. return (int8_t)RF_ReadPageReg(1, 0x7E);
  1386. }
  1387. /**
  1388. * @brief 获取接收数据包的SNR值
  1389. * @return SNR值
  1390. * @note 此函数须在接收中断被清除前调用,因为清除接收中断会将SNR寄存器清零
  1391. * @note SNR值范围:-20~10,单位dB
  1392. */
  1393. int32_t RF_GetPktSnr(void)
  1394. {
  1395. int32_t PktSnr = 0, SnrVal;
  1396. uint8_t i, Temp[6];
  1397. uint32_t NoiseStrength;
  1398. uint32_t SingalStrength;
  1399. RF_ReadPageRegs(2, 0x71, &Temp[0], 3); // Noise strength
  1400. RF_ReadPageRegs(1, 0x74, &Temp[3], 3); // Singal strength
  1401. SingalStrength = (((uint32_t)Temp[5] << 16) | ((uint32_t)Temp[4] << 8) | Temp[3]);
  1402. NoiseStrength = (((uint32_t)Temp[2] << 16) | ((uint32_t)Temp[1] << 8) | Temp[0]);
  1403. if (NoiseStrength == 0)
  1404. {
  1405. NoiseStrength = 1;
  1406. }
  1407. if(g_RfCfgParams.SpreadingFactor <= 9)
  1408. {
  1409. SnrVal = (SingalStrength << (9 - g_RfCfgParams.SpreadingFactor)) / NoiseStrength;
  1410. }
  1411. else
  1412. {
  1413. SnrVal = (SingalStrength >> (g_RfCfgParams.SpreadingFactor - 9)) / NoiseStrength;
  1414. }
  1415. for (i = 0; i < 31; i++)
  1416. {
  1417. if (SnrVal <= g_SnrLog10Talbe[i])
  1418. {
  1419. PktSnr = (int32_t)i - (int32_t)20;
  1420. break;
  1421. }
  1422. }
  1423. return PktSnr;
  1424. }
  1425. /**
  1426. * @brief 获取中断标志位
  1427. * @return IRQ标志位
  1428. * - 0x00: 无中断
  1429. * - 0x01: RF_IRQ_TX_DONE
  1430. * - 0x02: RF_IRQ_RX_TIMEOUT
  1431. * - 0x04: RF_IRQ_CRC_ERR
  1432. * - 0x08: RF_IRQ_RX_DONE
  1433. * - 0x40: RF_IRQ_MAPM_DONE
  1434. */
  1435. uint8_t RF_GetIRQFlag(void)
  1436. {
  1437. return (RF_ReadPageReg(0, 0x6C) & 0x7F);
  1438. }
  1439. /**
  1440. * @brief 清中断标志位
  1441. * @param <IRQFlag> 中断标志位
  1442. */
  1443. void RF_ClrIRQFlag(uint8_t IRQFlag)
  1444. {
  1445. RF_WritePageReg(0, 0x6C, IRQFlag);
  1446. }
  1447. /**
  1448. * * @brief 获取当前的频率设置
  1449. */
  1450. uint32_t RF_GetFreq(void)
  1451. {
  1452. return g_RfCfgParams.Frequency;
  1453. }
  1454. /**
  1455. * * @brief 获取当前的IQ反转值
  1456. */
  1457. RfIQModes_t RF_GetInvertIQ(void)
  1458. {
  1459. return g_RfCfgParams.InvertIQ;
  1460. }
  1461. /**
  1462. * @brief 获取当前的前导码长度设置
  1463. */
  1464. uint16_t RF_GetPreamLen(void)
  1465. {
  1466. return g_RfCfgParams.PreambleLen;
  1467. }
  1468. /**
  1469. * @brief 获取当前的发射功率设置
  1470. */
  1471. uint8_t RF_GetTxPower(void)
  1472. {
  1473. return g_RfCfgParams.TxPower;
  1474. }
  1475. /**
  1476. * @brief 获取当前的调制带宽设置
  1477. */
  1478. uint8_t RF_GetBandWidth(void)
  1479. {
  1480. return g_RfCfgParams.Bandwidth;
  1481. }
  1482. /**
  1483. * @brief 获取当前的扩频因子设置
  1484. */
  1485. uint8_t RF_GetSF(void)
  1486. {
  1487. return g_RfCfgParams.SpreadingFactor;
  1488. }
  1489. /**
  1490. * @brief 获取当前的CRC校验设置
  1491. */
  1492. uint8_t RF_GetCRC(void)
  1493. {
  1494. return g_RfCfgParams.CrcMode;
  1495. }
  1496. /**
  1497. * @brief 获取当前的编码率设置
  1498. */
  1499. uint8_t RF_GetCR(void)
  1500. {
  1501. return g_RfCfgParams.CodingRate;
  1502. }
  1503. /**
  1504. * @brief 获取当前的同步字设置
  1505. */
  1506. uint8_t RF_GetSyncWord(void)
  1507. {
  1508. return g_RfCfgParams.SyncWord;
  1509. }
  1510. /**
  1511. * @brief 获取当前的发射模式设置
  1512. */
  1513. uint8_t RF_GetLDR(void)
  1514. {
  1515. return g_RfCfgParams.LowDatarateOptimize;
  1516. }
  1517. /**
  1518. * @brief 获取单个符号的时间
  1519. * @param <bw> 带宽
  1520. * - RF_BW_062K / RF_BW_125K / RF_BW_250K / RF_BW_500K
  1521. * @param <sf> 扩频因子
  1522. * - RF_SF5 / RF_SF6 / RF_SF7 / RF_SF8 / RF_SF9 / RF_SF10 / RF_SF11 / RF_SF12
  1523. * @return 单个符号的时间,单位为us
  1524. * @note 该函数用于计算单个符号的时间
  1525. */
  1526. uint32_t RF_GetOneSymbolTime(uint8_t bw, uint8_t sf)
  1527. {
  1528. const uint32_t BwTable[4] = {62500, 125000, 250000, 500000};
  1529. if(bw < RF_BW_062K || bw > RF_BW_500K)
  1530. {
  1531. return 0;
  1532. }
  1533. return (1000000 * (1 << sf) / BwTable[bw - RF_BW_062K]);
  1534. }
  1535. /**
  1536. * @brief 计算发送数据包的时间
  1537. * @param <Size> 发送数据包的大小,单位为字节
  1538. * @return 发送数据包的时间,单位为ms
  1539. */
  1540. uint32_t RF_GetTxTimeMs(uint8_t Size)
  1541. {
  1542. uint8_t sf, cr, bw, ldr;
  1543. uint16_t PreambleLen; /* Preamble length */
  1544. float SymbolTime; /* Symbol time:ms */
  1545. float PreambleTime; /* Preamble time:ms */
  1546. float PayloadTime; /* Payload time:ms */
  1547. float TotalTime; /* Total time:ms */
  1548. const float BwTable[4] = {62.5, 125, 250, 500};
  1549. sf = RF_GetSF();
  1550. cr = RF_GetCR();
  1551. bw = RF_GetBandWidth();
  1552. ldr = RF_GetLDR();
  1553. PreambleLen = RF_GetPreamLen();
  1554. SymbolTime = (float)(1 << sf) / BwTable[bw - RF_BW_062K]; /* Symbol time: ms */
  1555. if (sf < 7)
  1556. {
  1557. PreambleTime = (PreambleLen + 6.25f) * SymbolTime;
  1558. PayloadTime = ceil((float)(Size * 8 - sf * 4 + 36) / ((sf - ldr * 2) * 4));
  1559. }
  1560. else
  1561. {
  1562. PreambleTime = (PreambleLen + 4.25f) * SymbolTime;
  1563. PayloadTime = ceil((float)(Size * 8 - sf * 4 + 44) / ((sf - ldr * 2) * 4));
  1564. }
  1565. TotalTime = PreambleTime + (PayloadTime * (cr + 4) + 8) * SymbolTime;
  1566. if(TotalTime < 1)
  1567. {
  1568. TotalTime = 1; /* 小于1ms时,按1ms处理 */
  1569. }
  1570. return (uint32_t)TotalTime;
  1571. }
  1572. /**
  1573. * @brief 启动mapm模式
  1574. */
  1575. void RF_EnableMapm(void)
  1576. {
  1577. RF_SetPageRegBits(1, 0x38, 0x01); /* Enable mapm mode */
  1578. RF_WritePageRegBits(0, 0x58, 0, 0x40); /* Enable mapm interrupt */
  1579. }
  1580. /**
  1581. * @brief 关闭mapm模式
  1582. */
  1583. void RF_DisableMapm(void)
  1584. {
  1585. RF_ResetPageRegBits(1, 0x38, 0x01); /* Disable mapm mode */
  1586. RF_WritePageRegBits(0, 0x58, 1, 0x40); /* Disable mapm interrupt */
  1587. }
  1588. /**
  1589. * @brief 配置mapm相关参数
  1590. * @param <pMapmCfg>
  1591. * fn: mapm中的field个数,总共发送fn*(2^fnm)个field(通常fnm=0)
  1592. * fnm: 同一个field重复发送的次数配置(默认fnm=0)
  1593. * - fnm=0时,表示同一个field发送1次,总共发送fn*1个fields
  1594. * - fnm=1时,表示同一个field发送2次,总共发送fn*2个fields
  1595. * - fnm=2时,表示同一个field发送4次,总共发送fn*4个fields
  1596. * - fnm=3时,表示同一个field发送8次,总共发送fn*8个fields
  1597. * gfs: 每个field中最后一个group的载荷功能选择
  1598. * - gfs=0时,表示最后一个group的载荷功能为地址
  1599. * - gfs=1时,表示最后一个group的载荷功能为剩余field的个数(包含当前field)
  1600. * gn: 一个field中group的个数
  1601. * pg1: field中第一个group的前导码个数,范围为8~255
  1602. * - pg1=8时,表示第一个group中有8个前导码
  1603. * - pg1=200时,表示第一个group中有200个前导码
  1604. * pgn: field中除第一个group外的其它group的前导码个数,范围为0~255
  1605. * - pgn=8时,表示第一个group中有8个前导码
  1606. * - pgn=200时,表示第一个group中有200个前导码
  1607. * pn: 数据包的前导码个数,范围为1~65535
  1608. * @note group中的地址或计数值占用2个chirp.
  1609. */
  1610. void RF_ConfigMapm(RF_MapmCfg_t *pMapmCfg)
  1611. {
  1612. uint8_t reg_fn, fn_h, fn_l;
  1613. fn_h = pMapmCfg->fn / 15 + 1;
  1614. fn_l = pMapmCfg->fn % 15 + 1;
  1615. reg_fn = (fn_h << 4) + fn_l;
  1616. RF_WritePageReg(1, 0x3D, reg_fn); /* set the number of fields */
  1617. RF_WritePageRegBits(1, 0x37, pMapmCfg->fnm, 0x80 | 0x40); /* set the unit code word of the field counter represents several fields */
  1618. RF_WritePageRegBits(1, 0x38, pMapmCfg->gfs, 0x02); /* set the last group function selection */
  1619. RF_WritePageRegBits(1, 0x38, pMapmCfg->gn - 1, 0x08 | 0x04); /* set the number of groups in Field */
  1620. RF_WritePageReg(1, 0x3B, pMapmCfg->pg1); /* set the number of Preambles in first groups */
  1621. /* set the number of preambles for groups other than the first group */
  1622. RF_WritePageReg(1, 0x3C, pMapmCfg->pgn);
  1623. /* set the number of preamble between the last group and the sync word */
  1624. RF_WritePageRegBits(1, 0x39, (uint8_t)(pMapmCfg->pn >> 8), 0x0F);
  1625. RF_WritePageReg(1, 0x3A, (uint8_t)(pMapmCfg->pn));
  1626. }
  1627. /**
  1628. * @brief 设置mapm模式下的组地址
  1629. * @param <MapmAddr> mapm组地址
  1630. * <AddrWidth> 地址宽度,范围为1~4
  1631. * @note 接收端的MapmAddr[0]须与发送端的MapmAddr[0]一致,
  1632. * 否则接收端不会触发mapm中断。
  1633. * @note Mapm地址寄存器说明:
  1634. * [Page1][Reg0x3E]为MapmAddr[0]
  1635. * [Page1][Reg0x3F]为MapmAddr[1]
  1636. * [Page1][Reg0x40]为MapmAddr[2]
  1637. * [Page1][Reg0x41]为MapmAddr[3]
  1638. */
  1639. void RF_SetMapmAddr(uint8_t *MapmAddr, uint8_t AddrWidth)
  1640. {
  1641. RF_WritePageRegs(1, 0x3E, MapmAddr, AddrWidth);
  1642. }
  1643. /**
  1644. * @brief 计算1个field花费的时间(ms)
  1645. * @param <pMapmCfg> mapm配置参数
  1646. * <SymbolTime> 单个symbol(chirp)时间
  1647. * @note Group1中chirp的数量为(pg1 + 2),其中pg1为Group1中前导码的个数,2为Group1中地址占用的chirp数。
  1648. * @note 其它Group中chirp的数量为(pgn + 2)*(gn-1),其中pgn为其它单个Group中前导码的个数,
  1649. * 2为其它单个Group中地址(或计数值)占用的chirp数,(gn-1)为除去Group1后剩余的Group数。
  1650. */
  1651. uint32_t RF_GetMapmOneFieldTime(RF_MapmCfg_t *pMapmCfg, uint32_t SymbolTime)
  1652. {
  1653. uint8_t pgn = pMapmCfg->pgn;
  1654. uint8_t pg1 = pMapmCfg->pg1;
  1655. uint8_t gn = pMapmCfg->gn;
  1656. uint16_t ChirpNumInOneField = (pg1 + 2) + (pgn + 2) * (gn - 1);
  1657. return ChirpNumInOneField * SymbolTime / 1000;
  1658. }
  1659. /**
  1660. * @brief 获取mapm模式下的剩余Mapm时间
  1661. * @param <pMapmCfg> mapm配置参数
  1662. * <SymbolTime> 单个symbol(chirp)时间
  1663. * @return 剩余Mapm时间,单位为ms
  1664. * @note 剩余Mapm时间为从当前时刻到剩余field发送完成的时间
  1665. * @note 剩余filed计数包括当前filed在内
  1666. */
  1667. uint32_t RF_GetLeftMapmTime(RF_MapmCfg_t *pMapmCfg, uint32_t SymbolTime)
  1668. {
  1669. uint8_t fnm, gn, pgn, pg1, fn;
  1670. uint16_t ChirpNumInOneField;
  1671. uint16_t NumberOfLeftChirps;
  1672. uint32_t LeftMapmTime;
  1673. pgn = pMapmCfg->pgn;
  1674. pg1 = pMapmCfg->pg1;
  1675. gn = pMapmCfg->gn;
  1676. fnm = pMapmCfg->fnm;
  1677. fn = pMapmCfg->fn;
  1678. /**
  1679. * @brief 计算1个field中chirp的数量
  1680. * @note Group1中chirp的数量为(pg1 + 2),其中pg1为Group1中前导码的个数,2为Group1中地址占用的chirp数。
  1681. * @note 其它Group中chirp的数量为(pgn + 2)*(gn-1),其中pgn为其它单个Group中前导码的个数,
  1682. * (gn-1)为除去Group1后剩余的Group数,2为其它单个Group中地址(或计数值)占用的chirp数。
  1683. */
  1684. ChirpNumInOneField = (pg1 + 2) + (pgn + 2) * (gn - 1);
  1685. /**
  1686. * @brief 计算剩余chirp的数量
  1687. * @note fn为mapm中field的数量,如果fnm > 0时,实际发送的field的数量为fn*(2^fnm)。
  1688. * @note pn为field与sync word之间的前导码个数,空中对应有pn个chirp。
  1689. * @note 减掉1个field的chirp数是为了减去自身filed花费的时间。
  1690. */
  1691. NumberOfLeftChirps = (1 << fnm) * fn * ChirpNumInOneField - ChirpNumInOneField;
  1692. /* 剩余时间为剩余chirp数乘以单个chirp的时间 */
  1693. LeftMapmTime = SymbolTime * NumberOfLeftChirps;
  1694. return LeftMapmTime / 1000; /* 微秒转毫秒 */
  1695. }
  1696. /**
  1697. * @brief 开始发送连续载波
  1698. * @note 调用此函数前须设置好发射功率和频率
  1699. * @note 调用此函数后,芯片会一直处于发射状态,直到调用RF_StopTxContinuousWave()函数停止发射
  1700. */
  1701. void RF_StartTxContinuousWave(void)
  1702. {
  1703. RF_WriteReg(0x02, RF_STATE_STB3); /* 设置芯片为空闲状态 */
  1704. RF_WritePageReg(0, 0x58, 0x00); /* 关闭所有RF中断 */
  1705. RF_SetTxMode(RF_TX_MODE_CONTINOUS); /* 设置连续发送模式 */
  1706. RF_WritePageReg(1, 0x0C, 1); /* 设置发送数据长度为1字节 */
  1707. RF_TurnonPA(); /* 发射数据前须打开PA */
  1708. RF_WriteReg(0x02, RF_STATE_TX); /* 设置芯片为发射状态 */
  1709. RF_WriteReg(0x01, 0xFF); /* 其中0x01为FIFO寄存器地址, 写完数据后在CS上升沿开始发送载波 */
  1710. g_RfOperatetate = RF_STATE_TX;
  1711. }
  1712. /**
  1713. * @brief 停止发送连续载波
  1714. * @note 调用此函数后,芯片会停止发射,并进入待机状态
  1715. */
  1716. void RF_StopTxContinuousWave(void)
  1717. {
  1718. RF_WriteReg(0x02, RF_STATE_STB3); /* 设置芯片为空闲状态 */
  1719. RF_TurnoffPA(); /* 发送完成后须关闭PA */
  1720. RF_WritePageReg(0, 0x58, 0x0F); /* 恢复RF默认中断 */
  1721. g_RfOperatetate = RF_STATE_STB3;
  1722. }
  1723. /**
  1724. * @brief 处理RF中断事件
  1725. * @note 此函数可以放在中断服务函数中调用;
  1726. * 也可以用于轮询方式调用此函数来处理RF中断事件。
  1727. */
  1728. void RF_IRQ_Process(void)
  1729. {
  1730. if (CHECK_RF_IRQ()) /* 检测到RF中断,高电平表示有中断 */
  1731. {
  1732. uint8_t IRQFlag;
  1733. IRQFlag = RF_GetIRQFlag(); /* 获取中断标志位 */
  1734. if (IRQFlag & RF_IRQ_TX_DONE) /* 发送完成中断 */
  1735. {
  1736. RF_TurnoffPA(); /* 发送完成后须关闭PA */
  1737. RF_ClrIRQFlag(RF_IRQ_TX_DONE); /* 清除发送完成中断标志位 */
  1738. IRQFlag &= ~RF_IRQ_TX_DONE;
  1739. }
  1740. if (IRQFlag & RF_IRQ_RX_DONE) /* 接收完成中断 */
  1741. {
  1742. g_RfRxPkt.Snr = RF_GetPktSnr(); /* 获取接收数据包的SNR值 */
  1743. g_RfRxPkt.Rssi = RF_GetPktRssi(); /* 获取接收数据包的RSSI值 */
  1744. /* 获取接收数据和长度 */
  1745. g_RfRxPkt.RxLen = RF_GetRecvPayload((uint8_t *)g_RfRxPkt.RxBuf);
  1746. RF_ClrIRQFlag(RF_IRQ_RX_DONE); /* 清除接收完成中断标志位 */
  1747. IRQFlag &= ~RF_IRQ_RX_DONE;
  1748. }
  1749. if (IRQFlag & RF_IRQ_MAPM_DONE) /* mapm接收完成中断 */
  1750. {
  1751. uint8_t MapmAddr = RF_ReadPageReg(0, 0x6E);
  1752. g_RfRxPkt.MapmRxBuf[g_RfRxPkt.MapmRxIndex++] = MapmAddr;
  1753. RF_ClrIRQFlag(RF_IRQ_MAPM_DONE); /* 清除mapm接收完成中断标志位 */
  1754. IRQFlag &= ~RF_IRQ_MAPM_DONE;
  1755. }
  1756. if (IRQFlag & RF_IRQ_CRC_ERR) /* CRC错误中断 */
  1757. {
  1758. RF_ClrIRQFlag(RF_IRQ_CRC_ERR); /* 清除CRC错误中断标志位 */
  1759. IRQFlag &= ~RF_IRQ_CRC_ERR;
  1760. }
  1761. if (IRQFlag & RF_IRQ_RX_TIMEOUT) /* 接收超时中断 */
  1762. {
  1763. /* rf_refresh(); */
  1764. IRQFlag &= ~RF_IRQ_RX_TIMEOUT;
  1765. RF_ClrIRQFlag(RF_IRQ_RX_TIMEOUT); /* 清除接收超时中断标志位 */
  1766. }
  1767. if (IRQFlag)
  1768. {
  1769. RF_ClrIRQFlag(IRQFlag); /* 清除未处理的中断标志位 */
  1770. }
  1771. }
  1772. }