pan3028.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008
  1. /*******************************************************************************
  2. * @note Copyright (C) 2020 Shanghai Panchip Microelectronics Co., Ltd. All rights reserved.
  3. *
  4. * @file pan3028.c
  5. * @brief
  6. *
  7. * @history - V3.0, 2021-11-05
  8. *******************************************************************************/
  9. #include "stdio.h"
  10. #include "math.h"
  11. #include "pan3028_port.h"
  12. #include "pan3028.h"
  13. #include "radio.h"
  14. uint8_t RadioRxPayload[255];
  15. uint8_t plhd_buf[16];
  16. uint8_t reg_agc_value[98] = {0x90,0xff,0x64,0x27,0x00,0x00,0x27,0x27,0x00,0x00,0x27,0x27,0x00,0x00,0x27,0x27,\
  17. 0x00,0x00,0x27,0x27,0x00,0x00,0x27,0x27,0x00,0x00,0x27,0x27,0x00,0x00,0x27,0x27,\
  18. 0x00,0x00,0x27,0x27,0x00,0x00,0x27,0x2B,0x00,0xF8,0x2B,0x31,0x00,0xFC,0x31,0x37,\
  19. 0x00,0xFF,0x37,0x3C,0x20,0xFF,0x3C,0x42,0x40,0xFF,0x42,0x48,0x60,0xFF,0x48,0x4D,\
  20. 0x80,0xFF,0x4D,0x53,0x84,0xFF,0x53,0x59,0x88,0xFF,0x59,0x5F,0x8C,0xFF,0x5F,0x64,\
  21. 0x90,0xFF,0x64,0x06,0xFF,0x40,0x42,0x0F,0x00,0x00,0x01,0xF4,0x2F,0xF3,0x0F,0x00,0x00,0x00};
  22. /**
  23. * @brief read one byte from register in current page
  24. * @param[in] <addr> register address to write
  25. * @return value read from register
  26. */
  27. static uint8_t PAN3028_read_reg(uint8_t addr)
  28. {
  29. uint8_t temreg = 0x00;
  30. rf_port.spi_cs_low();
  31. rf_port.spi_readwrite(0x00 | (addr<<1));
  32. temreg=rf_port.spi_readwrite(0x00);
  33. rf_port.spi_cs_high();
  34. return temreg;
  35. }
  36. /**
  37. * @brief write global register in current page and chick
  38. * @param[in] <addr> register address to write
  39. * @param[in] <value> address value to write to rgister
  40. * @return result
  41. */
  42. static uint32_t PAN3028_write_reg(uint8_t addr,uint8_t value)
  43. {
  44. uint16_t tmpreg = 0;
  45. uint16_t addr_w = (0x01 | (addr << 1));
  46. rf_port.spi_cs_low();
  47. rf_port.spi_readwrite(addr_w);
  48. rf_port.spi_readwrite(value);
  49. rf_port.spi_cs_high();
  50. tmpreg = PAN3028_read_reg(addr);
  51. if(tmpreg == value)
  52. {
  53. return OK;
  54. }
  55. else
  56. {
  57. return FAIL;
  58. }
  59. }
  60. /**
  61. * @brief rf send data fifo,send bytes register
  62. * @param[in] <addr> register address to write
  63. * @param[in] <buffer> send data buffer
  64. * @param[in] <size> send data size
  65. * @return none
  66. */
  67. static void PAN3028_write_fifo(uint8_t addr,uint8_t *buffer,int size)
  68. {
  69. int i;
  70. uint8_t addr_w = (0x01 | (addr << 1));
  71. rf_port.spi_cs_low();
  72. rf_port.spi_readwrite(addr_w);
  73. for(i =0;i<size;i++)
  74. {
  75. rf_port.spi_readwrite(buffer[i]);
  76. }
  77. rf_port.spi_cs_high();
  78. }
  79. /**
  80. * @brief rf receive data fifo,read bytes from register
  81. * @param[in] <addr> register address to write
  82. * @param[in] <buffer> receive data buffer
  83. * @param[in] <size> receive data size
  84. * @return none
  85. */
  86. static void PAN3028_read_fifo(uint8_t addr,uint8_t *buffer,int size)
  87. {
  88. int i;
  89. uint8_t addr_w = (0x00 | (addr<<1));
  90. rf_port.spi_cs_low();
  91. rf_port.spi_readwrite(addr_w);
  92. for(i =0;i<size;i++)
  93. {
  94. buffer[i] = rf_port.spi_readwrite(0x00);
  95. }
  96. rf_port.spi_cs_high();
  97. }
  98. /**
  99. * @brief switch page
  100. * @param[in] <page> page to switch
  101. * @return result
  102. */
  103. static uint32_t PAN3028_switch_page(enum PAGE_SEL page)
  104. {
  105. uint8_t page_sel = 0x00;
  106. uint8_t tmpreg = 0x00;
  107. tmpreg = PAN3028_read_reg(REG_SYS_CTL);
  108. page_sel = (tmpreg & 0xfc )| page;
  109. PAN3028_write_reg(REG_SYS_CTL,page_sel);
  110. if((PAN3028_read_reg(REG_SYS_CTL) &0x03) == page)
  111. {
  112. return OK;
  113. }else
  114. {
  115. return FAIL;
  116. }
  117. }
  118. /**
  119. * @brief This function write a value to register in specific page
  120. * @param[in] <page> the page of register
  121. * @param[in] <addr> register address
  122. * @param[in] <value> value to write
  123. * @return result
  124. */
  125. uint32_t PAN3028_write_spec_page_reg(enum PAGE_SEL page,uint8_t addr,uint8_t value)
  126. {
  127. if(PAN3028_switch_page(page) != OK)
  128. {
  129. return FAIL;
  130. }
  131. if(PAN3028_write_reg(addr,value) != OK)
  132. {
  133. return FAIL;
  134. }
  135. else
  136. {
  137. return OK;
  138. }
  139. }
  140. /**
  141. * @brief read a value to register in specific page
  142. * @param[in] <page> the page of register
  143. * @param[in] <addr> register address
  144. * @return success(register value) or failure
  145. */
  146. uint8_t PAN3028_read_spec_page_reg(enum PAGE_SEL page,uint8_t addr)
  147. {
  148. if(PAN3028_switch_page(page) != OK)
  149. {
  150. return FAIL;
  151. }
  152. return PAN3028_read_reg(addr);
  153. }
  154. /**
  155. * @brief write continue register valuies(buffer) in specific addr page
  156. * @param[in] <page> the page of register
  157. * @param[in] <addr> register start address
  158. * @param[in] <buffer> values to write
  159. * @param[in] <len> buffer len
  160. * @return result
  161. */
  162. uint32_t PAN3028_write_read_continue_regs(enum PAGE_SEL page,uint8_t addr,uint8_t *buffer,uint8_t len)
  163. {
  164. uint8_t i,temreg[256];
  165. uint16_t addr_w;
  166. if(PAN3028_switch_page(page) != OK)
  167. {
  168. return FAIL;
  169. }
  170. addr_w = (0x01 | (addr << 1));
  171. rf_port.spi_cs_low();
  172. rf_port.spi_readwrite(addr_w);
  173. for(i=0;i<len;i++)
  174. {
  175. rf_port.spi_readwrite(buffer[i]);
  176. }
  177. rf_port.spi_cs_high();
  178. rf_port.spi_cs_low();
  179. rf_port.spi_readwrite(0x00 | (addr<<1));
  180. for(i=0;i<len;i++)
  181. {
  182. temreg[i] =rf_port.spi_readwrite(0x00);
  183. }
  184. rf_port.spi_cs_high();
  185. for(i=0;i<len;i++)
  186. {
  187. if(temreg[i] != buffer[i])
  188. {
  189. return FAIL;
  190. }
  191. }
  192. return OK;
  193. }
  194. /**
  195. * @brief PAN3028 clear all irq
  196. * @param[in] <none>
  197. * @return none
  198. */
  199. void PAN3028_clr_irq(void)
  200. {
  201. PAN3028_write_spec_page_reg(PAGE0_SEL,0x6C,0x1f);
  202. }
  203. /**
  204. * @brief get irq status
  205. * @param[in] <none>
  206. * @return ira status
  207. */
  208. uint8_t PAN3028_get_irq(void)
  209. {
  210. uint8_t tmpreg;
  211. tmpreg = PAN3028_read_spec_page_reg(PAGE0_SEL,0x6C);
  212. return tmpreg;
  213. }
  214. /**
  215. * @brief software reset
  216. * @param[in] <none>
  217. * @return result
  218. */
  219. uint32_t PAN3028_rst(void)
  220. {
  221. uint8_t tmpreg = 0;
  222. tmpreg = PAN3028_read_reg(REG_SYS_CTL);
  223. tmpreg |= 0x80;
  224. PAN3028_write_reg(REG_SYS_CTL,tmpreg);
  225. tmpreg = PAN3028_read_reg(REG_SYS_CTL);
  226. tmpreg &= 0x7F;
  227. PAN3028_write_reg(REG_SYS_CTL,tmpreg);
  228. return OK;
  229. }
  230. /**
  231. * @brief clear packet count register
  232. * @param[in] <none>
  233. * @return none
  234. */
  235. void PAN3028_clr_pkt_cnt(void)
  236. {
  237. uint8_t tmpreg;
  238. tmpreg = PAN3028_read_reg(REG_SYS_CTL);
  239. tmpreg = (tmpreg & 0xbf) | 0x40 ;
  240. PAN3028_write_reg(REG_SYS_CTL,tmpreg);
  241. tmpreg = PAN3028_read_reg(REG_SYS_CTL);
  242. tmpreg = (tmpreg & 0xbf);
  243. PAN3028_write_reg(REG_SYS_CTL,tmpreg);
  244. }
  245. /**
  246. * @brief enable AGC function
  247. * @param[in] <state>
  248. * AGC_OFF/AGC_ON
  249. * @return result
  250. */
  251. uint32_t PAN3028_agc_enable(uint32_t state)
  252. {
  253. uint8_t reg_val = 0x02;
  254. if(state == AGC_OFF)
  255. {
  256. reg_val = 0x03;
  257. }
  258. else
  259. {
  260. reg_val = 0x02;
  261. }
  262. if(PAN3028_write_spec_page_reg(PAGE2_SEL,0x06, reg_val) != OK)
  263. {
  264. return FAIL;
  265. }
  266. return OK;
  267. }
  268. /**
  269. * @brief configure AGC function
  270. * @param[in] <none>
  271. * @return result
  272. */
  273. uint32_t PAN3028_agc_config(void)
  274. {
  275. return PAN3028_write_read_continue_regs(PAGE2_SEL,0x07,reg_agc_value,98);
  276. }
  277. /**
  278. * @brief do basic configuration to initialize
  279. * @param[in] <none>
  280. * @return result
  281. */
  282. uint32_t PAN3028_init(void)
  283. {
  284. if(PAN3028_write_spec_page_reg(PAGE0_SEL,0x06,0x01) != OK)
  285. {
  286. return FAIL;
  287. }
  288. if(PAN3028_write_spec_page_reg(PAGE0_SEL,0x40,0x50) != OK)
  289. {
  290. return FAIL;
  291. }
  292. if(PAN3028_write_spec_page_reg(PAGE0_SEL,0x3e,0x2c) != OK)
  293. {
  294. return FAIL;
  295. }
  296. if(PAN3028_write_spec_page_reg(PAGE0_SEL,0x3c,0xff) != OK)
  297. {
  298. return FAIL;
  299. }
  300. if(PAN3028_write_spec_page_reg(PAGE0_SEL,0x4c,0xbf) != OK)
  301. {
  302. return FAIL;
  303. }
  304. if(PAN3028_write_spec_page_reg(PAGE0_SEL,0x4d,0x0e) != OK)
  305. {
  306. return FAIL;
  307. }
  308. if(PAN3028_write_spec_page_reg(PAGE1_SEL,0x0e,0x44) != OK)
  309. {
  310. return FAIL;
  311. }
  312. if(PAN3028_write_spec_page_reg(PAGE1_SEL,0x0f,0x0A) != OK)
  313. {
  314. return FAIL;
  315. }
  316. if(PAN3028_write_spec_page_reg(PAGE1_SEL,0x1e,0x00) != OK)
  317. {
  318. return FAIL;
  319. }
  320. if(PAN3028_write_spec_page_reg(PAGE1_SEL,0x11,0xA1) != OK)
  321. {
  322. return FAIL;
  323. }
  324. if(PAN3028_write_spec_page_reg(PAGE1_SEL,0x15,0x38) != OK)
  325. {
  326. return FAIL;
  327. }
  328. if(PAN3028_write_spec_page_reg(PAGE1_SEL,0x2f,0x0c) != OK)
  329. {
  330. return FAIL;
  331. }
  332. if(PAN3028_write_spec_page_reg(PAGE3_SEL,0x06,0x26) != OK)
  333. {
  334. return FAIL;
  335. }
  336. if(PAN3028_write_spec_page_reg(PAGE3_SEL,0x10,0x80) != OK)
  337. {
  338. return FAIL;
  339. }
  340. if(PAN3028_write_spec_page_reg(PAGE3_SEL,0x11,0x0d) != OK)
  341. {
  342. return FAIL;
  343. }
  344. if(PAN3028_write_spec_page_reg(PAGE3_SEL,0x12,0x16) != OK)
  345. {
  346. return FAIL;
  347. }
  348. if(PAN3028_write_spec_page_reg(PAGE3_SEL,0x18,0xff) != OK)
  349. {
  350. return FAIL;
  351. }
  352. return OK;
  353. }
  354. /**
  355. * @brief change PAN3028 mode from deep sleep to standby3(STB3)
  356. * @param[in] <none>
  357. * @return result
  358. */
  359. uint32_t PAN3028_deepsleep_wakeup(void)
  360. {
  361. rf_port.delayus(10);
  362. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_DEEP_SLEEP) != OK)
  363. {
  364. return FAIL;
  365. }
  366. rf_port.delayus(10);
  367. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_SLEEP) != OK)
  368. {
  369. return FAIL;
  370. }
  371. rf_port.delayms(1);
  372. if(PAN3028_write_reg(0x03, 0x1b) != OK)
  373. {
  374. return FAIL;
  375. }
  376. if(PAN3028_write_reg(0x04, 0x76) != OK)
  377. {
  378. return FAIL;
  379. }
  380. if(PAN3028_write_spec_page_reg(PAGE3_SEL,0x26, 0x40) != OK)
  381. {
  382. return FAIL;
  383. }
  384. rf_port.tcxo_init();
  385. rf_port.delayms(1);
  386. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_STB1) != OK)
  387. {
  388. return FAIL;
  389. }
  390. rf_port.delayus(10);
  391. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_STB2) != OK)
  392. {
  393. return FAIL;
  394. }
  395. rf_port.delayms(1);
  396. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_STB3) != OK)
  397. {
  398. return FAIL;
  399. }
  400. else
  401. {
  402. rf_port.delayus(10);
  403. return OK;
  404. }
  405. }
  406. /**
  407. * @brief change PAN3028 mode from sleep to standby3(STB3)
  408. * @param[in] <none>
  409. * @return result
  410. */
  411. uint32_t PAN3028_sleep_wakeup(void)
  412. {
  413. rf_port.delayus(10);
  414. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_SLEEP) != OK)
  415. {
  416. return FAIL;
  417. }
  418. rf_port.delayms(1);
  419. if(PAN3028_write_reg(0x03, 0x1b) != OK)
  420. {
  421. return FAIL;
  422. }
  423. if(PAN3028_write_reg(0x04, 0x76) != OK)
  424. {
  425. return FAIL;
  426. }
  427. if(PAN3028_write_spec_page_reg(PAGE3_SEL,0x26, 0x40) != OK)
  428. {
  429. return FAIL;
  430. }
  431. rf_port.tcxo_init();
  432. rf_port.delayms(1);
  433. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_STB1) != OK)
  434. {
  435. return FAIL;
  436. }
  437. rf_port.delayus(10);
  438. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_STB2) != OK)
  439. {
  440. return FAIL;
  441. }
  442. rf_port.delayms(1);
  443. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_STB3) != OK)
  444. {
  445. return FAIL;
  446. }
  447. else
  448. {
  449. rf_port.delayus(10);
  450. return OK;
  451. }
  452. }
  453. /**
  454. * @brief change PAN3028 mode from standby3(STB3) to deep sleep, PAN3028 should set DCDC_OFF before enter deepsleep
  455. * @param[in] <none>
  456. * @return result
  457. */
  458. uint32_t PAN3028_deepsleep(void)
  459. {
  460. rf_port.delayus(10);
  461. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_STB3) != OK)
  462. {
  463. return FAIL;
  464. }
  465. rf_port.delayus(10);
  466. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_STB2) != OK)
  467. {
  468. return FAIL;
  469. }
  470. rf_port.delayus(10);
  471. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_STB1) != OK)
  472. {
  473. return FAIL;
  474. }
  475. rf_port.delayus(10);
  476. rf_port.tcxo_close();
  477. if(PAN3028_write_reg(0x04, 0x06) != OK)
  478. {
  479. return FAIL;
  480. }
  481. rf_port.delayus(10);
  482. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_SLEEP) != OK)
  483. {
  484. return FAIL;
  485. }
  486. rf_port.delayus(10);
  487. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_DEEP_SLEEP) != OK)
  488. {
  489. return FAIL;
  490. }
  491. else
  492. {
  493. return OK;
  494. }
  495. }
  496. /**
  497. * @brief change PAN3028 mode from standby3(STB3) to sleep, PAN3028 should set DCDC_OFF before enter sleep
  498. * @param[in] <none>
  499. * @return result
  500. */
  501. uint32_t PAN3028_sleep(void)
  502. {
  503. rf_port.delayus(10);
  504. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_STB3) != OK)
  505. {
  506. return FAIL;
  507. }
  508. rf_port.delayus(10);
  509. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_STB2) != OK)
  510. {
  511. return FAIL;
  512. }
  513. rf_port.delayus(10);
  514. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_STB1) != OK)
  515. {
  516. return FAIL;
  517. }
  518. rf_port.delayus(10);
  519. rf_port.tcxo_close();
  520. if(PAN3028_write_reg(0x04, 0x16) != OK)
  521. {
  522. return FAIL;
  523. }
  524. rf_port.delayus(10);
  525. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_SLEEP) != OK)
  526. {
  527. return FAIL;
  528. }
  529. else
  530. {
  531. rf_port.delayus(10);
  532. return OK;
  533. }
  534. }
  535. /**
  536. * @brief set LO frequency
  537. * @param[in] <lo> LO frequency
  538. * LO_400M / LO_800M
  539. * @return result
  540. */
  541. uint32_t PAN3028_set_lo_freq(uint32_t lo)
  542. {
  543. uint32_t reg_val = 0;
  544. reg_val = PAN3028_read_spec_page_reg(PAGE0_SEL,0x45);
  545. reg_val &= ~(0x03);
  546. if(lo == LO_400M)
  547. {
  548. reg_val |= 0x02;
  549. }
  550. else
  551. {
  552. reg_val |= 0x01;
  553. }
  554. if(PAN3028_write_spec_page_reg(PAGE0_SEL,0x45, reg_val) != OK)
  555. {
  556. return FAIL;
  557. }
  558. return OK;
  559. }
  560. /**
  561. * @brief set frequence
  562. * @param[in] <freq> RF frequency(in Hz) to set
  563. * @return result
  564. */
  565. uint32_t PAN3028_set_freq(uint32_t freq)
  566. {
  567. uint8_t reg_read;
  568. uint8_t reg_freq;
  569. float tmp_var = 0.0;
  570. int integer_part = 0;
  571. float fractional_part = 0.0;
  572. int fb,fc;
  573. uint8_t lowband_sel = 0;
  574. if ( (freq >= freq_336000000) && (freq <= freq_470000000))
  575. {
  576. if(PAN3028_write_spec_page_reg(PAGE0_SEL,0x4a,0x92) != OK)
  577. {
  578. return FAIL;
  579. }
  580. lowband_sel = 1;
  581. tmp_var = freq * 4 * 1.0 / 16000000;
  582. PAN3028_set_lo_freq(LO_400M);
  583. }
  584. else if ( (freq > freq_470000000) && (freq <= freq_510000000))
  585. {
  586. if(PAN3028_write_spec_page_reg(PAGE0_SEL,0x4a,0xb2) != OK)
  587. {
  588. return FAIL;
  589. }
  590. lowband_sel = 1;
  591. tmp_var = freq * 4 * 1.0 / 16000000;
  592. PAN3028_set_lo_freq(LO_400M);
  593. }
  594. else if((freq >= freq_800000000) && (freq <= freq_920000000))
  595. {
  596. if(PAN3028_write_spec_page_reg(PAGE0_SEL,0x4a,0x92) != OK)
  597. {
  598. return FAIL;
  599. }
  600. lowband_sel = 0;
  601. tmp_var = freq * 2 * 1.0 / 16000000;
  602. PAN3028_set_lo_freq(LO_800M);
  603. }
  604. else
  605. {
  606. return FAIL;
  607. }
  608. integer_part = (int)tmp_var;
  609. fb = integer_part - 20;
  610. fractional_part = tmp_var - integer_part;
  611. fc = (int)(fractional_part * 1600 / (2 * (1 + lowband_sel)));
  612. if(fc < 0xff)
  613. {
  614. fb = fb - 1;
  615. fc = fc + 400;
  616. }
  617. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x15, (fb & 0x7F)) != OK)
  618. {
  619. return FAIL;
  620. }
  621. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x16,(fc & 0xff)) != OK)
  622. {
  623. return FAIL;
  624. }
  625. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x17,((fc >> 8) & 0x0f)) != OK)
  626. {
  627. return FAIL;
  628. }
  629. reg_read = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x18);
  630. reg_read &= ~((1 << 2) | (1 << 1));
  631. reg_read |= (1 << 3) | (lowband_sel << 2) | (lowband_sel << 1);
  632. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x18, reg_read) != OK)
  633. {
  634. return FAIL;
  635. }
  636. reg_freq = freq & 0xff;
  637. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x09, reg_freq) != OK)
  638. {
  639. return FAIL;
  640. }
  641. reg_freq = (freq >> 8) & 0xff;
  642. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x0a, reg_freq) != OK)
  643. {
  644. return FAIL;
  645. }
  646. reg_freq = (freq >> 16) & 0xff;
  647. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x0b, reg_freq) != OK)
  648. {
  649. return FAIL;
  650. }
  651. reg_freq = (freq >> 24) & 0xff;
  652. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x0c, reg_freq) != OK)
  653. {
  654. return FAIL;
  655. }
  656. return OK;
  657. }
  658. /**
  659. * @brief read frequency(in Hz)
  660. * @param[in] <none>
  661. * @return frequency(in Hz)
  662. */
  663. uint32_t PAN3028_read_freq(void)
  664. {
  665. uint8_t reg1, reg2, reg3 , reg4;
  666. uint32_t freq = 0x00;
  667. reg1 = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x09);
  668. reg2 = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x0a);
  669. reg3 = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x0b);
  670. reg4 = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x0c);
  671. freq = (reg4 << 24) | (reg3 << 16) | (reg2 << 8) | reg1;
  672. return freq;
  673. }
  674. /**
  675. * @brief calculate tx time
  676. * @param[in] <none>
  677. * @return tx time(ms)
  678. */
  679. uint32_t PAN3028_calculate_tx_time(void)
  680. {
  681. int bw_val;
  682. float tx_done_time;
  683. uint8_t pl = PAN3028_read_spec_page_reg(PAGE1_SEL,REG_PAYLOAD_LEN);
  684. uint8_t sf = PAN3028_get_sf();
  685. uint8_t crc = PAN3028_get_crc();
  686. uint8_t code_rate = PAN3028_get_code_rate();
  687. uint8_t bw = PAN3028_get_bw();
  688. float a,b,c,d=0.00;
  689. if(bw == 6)
  690. {
  691. bw_val = 62500;
  692. }
  693. if(bw == 7)
  694. {
  695. bw_val = 125000;
  696. }
  697. if(bw == 8)
  698. {
  699. bw_val = 250000;
  700. }
  701. if(bw == 9)
  702. {
  703. bw_val = 500000;
  704. }
  705. a = (float)(8 * pl - 4 * sf + 28 + 16 *crc) / (float)(4 * sf);
  706. b = ceil(a);
  707. c = code_rate + 4;
  708. d = ((float)((2<<(sf-1))) / bw_val);
  709. tx_done_time =(12.25 +8 + b*c)*d*1000 ;
  710. return tx_done_time + 5;
  711. }
  712. /**
  713. * @brief set bandwidth
  714. * @param[in] <bw_val> value relate to bandwidth
  715. * BW_62_5K / BW_125K / BW_250K / BW_500K
  716. * @return result
  717. */
  718. uint32_t PAN3028_set_bw(uint32_t bw_val)
  719. {
  720. uint8_t temp_val_1;
  721. uint8_t temp_val_2;
  722. temp_val_1 = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x0d);
  723. temp_val_2 = ((temp_val_1 & 0x0F) | (bw_val << 4)) ;
  724. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x0d, temp_val_2) != OK)
  725. {
  726. return FAIL;
  727. }
  728. else
  729. {
  730. return OK;
  731. }
  732. }
  733. /**
  734. * @brief read bandwidth
  735. * @param[in] <none>
  736. * @return bandwidth
  737. */
  738. uint8_t PAN3028_get_bw(void)
  739. {
  740. uint8_t tmpreg;
  741. tmpreg = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x0d);
  742. return (tmpreg & 0xff) >> 4;
  743. }
  744. /**
  745. * @brief set spread factor
  746. * @param[in] <sf> spread factor to set
  747. * SF_7 / SF_8 / SF_9 / SF_10 / SF_11 / SF_12
  748. * @return result
  749. */
  750. uint32_t PAN3028_set_sf(uint32_t sf_val)
  751. {
  752. uint8_t temp_val_1;
  753. uint8_t temp_val_2;
  754. if(sf_val < 7 || sf_val > 12)
  755. {
  756. return FAIL;
  757. }
  758. else
  759. {
  760. temp_val_1 = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x0e);
  761. temp_val_2 = ((temp_val_1 & 0x0F) | (sf_val << 4)) ;
  762. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x0e, temp_val_2) != OK)
  763. {
  764. return FAIL;
  765. }
  766. else
  767. {
  768. return OK;
  769. }
  770. }
  771. }
  772. /**
  773. * @brief read Spreading Factor
  774. * @param[in] <none>
  775. * @return Spreading Factor
  776. */
  777. uint8_t PAN3028_get_sf(void)
  778. {
  779. uint8_t tmpreg;
  780. tmpreg = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x0e);
  781. return (tmpreg & 0xff) >> 4;
  782. }
  783. /**
  784. * @brief set payload CRC
  785. * @param[in] <crc_val> CRC to set
  786. * CRC_ON / CRC_OFF
  787. * @return result
  788. */
  789. uint32_t PAN3028_set_crc(uint32_t crc_val)
  790. {
  791. uint8_t temp_val_1;
  792. uint8_t temp_val_2;
  793. temp_val_1 = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x0e);
  794. temp_val_2 = ((temp_val_1 & 0xF7) | (crc_val << 3)) ;
  795. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x0e, temp_val_2) != OK)
  796. {
  797. return FAIL;
  798. }
  799. else
  800. {
  801. return OK;
  802. }
  803. }
  804. /**
  805. * @brief read payload CRC
  806. * @param[in] <none>
  807. * @return CRC status
  808. */
  809. uint8_t PAN3028_get_crc(void)
  810. {
  811. uint8_t tmpreg;
  812. tmpreg = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x0e);
  813. return (tmpreg & 0x08) >> 3;
  814. }
  815. /**
  816. * @brief set code rate
  817. * @param[in] <code_rate> code rate to set
  818. * CODE_RATE_45 / CODE_RATE_46 / CODE_RATE_47 / CODE_RATE_48
  819. * @return result
  820. */
  821. uint32_t PAN3028_set_code_rate(uint8_t code_rate)
  822. {
  823. uint8_t tmpreg = 0;
  824. tmpreg = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x0d);
  825. tmpreg &= ~(0x7 << 1);
  826. tmpreg |= (code_rate << 1);
  827. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x0d, tmpreg) != OK)
  828. {
  829. return FAIL;
  830. }
  831. else
  832. {
  833. return OK;
  834. }
  835. }
  836. /**
  837. * @brief get code rate
  838. * @param[in] <none>
  839. * @return code rate
  840. */
  841. uint8_t PAN3028_get_code_rate(void)
  842. {
  843. uint8_t code_rate = 0;
  844. uint8_t tmpreg = 0;
  845. tmpreg = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x0d);
  846. code_rate = ((tmpreg & 0x0e) >> 1);
  847. return code_rate;
  848. }
  849. /**
  850. * @brief set rf mode
  851. * @param[in] <mode>
  852. * PAN3028_MODE_DEEP_SLEEP / PAN3028_MODE_SLEEP
  853. * PAN3028_MODE_STB1 / PAN3028_MODE_STB2
  854. * PAN3028_MODE_STB3 / PAN3028_MODE_TX / PAN3028_MODE_RX
  855. * @return result
  856. */
  857. uint32_t PAN3028_set_mode(uint8_t mode)
  858. {
  859. if(PAN3028_write_reg(REG_OP_MODE,mode) != OK)
  860. {
  861. return FAIL;
  862. }
  863. else
  864. {
  865. return OK;
  866. }
  867. }
  868. /**
  869. * @brief get rf mode
  870. * @param[in] <none>
  871. * @return mode
  872. * PAN3028_MODE_DEEP_SLEEP / PAN3028_MODE_SLEEP
  873. * PAN3028_MODE_STB1 / PAN3028_MODE_STB2
  874. * PAN3028_MODE_STB3 / PAN3028_MODE_TX / PAN3028_MODE_RX
  875. */
  876. uint8_t PAN3028_get_mode(void)
  877. {
  878. return PAN3028_read_reg(REG_OP_MODE);
  879. }
  880. /**
  881. * @brief set rf Tx mode
  882. * @param[in] <mode>
  883. * PAN3028_TX_SINGLE/PAN3028_TX_CONTINOUS
  884. * @return result
  885. */
  886. uint32_t PAN3028_set_tx_mode(uint8_t mode)
  887. {
  888. uint8_t tmp;
  889. tmp = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x06);
  890. tmp = tmp & (~(1 << 2));
  891. tmp = tmp | (mode << 2);
  892. if(PAN3028_write_spec_page_reg(PAGE3_SEL,0x06,tmp) != OK)
  893. {
  894. return FAIL;
  895. }
  896. else
  897. {
  898. return OK;
  899. }
  900. }
  901. /**
  902. * @brief set rf Rx mode
  903. * @param[in] <mode>
  904. * PAN3028_RX_SINGLE/PAN3028_RX_SINGLE_TIMEOUT/PAN3028_RX_CONTINOUS
  905. * @return result
  906. */
  907. uint32_t PAN3028_set_rx_mode(uint8_t mode)
  908. {
  909. uint8_t tmp;
  910. tmp = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x06);
  911. tmp = tmp & (~(3 << 0));
  912. tmp = tmp | (mode << 0);
  913. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x06, tmp) != OK)
  914. {
  915. return FAIL;
  916. }
  917. else
  918. {
  919. return OK;
  920. }
  921. }
  922. /**
  923. * @brief set timeout for Rx. It is useful in PAN3028_RX_SINGLE_TIMEOUT mode
  924. * @param[in] <timeout> rx single timeout time(in ms)
  925. * @return result
  926. */
  927. uint32_t PAN3028_set_timeout(uint32_t timeout)
  928. {
  929. uint8_t timeout_lsb = 0;
  930. uint8_t timeout_msb = 0;
  931. if(timeout > 0xffff)
  932. {
  933. timeout = 0xffff;
  934. }
  935. timeout_lsb = timeout & 0xff;
  936. timeout_msb = (timeout >> 8) & 0xff;
  937. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x07, timeout_lsb) != OK)
  938. {
  939. return FAIL;
  940. }
  941. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x08, timeout_msb) != OK)
  942. {
  943. return FAIL;
  944. }
  945. else
  946. {
  947. return OK;
  948. }
  949. }
  950. /**
  951. * @brief get snr value
  952. * @param[in] <none>
  953. * @return snr
  954. */
  955. float PAN3028_get_snr(void)
  956. {
  957. float snr_val=0.0;
  958. uint8_t sig_pow_l, sig_pow_m, sig_pow_h;
  959. uint8_t noise_pow_l, noise_pow_m, noise_pow_h;
  960. uint32_t sig_pow_val;
  961. uint32_t noise_pow_val;
  962. uint32_t sf_val;
  963. sig_pow_l = PAN3028_read_spec_page_reg(PAGE1_SEL,0x74);
  964. sig_pow_m = PAN3028_read_spec_page_reg(PAGE1_SEL,0x75);
  965. sig_pow_h = PAN3028_read_spec_page_reg(PAGE1_SEL,0x76);
  966. sig_pow_val = ((sig_pow_h << 16) | (sig_pow_m << 8) | sig_pow_l );
  967. noise_pow_l = PAN3028_read_spec_page_reg(PAGE2_SEL,0x71);
  968. noise_pow_m = PAN3028_read_spec_page_reg(PAGE2_SEL,0x72);
  969. noise_pow_h = PAN3028_read_spec_page_reg(PAGE2_SEL,0x73);
  970. noise_pow_val = ((noise_pow_h << 16) | (noise_pow_m << 8) | noise_pow_l );
  971. sf_val = (PAN3028_read_spec_page_reg(PAGE1_SEL,0x7c) & 0xf0) >> 4;
  972. if(noise_pow_val == 0)
  973. {
  974. noise_pow_val = 1;
  975. }
  976. snr_val = (float)(10 * log10((sig_pow_val / pow(2,sf_val)) / noise_pow_val));
  977. return snr_val;
  978. }
  979. /**
  980. * @brief get cascade snr value
  981. * @param[in] <none>
  982. * @return snr
  983. */
  984. float PAN3028_get_snr_cascade(void)
  985. {
  986. float snr_val1=0.0;
  987. uint8_t sig_pow_l, sig_pow_m, sig_pow_h;
  988. uint8_t noise_pow_l, noise_pow_m, noise_pow_h;
  989. uint32_t sig_pow_val;
  990. uint32_t noise_pow_val;
  991. sig_pow_l = PAN3028_read_spec_page_reg(PAGE1_SEL, 0x74);
  992. sig_pow_m = PAN3028_read_spec_page_reg(PAGE1_SEL, 0x75);
  993. sig_pow_h = PAN3028_read_spec_page_reg(PAGE1_SEL, 0x76);
  994. sig_pow_val = ( (sig_pow_h << 16) | (sig_pow_m << 8) | sig_pow_l );
  995. noise_pow_l = PAN3028_read_spec_page_reg(PAGE2_SEL,0x71);
  996. noise_pow_m = PAN3028_read_spec_page_reg(PAGE2_SEL,0x72);
  997. noise_pow_h = PAN3028_read_spec_page_reg(PAGE2_SEL,0x73);
  998. noise_pow_val = ((noise_pow_h << 16) | (noise_pow_m << 8) | noise_pow_l );
  999. if(noise_pow_val == 0)
  1000. {
  1001. noise_pow_val = 1;
  1002. }
  1003. snr_val1 = (float)(10 * log10((sig_pow_val)/noise_pow_val));
  1004. return snr_val1;
  1005. }
  1006. /**
  1007. * @brief get rssi value
  1008. * @param[in] <none>
  1009. * @return rssi
  1010. */
  1011. float PAN3028_get_rssi(void)
  1012. {
  1013. float rssi_val;
  1014. int rssi_mix_val;
  1015. int bw_pow_val;
  1016. float snr;
  1017. int bw_val = PAN3028_get_bw();
  1018. switch(bw_val)
  1019. {
  1020. case 6 :
  1021. bw_pow_val = 9;
  1022. break;
  1023. case 7 :
  1024. bw_pow_val = 6;
  1025. break;
  1026. case 8:
  1027. bw_pow_val = 3;
  1028. break;
  1029. case 9:
  1030. bw_pow_val = 0;
  1031. break;
  1032. }
  1033. snr = PAN3028_get_snr();
  1034. PAN3028_get_snr_cascade();
  1035. if(snr < 6)
  1036. {
  1037. rssi_val = snr - 113 - bw_pow_val;
  1038. }else{
  1039. rssi_mix_val = PAN3028_read_spec_page_reg(PAGE1_SEL,0x7e);
  1040. rssi_val = rssi_mix_val - 256;
  1041. }
  1042. return rssi_val;
  1043. }
  1044. /**
  1045. * @brief set tx_power
  1046. * @param[in] <tx_power> Reference datasheet for tx_power parameter description
  1047. * @return result
  1048. */
  1049. uint32_t PAN3028_set_tx_power(uint8_t tx_power)
  1050. {
  1051. uint8_t pa_1st_pwr, pa_2nd_pwr, reg_val;
  1052. pa_1st_pwr = (tx_power >> 4) & 0x07;
  1053. pa_2nd_pwr = tx_power & 0x0f;
  1054. if(pa_1st_pwr < 0x7)
  1055. {
  1056. pa_2nd_pwr = 0x0;
  1057. }
  1058. reg_val = (pa_2nd_pwr << 4) | pa_1st_pwr;
  1059. return PAN3028_write_spec_page_reg(PAGE1_SEL, 0x63, reg_val);
  1060. }
  1061. /**
  1062. * @brief get tx_power
  1063. * @param[in] <none>
  1064. * @return tx_power
  1065. */
  1066. uint32_t PAN3028_get_tx_power(void)
  1067. {
  1068. uint8_t pa_1st_pwr, pa_2nd_pwr, reg_val;
  1069. reg_val = PAN3028_read_spec_page_reg(PAGE1_SEL, 0x63);
  1070. pa_1st_pwr = reg_val & 0x07;
  1071. pa_2nd_pwr = (reg_val >> 4) & 0x0f;
  1072. return ((pa_1st_pwr << 4) | pa_2nd_pwr);
  1073. }
  1074. /**
  1075. * @brief set preamble
  1076. * @param[in] <reg> preamble
  1077. * @return result
  1078. */
  1079. uint32_t PAN3028_set_preamble(uint16_t reg)
  1080. {
  1081. uint8_t tmp_value;
  1082. tmp_value = reg & 0xff;
  1083. if(PAN3028_write_spec_page_reg(PAGE3_SEL,0x13, tmp_value) != OK)
  1084. {
  1085. return FAIL;
  1086. }
  1087. tmp_value = (reg >> 8) & 0xff;
  1088. if(PAN3028_write_spec_page_reg(PAGE3_SEL,0x14, tmp_value) != OK)
  1089. {
  1090. return FAIL;
  1091. }
  1092. return OK;
  1093. }
  1094. /**
  1095. * @brief set RF GPIO as input
  1096. * @param[in] <gpio_pin> pin number of GPIO to be enable
  1097. * @return result
  1098. */
  1099. uint32_t PAN3028_set_gpio_input(uint8_t gpio_pin)
  1100. {
  1101. uint8_t tmpreg = 0;
  1102. if(gpio_pin < 8)
  1103. {
  1104. tmpreg = PAN3028_read_spec_page_reg(PAGE0_SEL, 0x63);
  1105. tmpreg |= (1 << gpio_pin);
  1106. if(PAN3028_write_spec_page_reg(PAGE0_SEL, 0x63, tmpreg) != OK)
  1107. {
  1108. return FAIL;
  1109. }
  1110. else
  1111. {
  1112. return OK;
  1113. }
  1114. }
  1115. else
  1116. {
  1117. tmpreg = PAN3028_read_spec_page_reg(PAGE0_SEL, 0x64);
  1118. tmpreg |= (1 << (gpio_pin - 8));
  1119. if(PAN3028_write_spec_page_reg(PAGE0_SEL, 0x64, tmpreg) != OK)
  1120. {
  1121. return FAIL;
  1122. }
  1123. else
  1124. {
  1125. return OK;
  1126. }
  1127. }
  1128. }
  1129. /**
  1130. * @brief set RF GPIO as output
  1131. * @param[in] <gpio_pin> pin number of GPIO to be enable
  1132. * @return result
  1133. */
  1134. uint32_t PAN3028_set_gpio_output(uint8_t gpio_pin)
  1135. {
  1136. uint8_t tmpreg = 0;
  1137. if(gpio_pin < 8)
  1138. {
  1139. tmpreg = PAN3028_read_spec_page_reg(PAGE0_SEL, 0x65);
  1140. tmpreg |= (1 << gpio_pin);
  1141. if(PAN3028_write_spec_page_reg(PAGE0_SEL, 0x65, tmpreg) != OK)
  1142. {
  1143. return FAIL;
  1144. }
  1145. else
  1146. {
  1147. return OK;
  1148. }
  1149. }
  1150. else
  1151. {
  1152. tmpreg = PAN3028_read_spec_page_reg(PAGE0_SEL, 0x66);
  1153. tmpreg |= (1 << (gpio_pin - 8));
  1154. if(PAN3028_write_spec_page_reg(PAGE0_SEL, 0x66, tmpreg) != OK)
  1155. {
  1156. return FAIL;
  1157. }
  1158. else
  1159. {
  1160. return OK;
  1161. }
  1162. }
  1163. }
  1164. /**
  1165. * @brief set GPIO output state, SET or RESET
  1166. * @param[in] <gpio_pin> pin number of GPIO to be opearted
  1167. * <state> 0 - reset,
  1168. * 1 - set
  1169. * @return result
  1170. */
  1171. uint32_t PAN3028_set_gpio_state(uint8_t gpio_pin, uint8_t state)
  1172. {
  1173. uint8_t tmpreg = 0;
  1174. if(gpio_pin < 8)
  1175. {
  1176. tmpreg = PAN3028_read_spec_page_reg(PAGE0_SEL, 0x67);
  1177. if(state == 0)
  1178. {
  1179. tmpreg &= ~(1 << gpio_pin);
  1180. }
  1181. else
  1182. {
  1183. tmpreg |= (1 << gpio_pin);
  1184. }
  1185. if(PAN3028_write_spec_page_reg(PAGE0_SEL, 0x67, tmpreg) != OK)
  1186. {
  1187. return FAIL;
  1188. }
  1189. else
  1190. {
  1191. return OK;
  1192. }
  1193. }
  1194. else
  1195. {
  1196. tmpreg = PAN3028_read_spec_page_reg(PAGE0_SEL, 0x68);
  1197. if(state == 0)
  1198. {
  1199. tmpreg &= ~(1 << (gpio_pin - 8));
  1200. }
  1201. else
  1202. {
  1203. tmpreg |= (1 << (gpio_pin - 8));
  1204. }
  1205. if(PAN3028_write_spec_page_reg(PAGE0_SEL, 0x68, tmpreg) != OK)
  1206. {
  1207. return FAIL;
  1208. }
  1209. else
  1210. {
  1211. return OK;
  1212. }
  1213. }
  1214. }
  1215. /**
  1216. * @brief CAD function enable
  1217. * @param[in] <none>
  1218. * @return result
  1219. */
  1220. uint32_t PAN3028_cad_en(void)
  1221. {
  1222. PAN3028_set_gpio_output(11);
  1223. if(PAN3028_write_spec_page_reg(PAGE1_SEL, 0x0f, 0x10) != OK)
  1224. {
  1225. return FAIL;
  1226. }
  1227. return OK;
  1228. }
  1229. /**
  1230. * @brief set rf syncword
  1231. * @param[in] <sync> syncword
  1232. * @return result
  1233. */
  1234. uint32_t PAN3028_set_syncword(uint32_t sync)
  1235. {
  1236. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x0f, sync) != OK)
  1237. {
  1238. return FAIL;
  1239. }
  1240. else
  1241. {
  1242. return OK;
  1243. }
  1244. }
  1245. /**
  1246. * @brief read rf syncword
  1247. * @param[in] <none>
  1248. * @return syncword
  1249. */
  1250. uint8_t PAN3028_get_syncword(void)
  1251. {
  1252. uint8_t tmpreg;
  1253. tmpreg = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x0f);
  1254. return tmpreg;
  1255. }
  1256. /**
  1257. * @brief send one packet
  1258. * @param[in] <buff> buffer contain data to send
  1259. * @param[in] <len> the length of data to send
  1260. * @return result
  1261. */
  1262. uint32_t PAN3028_send_packet(uint8_t *buff, uint32_t len)
  1263. {
  1264. if(PAN3028_write_spec_page_reg(PAGE1_SEL,REG_PAYLOAD_LEN,len) != OK)
  1265. {
  1266. return FAIL;
  1267. }
  1268. if(PAN3028_write_reg(REG_OP_MODE,PAN3028_MODE_TX) != OK)
  1269. {
  1270. return FAIL;
  1271. }
  1272. else
  1273. {
  1274. PAN3028_write_fifo(REG_FIFO_ACC_ADDR,buff,len);
  1275. return OK;
  1276. }
  1277. }
  1278. /**
  1279. * @brief receive a packet in non-block method, it will return 0 when no data got
  1280. * @param[in] <buff> buffer provide for data to receive
  1281. * @return length, it will return 0 when no data got
  1282. */
  1283. uint8_t PAN3028_recv_packet(uint8_t *buff)
  1284. {
  1285. uint32_t len = 0;
  1286. len = PAN3028_read_spec_page_reg(PAGE1_SEL, 0x7D);
  1287. PAN3028_read_fifo(REG_FIFO_ACC_ADDR,buff,len);
  1288. /* clear rx done irq */
  1289. PAN3028_clr_irq();
  1290. return len;
  1291. }
  1292. /**
  1293. * @brief set early interruption
  1294. * @param[in] <earlyirq_val> PLHD IRQ to set
  1295. * PLHD_IRQ_ON / PLHD_IRQ_OFF
  1296. * @return result
  1297. */
  1298. uint32_t PAN3028_set_early_irq(uint32_t earlyirq_val)
  1299. {
  1300. uint8_t temp_val_1;
  1301. uint8_t temp_val_2;
  1302. temp_val_1 = PAN3028_read_spec_page_reg(PAGE1_SEL, 0x2d);
  1303. temp_val_2 = ((temp_val_1 & 0x7f) | (earlyirq_val << 7)) ;
  1304. if(PAN3028_write_spec_page_reg(PAGE1_SEL, 0x2d, temp_val_2) != OK)
  1305. {
  1306. return FAIL;
  1307. }
  1308. else
  1309. {
  1310. return OK;
  1311. }
  1312. }
  1313. /**
  1314. * @brief read plhd irq status
  1315. * @param[in] <none>
  1316. * @return plhd irq status
  1317. */
  1318. uint8_t PAN3028_get_early_irq(void)
  1319. {
  1320. uint8_t tmpreg;
  1321. tmpreg = PAN3028_read_spec_page_reg(PAGE1_SEL, 0x2d);
  1322. return tmpreg;
  1323. }
  1324. /**
  1325. * @brief set plhd
  1326. * @param[in] <addr> PLHD start addr,Range:0..7f
  1327. * <len> PLHD len
  1328. * PLHD_LEN8 / PLHD_LEN16
  1329. * @return result
  1330. */
  1331. uint32_t PAN3028_set_plhd(uint8_t addr,uint8_t len)
  1332. {
  1333. uint8_t temp_val_2;
  1334. temp_val_2 = ((addr & 0x7f) | (len << 7)) ;
  1335. if(PAN3028_write_spec_page_reg(PAGE1_SEL, 0x2e, temp_val_2) != OK)
  1336. {
  1337. return FAIL;
  1338. }
  1339. else
  1340. {
  1341. return OK;
  1342. }
  1343. }
  1344. /**
  1345. * @brief read plhd status
  1346. * @param[in] <none>
  1347. * @return plhd status
  1348. */
  1349. uint8_t PAN3028_get_plhd(void)
  1350. {
  1351. uint8_t tmpreg;
  1352. tmpreg = PAN3028_read_spec_page_reg(PAGE1_SEL, 0x2e);
  1353. return ((tmpreg & 0x80) >> 7);
  1354. }
  1355. /**
  1356. * @brief set plhd mask
  1357. * @param[in] <plhd_val> plhd mask to set
  1358. * PLHD_ON / PLHD_OFF
  1359. * @return result
  1360. */
  1361. uint32_t PAN3028_set_plhd_mask(uint32_t plhd_val)
  1362. {
  1363. uint8_t temp_val_1;
  1364. uint8_t temp_val_2;
  1365. temp_val_1 = PAN3028_read_spec_page_reg(PAGE0_SEL, 0x58);
  1366. temp_val_2 = ((temp_val_1 & 0xef) | (plhd_val << 4)) ;
  1367. if(PAN3028_write_spec_page_reg(PAGE0_SEL, 0x58, temp_val_2) != OK)
  1368. {
  1369. return FAIL;
  1370. }
  1371. else
  1372. {
  1373. return OK;
  1374. }
  1375. }
  1376. /**
  1377. * @brief read plhd mask
  1378. * @param[in] <none>
  1379. * @return plhd mask
  1380. */
  1381. uint8_t PAN3028_get_plhd_mask(void)
  1382. {
  1383. uint8_t tmpreg;
  1384. tmpreg = PAN3028_read_spec_page_reg(PAGE0_SEL, 0x58);
  1385. return tmpreg;
  1386. }
  1387. /**
  1388. * @brief receive 8 bytes plhd data
  1389. * @param[in] <buff> buffer provide for data to receive
  1390. * @return result
  1391. */
  1392. uint8_t PAN3028_recv_plhd8(uint8_t *buff)
  1393. {
  1394. uint32_t i,len = 8;
  1395. for(i = 0; i < len; i++)
  1396. {
  1397. buff[i] = PAN3028_read_spec_page_reg(PAGE2_SEL, 0x76 + i);
  1398. }
  1399. PAN3028_clr_irq();
  1400. return len;
  1401. }
  1402. /**
  1403. * @brief receive 16 bytes plhd data
  1404. * @param[in] <buff> buffer provide for data to receive
  1405. * @return result
  1406. */
  1407. uint8_t PAN3028_recv_plhd16(uint8_t *buff)
  1408. {
  1409. uint32_t i,len = 16;
  1410. for(i = 0; i < len; i++)
  1411. {
  1412. if(i<10)
  1413. {
  1414. buff[i] = PAN3028_read_spec_page_reg(PAGE2_SEL, 0x76 + i);
  1415. }else{
  1416. buff[i] = PAN3028_read_spec_page_reg(PAGE0_SEL, 0x76 + i - 10);
  1417. }
  1418. }
  1419. PAN3028_clr_irq();
  1420. return len;
  1421. }
  1422. /**
  1423. * @brief receive a packet in non-block method, it will return 0 when no data got
  1424. * @param[in] <buff> buffer provide for data to receive
  1425. * <len> PLHD_LEN8 / PLHD_LEN16
  1426. * @return result
  1427. */
  1428. uint32_t PAN3028_plhd_receive(uint8_t *buf,uint8_t len)
  1429. {
  1430. if(len == PLHD_LEN8)
  1431. {
  1432. return PAN3028_recv_plhd8(buf);
  1433. }else if (len == PLHD_LEN16)
  1434. {
  1435. return PAN3028_recv_plhd16(buf);
  1436. }
  1437. return FAIL;
  1438. }
  1439. /**
  1440. * @brief set dcdc mode, The default configuration is DCDC_OFF, PAN3028 should set DCDC_OFF before enter sleep/deepsleep
  1441. * @param[in] <dcdc_val> dcdc switch
  1442. * DCDC_ON / DCDC_OFF
  1443. * @return result
  1444. */
  1445. uint32_t PAN3028_set_dcdc_mode(uint32_t dcdc_val)
  1446. {
  1447. uint8_t temp_val_1;
  1448. uint8_t temp_val_2;
  1449. temp_val_1 = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x1e);
  1450. temp_val_2 = ((temp_val_1 & 0xfe) | (dcdc_val << 0)) ;
  1451. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x1e, temp_val_2) != OK)
  1452. {
  1453. return FAIL;
  1454. }
  1455. else
  1456. {
  1457. return OK;
  1458. }
  1459. }
  1460. /**
  1461. * @brief set LDR mode
  1462. * @param[in] <mode> LDR switch
  1463. * LDR_ON / LDR_OFF
  1464. * @return result
  1465. */
  1466. uint32_t PAN3028_set_ldr(uint32_t mode)
  1467. {
  1468. uint8_t temp_val_1;
  1469. uint8_t temp_val_2;
  1470. temp_val_1 = PAN3028_read_spec_page_reg(PAGE3_SEL, 0x12);
  1471. temp_val_2 = ((temp_val_1 & 0xF7) | (mode << 3)) ;
  1472. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x12, temp_val_2) != OK)
  1473. {
  1474. return FAIL;
  1475. }
  1476. else
  1477. {
  1478. return OK;
  1479. }
  1480. }
  1481. /**
  1482. * @brief set preamble by Spreading Factor,It is useful in all_sf_search mode
  1483. * @param[in] <sf> Spreading Factor
  1484. * @return result
  1485. */
  1486. uint32_t PAN3028_set_all_sf_preamble(uint32_t sf)
  1487. {
  1488. switch(sf)
  1489. {
  1490. case 7:
  1491. return (PAN3028_write_spec_page_reg(PAGE3_SEL, 0x13, 128) == OK);
  1492. case 8:
  1493. return (PAN3028_write_spec_page_reg(PAGE3_SEL, 0x13, 80) == OK);
  1494. case 9:
  1495. return (PAN3028_write_spec_page_reg(PAGE3_SEL, 0x13, 48) == OK);
  1496. case 10:
  1497. return (PAN3028_write_spec_page_reg(PAGE3_SEL, 0x13, 24) == OK);
  1498. case 11:
  1499. return (PAN3028_write_spec_page_reg(PAGE3_SEL, 0x13, 16) == OK);
  1500. case 12:
  1501. return (PAN3028_write_spec_page_reg(PAGE3_SEL, 0x13, 12) == OK);
  1502. default:
  1503. return FAIL;
  1504. }
  1505. }
  1506. /**
  1507. * @brief open all sf auto-search mode
  1508. * @param[in] <none>
  1509. * @return result
  1510. */
  1511. uint32_t PAN3028_set_all_sf_search(void)
  1512. {
  1513. uint8_t tmp_val;
  1514. tmp_val = (PAN3028_read_spec_page_reg(PAGE3_SEL,0x12) | 0x01);
  1515. if(PAN3028_write_spec_page_reg(PAGE3_SEL,0x12,tmp_val) != OK)
  1516. {
  1517. return FAIL;
  1518. }
  1519. if(PAN3028_write_spec_page_reg(PAGE1_SEL,0x2d,0x3f) != OK)
  1520. {
  1521. return FAIL;
  1522. }
  1523. if(PAN3028_write_spec_page_reg(PAGE0_SEL,0x06,0x01) != OK)
  1524. {
  1525. return FAIL;
  1526. }
  1527. if(PAN3028_write_spec_page_reg(PAGE0_SEL,0x4a,0xae) != OK)
  1528. {
  1529. return FAIL;
  1530. }
  1531. if(PAN3028_write_spec_page_reg(PAGE0_SEL,0x55,0x02) != OK)
  1532. {
  1533. return FAIL;
  1534. }
  1535. if(PAN3028_write_spec_page_reg(PAGE1_SEL,0x0f,0x0a) != OK)
  1536. {
  1537. return FAIL;
  1538. }
  1539. return OK;
  1540. }
  1541. /**
  1542. * @brief close all sf auto-search mode
  1543. * @param[in] <none>
  1544. * @return result
  1545. */
  1546. uint32_t PAN3028_set_all_sf_search_off(void)
  1547. {
  1548. uint8_t tmp_val;
  1549. tmp_val = (PAN3028_read_spec_page_reg(PAGE3_SEL,0x12) & 0xFE);
  1550. if(PAN3028_write_spec_page_reg(PAGE3_SEL,0x12,tmp_val) != OK)
  1551. {
  1552. return FAIL;
  1553. }
  1554. else
  1555. {
  1556. return OK;
  1557. }
  1558. }
  1559. /**
  1560. * @brief RF IRQ server routine, it should be call at ISR of IRQ pin
  1561. * @param[in] <none>
  1562. * @return result
  1563. */
  1564. void PAN3028_irq_handler(void)
  1565. {
  1566. double snr,rssi,plhd_len;
  1567. uint16_t size = 0;
  1568. uint8_t irq = PAN3028_get_irq();
  1569. if(irq & REG_IRQ_RX_PLHD_DONE)
  1570. {
  1571. plhd_len = PAN3028_get_plhd();
  1572. size = PAN3028_plhd_receive(plhd_buf,plhd_len);
  1573. rf_rx_plhddone_event( plhd_buf, size );
  1574. }else if(irq & REG_IRQ_RX_DONE)
  1575. {
  1576. snr = PAN3028_get_snr();
  1577. rssi = PAN3028_get_rssi();
  1578. size = PAN3028_recv_packet(RadioRxPayload);
  1579. rf_rx_done_event( RadioRxPayload, size, rssi, snr );
  1580. }
  1581. else if(irq & REG_IRQ_CRC_ERR)
  1582. {
  1583. rf_rx_err_event();
  1584. PAN3028_clr_irq();
  1585. }
  1586. else if(irq & REG_IRQ_RX_TIMEOUT)
  1587. {
  1588. rf_rx_timeout_event();
  1589. PAN3028_clr_irq();
  1590. }
  1591. else if(irq & REG_IRQ_TX_DONE)
  1592. {
  1593. rf_tx_done_event();
  1594. PAN3028_clr_irq();
  1595. }
  1596. }
  1597. /**
  1598. * @brief set carrier tx power
  1599. * @param[in] <none>
  1600. * @return result
  1601. */
  1602. uint32_t PAN3028_set_carrier_tx_power(uint8_t tx_power)
  1603. {
  1604. uint8_t pa_1st_pwr, pa_2nd_pwr, reg_val;
  1605. pa_1st_pwr = (tx_power >> 4) & 0x07;
  1606. pa_2nd_pwr = tx_power & 0x0f;
  1607. if(pa_1st_pwr < 0x7)
  1608. {
  1609. pa_2nd_pwr = 0x0;
  1610. }
  1611. reg_val = (pa_2nd_pwr << 4) | pa_1st_pwr;
  1612. return PAN3028_write_spec_page_reg(PAGE1_SEL, 0x65, reg_val);
  1613. }
  1614. /**
  1615. * @brief get carrier tx power
  1616. * @param[in] <none>
  1617. * @return carrier tx power
  1618. */
  1619. uint32_t PAN3028_get_carrier_tx_power(void)
  1620. {
  1621. uint8_t pa_1st_pwr, pa_2nd_pwr, reg_val;
  1622. reg_val = PAN3028_read_spec_page_reg(PAGE1_SEL, 0x65);
  1623. pa_1st_pwr = reg_val & 0x07;
  1624. pa_2nd_pwr = (reg_val >> 4) & 0x0f;
  1625. return ((pa_1st_pwr << 4) | pa_2nd_pwr);
  1626. }
  1627. /**
  1628. * @brief set wave test mode
  1629. * @param[in] none
  1630. * @return result
  1631. */
  1632. uint32_t PAN3028_set_carrier_wave_test_mode(void)
  1633. {
  1634. if(PAN3028_write_reg(0x02, 0x01) != OK)
  1635. {
  1636. return FAIL;
  1637. }
  1638. rf_port.delayms(8);
  1639. if(PAN3028_write_reg(0x04, 0x16) != OK)
  1640. {
  1641. return FAIL;
  1642. }
  1643. rf_port.delayms(8);
  1644. if(PAN3028_write_reg(0x04, 0x56) != OK)
  1645. {
  1646. return FAIL;
  1647. }
  1648. rf_port.delayms(8);
  1649. if(PAN3028_write_reg(0x04, 0x76) != OK)
  1650. {
  1651. return FAIL;
  1652. }
  1653. rf_port.delayms(8);
  1654. rf_port.antenna_init();
  1655. rf_port.tcxo_init();
  1656. rf_port.delayms(8);
  1657. if(PAN3028_write_reg(0x04, 0xF6) != OK)
  1658. {
  1659. return FAIL;
  1660. }
  1661. rf_port.delayms(8);
  1662. if(PAN3028_write_reg(0x02, 0x02) != OK)
  1663. {
  1664. return FAIL;
  1665. }
  1666. rf_port.delayms(8);
  1667. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x24, 0x60) != OK)
  1668. {
  1669. return FAIL;
  1670. }
  1671. rf_port.delayms(8);
  1672. if(PAN3028_write_reg(0x02, 0x03) != OK)
  1673. {
  1674. return FAIL;
  1675. }
  1676. rf_port.delayms(8);
  1677. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x24, 0xE0) != OK)
  1678. {
  1679. return FAIL;
  1680. }
  1681. rf_port.delayms(8);
  1682. if(PAN3028_write_reg(0x02, 0x04) != OK)
  1683. {
  1684. return FAIL;
  1685. }
  1686. rf_port.delayms(8);
  1687. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x24, 0xF0) != OK)
  1688. {
  1689. return FAIL;
  1690. }
  1691. rf_port.delayms(8);
  1692. if(PAN3028_write_spec_page_reg(PAGE0_SEL, 0x4a, 0x8e) != OK)
  1693. {
  1694. return FAIL;
  1695. }
  1696. rf_port.delayms(8);
  1697. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x18, 0x0f) != OK)
  1698. {
  1699. return FAIL;
  1700. }
  1701. rf_port.delayms(8);
  1702. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x15, 0x58) != OK)
  1703. {
  1704. return FAIL;
  1705. }
  1706. rf_port.delayms(8);
  1707. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x16, 0x64) != OK)
  1708. {
  1709. return FAIL;
  1710. }
  1711. rf_port.delayms(8);
  1712. if(PAN3028_write_spec_page_reg(PAGE3_SEL, 0x17, 0x00) != OK)
  1713. {
  1714. return FAIL;
  1715. }
  1716. rf_port.delayms(8);
  1717. if(PAN3028_write_spec_page_reg(PAGE1_SEL, 0x66, 0x7f) != OK)
  1718. {
  1719. return FAIL;
  1720. }
  1721. rf_port.delayms(8);
  1722. if(PAN3028_write_spec_page_reg(PAGE1_SEL, 0x65, 0xf7) != OK)
  1723. {
  1724. return FAIL;
  1725. }
  1726. rf_port.delayms(8);
  1727. if(PAN3028_write_spec_page_reg(PAGE0_SEL, 0x17, 0x08) != OK)
  1728. {
  1729. return FAIL;
  1730. }
  1731. rf_port.delayms(8);
  1732. if(PAN3028_write_spec_page_reg(PAGE0_SEL, 0x18, 0x28) != OK)
  1733. {
  1734. return FAIL;
  1735. }
  1736. rf_port.delayms(8);
  1737. return OK;
  1738. }