A7169_hal.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. #include "A7169_hal.h"
  2. #include "A7169reg.h"
  3. /*********************************************************************
  4. ** Global Variable Declaration
  5. *********************************************************************/
  6. uint8_t timer;
  7. uint8_t TimeoutFlag;
  8. uint16_t RxCnt;
  9. uint32_t Err_ByteCnt;
  10. uint32_t Err_BitCnt;
  11. uint16_t TimerCnt0;
  12. uint8_t *Uartptr;
  13. uint8_t UartSendCnt;
  14. uint8_t CmdBuf[11];
  15. uint8_t tmpbuf[64];
  16. uint8_t fb;
  17. uint16_t BODF;
  18. bool fb_ok;
  19. const uint8_t BitCount_Tab[16]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
  20. const uint8_t ID_Tab[8]={0x34,0x75,0xC5,0x8C,0xC7,0x33,0x45,0xE7}; //ID
  21. const uint8_t PN9_Tab[]=
  22. { 0xFF,0x83,0xDF,0x17,0x32,0x09,0x4E,0xD1,
  23. 0xE7,0xCD,0x8A,0x91,0xC6,0xD5,0xC4,0xC4,
  24. 0x40,0x21,0x18,0x4E,0x55,0x86,0xF4,0xDC,
  25. 0x8A,0x15,0xA7,0xEC,0x92,0xDF,0x93,0x53,
  26. 0x30,0x18,0xCA,0x34,0xBF,0xA2,0xC7,0x59,
  27. 0x67,0x8F,0xBA,0x0D,0x6D,0xD8,0x2D,0x7D,
  28. 0x54,0x0A,0x57,0x97,0x70,0x39,0xD2,0x7A,
  29. 0xEA,0x24,0x33,0x85,0xED,0x9A,0x1D,0xE0
  30. }; // This table are 64bytes PN9 pseudo random code.
  31. A7169Config_ts A7169ConfigBuffer;
  32. void A7169_delayMs(uint32_t time)
  33. {
  34. uint32_t i, j;
  35. i = time;
  36. while (i --)
  37. {
  38. for ( j = 0; j < 1000; j++)
  39. {
  40. ;
  41. }
  42. }
  43. }
  44. void A7169_delayUs(uint32_t time)
  45. {
  46. uint32_t i, j;
  47. i = time;
  48. while (i --)
  49. {
  50. for ( j = 0; j < 1; j++)
  51. {
  52. ;
  53. }
  54. }
  55. }
  56. /*********************************************************************
  57. ** Strobe Command
  58. *********************************************************************/
  59. void StrobeCMD(uint8_t cmd)
  60. {
  61. BOARD_A7169_SCS_L();
  62. myRadioSpi_wByte(cmd);
  63. BOARD_A7169_SCS_H();
  64. }
  65. /************************************************************************
  66. ** A7169_WriteReg
  67. ************************************************************************/
  68. void A7169_WriteReg(uint8_t address, uint16_t dataWord)
  69. {
  70. BOARD_A7169_SCS_L();
  71. address |= CMD_Reg_W;
  72. myRadioSpi_wByte(address);
  73. //send word
  74. myRadioSpi_wByte((dataWord >> 8) & 0x00ff);
  75. myRadioSpi_wByte(dataWord & 0x00ff);
  76. BOARD_A7169_SCS_H();
  77. }
  78. /************************************************************************
  79. ** A7169_ReadReg
  80. ************************************************************************/
  81. uint16_t A7169_ReadReg(uint8_t address)
  82. {
  83. uint16_t tmp;
  84. BOARD_A7169_SCS_L();
  85. address |= CMD_Reg_R;
  86. myRadioSpi_wByte(address);
  87. //read code
  88. tmp = (uint16_t)myRadioSpi_rByte() << 8;
  89. tmp |= ((uint16_t)myRadioSpi_rByte() & 0x00ff);
  90. BOARD_A7169_SCS_H();
  91. return tmp;
  92. }
  93. /************************************************************************
  94. ** A7169_WritePageA
  95. ************************************************************************/
  96. void A7169_WritePageA(uint8_t address, uint16_t dataWord)
  97. {
  98. uint16_t tmp;
  99. tmp = address;
  100. tmp = ((tmp << 12) | A7169ConfigBuffer.config[CRYSTAL_REG]);
  101. A7169_WriteReg(CRYSTAL_REG, tmp);
  102. A7169_WriteReg(PAGEA_REG, dataWord);
  103. }
  104. /************************************************************************
  105. ** A7169_ReadPageA
  106. ************************************************************************/
  107. uint16_t A7169_ReadPageA(uint8_t address)
  108. {
  109. uint16_t tmp;
  110. tmp = address;
  111. tmp = ((tmp << 12) | A7169ConfigBuffer.config[CRYSTAL_REG]);
  112. A7169_WriteReg(CRYSTAL_REG, tmp);
  113. tmp = A7169_ReadReg(PAGEA_REG);
  114. return tmp;
  115. }
  116. /************************************************************************
  117. ** A7169_WritePageB
  118. ************************************************************************/
  119. void A7169_WritePageB(uint8_t address, uint16_t dataWord)
  120. {
  121. uint16_t tmp;
  122. tmp = address;
  123. if ( tmp & 0x20 )
  124. {
  125. tmp = ( ( ( tmp & 0x1F ) << 7 ) | (A7169ConfigBuffer.config[CRYSTAL_REG]&~0x0F80) );
  126. A7169_WriteReg ( CRYSTAL_REG, tmp );
  127. A7169_WriteReg ( PIN_REG,((A7169ConfigBuffer.config[PIN_REG]&~0x0001) | 0x01) );
  128. }
  129. else
  130. {
  131. tmp = ( ( ( tmp & 0x1F ) << 7 ) | (A7169ConfigBuffer.config[CRYSTAL_REG]&~0x0F80) );
  132. A7169_WriteReg ( CRYSTAL_REG, tmp );
  133. A7169_WriteReg ( PIN_REG, (A7169ConfigBuffer.config[PIN_REG]&~0x0001));
  134. }
  135. A7169_WriteReg(PAGEB_REG, dataWord);
  136. }
  137. /************************************************************************
  138. ** A7169_ReadPageB
  139. ************************************************************************/
  140. uint16_t A7169_ReadPageB(uint8_t address)
  141. {
  142. uint16_t tmp;
  143. tmp = address;
  144. if ( tmp & 0x20 )
  145. {
  146. tmp = ( ( ( tmp & 0x1F ) << 7 ) | (A7169ConfigBuffer.config[CRYSTAL_REG]&~0x0F80) );
  147. A7169_WriteReg ( CRYSTAL_REG, tmp );
  148. A7169_WriteReg ( PIN_REG, ((A7169ConfigBuffer.config[PIN_REG]&~0x0001) | 0x01) );
  149. }
  150. else
  151. {
  152. tmp = ( ( ( tmp & 0x1F ) << 7 ) | (A7169ConfigBuffer.config[CRYSTAL_REG]&~0x0F80) );
  153. A7169_WriteReg ( CRYSTAL_REG, tmp );
  154. A7169_WriteReg ( PIN_REG, (A7169ConfigBuffer.config[PIN_REG]&~0x0001) );
  155. }
  156. tmp = A7169_ReadReg(PAGEB_REG);
  157. return tmp;
  158. }
  159. /*********************************************************************
  160. ** A7169_POR
  161. *********************************************************************/
  162. void A7169_POR(void)
  163. {
  164. //power on only
  165. A7169_delayMs(10); //for regulator settling time (power on only)
  166. StrobeCMD(CMD_RF_RST); //reset A7169 chip
  167. while(A7169_WriteID()) //check SPI
  168. {
  169. StrobeCMD(CMD_RF_RST); //reset A7169 chip
  170. }
  171. A7169_WritePageA(PM_PAGEA, A7169ConfigBuffer.pageA[PM_PAGEA] | 0x1000); //STS=1
  172. A7169_delayMs(2);
  173. entry_deep_sleep_mode(); //deep sleep
  174. A7169_delayMs(2);
  175. wake_up_from_deep_sleep_mode(); //wake up
  176. StrobeCMD(CMD_RF_RST); //reset A7169 chip
  177. while(A7169_WriteID()) //check SPI
  178. {
  179. StrobeCMD(CMD_RF_RST); //reset A7169 chip
  180. }
  181. A7169_WritePageA(PM_PAGEA, A7169ConfigBuffer.pageA[PM_PAGEA] | 0x1000); //STS=1
  182. A7169_delayMs(2);
  183. }
  184. /*********************************************************************
  185. ** InitRF
  186. *********************************************************************/
  187. uint8_t InitRF(void)
  188. {
  189. //initial pin
  190. A7169_delayMs(1); //delay 1ms for regulator stabilized
  191. StrobeCMD(CMD_RF_RST); //reset A7169 chip
  192. A7169_delayMs(1);
  193. if(A7169_Config()) //config A7169 chip
  194. return 1;
  195. A7169_delayUs(800); //delay 800us for crystal stabilized
  196. if(A7169_WriteID()) //write ID code
  197. return 1;
  198. if(A7169_Cal()) //IF and VCO Calibration
  199. return 1;
  200. return 0;
  201. }
  202. /*********************************************************************
  203. ** A7169_Config
  204. *********************************************************************/
  205. uint8_t A7169_Config(void)
  206. {
  207. uint8_t i;
  208. uint16_t tmp = 0;
  209. for(i=0; i<8; i++)
  210. A7169_WriteReg(i, A7169ConfigBuffer.config[i]);
  211. for(i=10; i<16; i++)
  212. {
  213. if((i == 14) && (fb_ok == 1))
  214. A7169_WriteReg(i, A7169ConfigBuffer.config[i] | (1<<4)); //MIFS=1(Manual)
  215. else
  216. A7169_WriteReg(i, A7169ConfigBuffer.config[i]);
  217. }
  218. for(i=0; i<16; i++)
  219. A7169_WritePageA(i, A7169ConfigBuffer.pageA[i]);
  220. for(i=0; i<53; i++)
  221. A7169_WritePageB(i, A7169ConfigBuffer.pageB[i]);
  222. //for check
  223. tmp = A7169_ReadReg(SYSTEMCLOCK_REG);
  224. if(tmp != A7169ConfigBuffer.config[SYSTEMCLOCK_REG])
  225. {
  226. return 1;
  227. }
  228. return 0;
  229. }
  230. /************************************************************************
  231. ** WriteID
  232. ************************************************************************/
  233. uint8_t A7169_WriteID(void)
  234. {
  235. uint8_t i;
  236. uint8_t d1, d2, d3, d4;
  237. BOARD_A7169_SCS_L();
  238. myRadioSpi_wByte(CMD_ID_W);
  239. for(i=0; i<4; i++)
  240. myRadioSpi_wByte(ID_Tab[i]);
  241. BOARD_A7169_SCS_H();
  242. BOARD_A7169_SCS_L();
  243. myRadioSpi_wByte(CMD_ID_R);
  244. d1=myRadioSpi_rByte();
  245. d2=myRadioSpi_rByte();
  246. d3=myRadioSpi_rByte();
  247. d4=myRadioSpi_rByte();
  248. BOARD_A7169_SCS_H();
  249. if((d1!=ID_Tab[0]) || (d2!=ID_Tab[1]) || (d3!=ID_Tab[2]) || (d4!=ID_Tab[3]))
  250. {
  251. return 1;
  252. }
  253. return 0;
  254. }
  255. /*********************************************************************
  256. ** A7169_Cal
  257. *********************************************************************/
  258. uint8_t A7169_Cal(void)
  259. {
  260. uint8_t i;
  261. uint8_t fb_old, fcd, fbcf;//IF Filter
  262. uint8_t vb,vbcf; //VCO Current
  263. uint8_t vcb, vccf; //VCO Band
  264. uint16_t tmp;
  265. bool fb_fail;
  266. StrobeCMD(CMD_STBY);
  267. //IF calibration procedure @STB state
  268. if(fb_ok == 1)
  269. {
  270. A7169_WriteReg(MODE_REG, A7169ConfigBuffer.config[MODE_REG] | 0x0800); //VCO Current Calibration
  271. do{
  272. tmp = A7169_ReadReg(MODE_REG);
  273. }while(tmp & 0x0800);
  274. tmp = (A7169ConfigBuffer.config[CALIBRATION_REG] & 0xFFE0);
  275. tmp = tmp | fb | (1<<4);
  276. A7169_WriteReg(CALIBRATION_REG, tmp);
  277. }
  278. else
  279. {
  280. //IF calibration procedure @STB state
  281. fb_fail=0;
  282. for(i=0;i<3;i++)
  283. {
  284. A7169_WriteReg(MODE_REG, A7169ConfigBuffer.config[MODE_REG] | 0x0802); //IF Filter & VCO Current Calibration
  285. do{
  286. tmp = A7169_ReadReg(MODE_REG);
  287. }while(tmp & 0x0802);
  288. //for check(IF Filter)
  289. tmp = A7169_ReadReg(CALIBRATION_REG);
  290. fb = tmp & 0x0F;
  291. fcd = (tmp>>11) & 0x1F;
  292. fbcf = (tmp>>4) & 0x01;
  293. if((fb<3) || (fb>11))
  294. fb_fail = 1;
  295. else
  296. {
  297. if(i==0)
  298. fb_old = fb;
  299. else
  300. {
  301. if(fb != fb_old)
  302. {
  303. if(fb > fb_old)
  304. {
  305. if((fb-fb_old)!=1)
  306. fb_fail = 1;
  307. }
  308. else
  309. {
  310. if((fb_old-fb)!=1)
  311. fb_fail = 1;
  312. }
  313. }
  314. }
  315. }
  316. if((fbcf) || (fb_fail) || (fcd>6))
  317. {
  318. return 1;
  319. }
  320. }
  321. }
  322. tmp = 0;
  323. tmp = ( fb - 2 ) | 0x0010;
  324. A7169_WriteReg ( CALIBRATION_REG, A7169ConfigBuffer.config[CALIBRATION_REG] | tmp );
  325. //for check(VCO Current)
  326. tmp = A7169_ReadPageA(VCB_PAGEA);
  327. vcb = tmp & 0x0F;
  328. vccf = (tmp>>4) & 0x01;
  329. if(vccf)
  330. {
  331. return 1;
  332. }
  333. //RSSI Calibration procedure @STB state
  334. A7169_WriteReg(ADC_REG, 0x4C00); //set ADC average=64
  335. A7169_WriteReg(MODE_REG, A7169ConfigBuffer.config[MODE_REG] | 0x9000); //RSSI Calibration
  336. do{
  337. tmp = A7169_ReadReg(MODE_REG);
  338. }while(tmp & 0x1000);
  339. A7169_WriteReg(ADC_REG, A7169ConfigBuffer.config[ADC_REG]);
  340. //VCO calibration procedure @STB state
  341. A7169_WriteReg(PLL1_REG, A7169ConfigBuffer.config[PLL1_REG]);
  342. A7169_WriteReg(PLL2_REG, A7169ConfigBuffer.config[PLL2_REG]);
  343. A7169_WriteReg(MODE_REG, A7169ConfigBuffer.config[MODE_REG] | 0x0004); //VCO Band Calibration
  344. do{
  345. tmp = A7169_ReadReg(MODE_REG);
  346. }while(tmp & 0x0004);
  347. //for check(VCO Band)
  348. tmp = A7169_ReadReg(CALIBRATION_REG);
  349. vb = (tmp >>5) & 0x07;
  350. vbcf = (tmp >>8) & 0x01;
  351. if(vbcf)
  352. {
  353. return 1;
  354. }
  355. fb_ok = 1;
  356. return 0;
  357. }
  358. /*********************************************************************
  359. ** A7169_WriteFIFO
  360. *********************************************************************/
  361. void A7169_WriteFIFO(void)
  362. {
  363. uint8_t i;
  364. StrobeCMD(CMD_TFR); //TX FIFO address pointer reset
  365. BOARD_A7169_SCS_L();
  366. myRadioSpi_wByte(CMD_FIFO_W); //TX FIFO write command
  367. for(i=0; i <64; i++)
  368. myRadioSpi_wByte(PN9_Tab[i]);
  369. BOARD_A7169_SCS_H();
  370. }
  371. /*********************************************************************
  372. ** A7169_FifoWrite
  373. *********************************************************************/
  374. void A7169_FifoWrite(uint8_t *src, uint16_t len)
  375. {
  376. uint8_t i;
  377. StrobeCMD(CMD_TFR); //TX FIFO address pointer reset
  378. BOARD_A7169_SCS_L();
  379. myRadioSpi_wByte(CMD_FIFO_W); //TX FIFO write command
  380. for(i=0; i < len; i++)
  381. {
  382. myRadioSpi_wByte(src[i]);
  383. }
  384. BOARD_A7169_SCS_H();
  385. }
  386. /*********************************************************************
  387. ** RxPacket
  388. *********************************************************************/
  389. void RxPacket(void)
  390. {
  391. uint8_t i;
  392. uint8_t recv;
  393. uint8_t tmp;
  394. RxCnt++;
  395. StrobeCMD(CMD_RFR); //RX FIFO address pointer reset
  396. BOARD_A7169_SCS_L();
  397. myRadioSpi_wByte(CMD_FIFO_R); //RX FIFO read command
  398. for(i=0; i <64; i++)
  399. {
  400. tmpbuf[i] = myRadioSpi_rByte();
  401. }
  402. BOARD_A7169_SCS_H();
  403. for(i=0; i<64; i++)
  404. {
  405. recv = tmpbuf[i];
  406. tmp = recv ^ PN9_Tab[i];
  407. if(tmp!=0)
  408. {
  409. Err_ByteCnt++;
  410. Err_BitCnt += (BitCount_Tab[tmp>>4] + BitCount_Tab[tmp & 0x0F]);
  411. }
  412. }
  413. }
  414. /*********************************************************************
  415. ** RxPacket
  416. *********************************************************************/
  417. void RxPacket_ReadFifo(uint8_t *fuffer, uint16_t len)
  418. {
  419. uint8_t i;
  420. uint8_t recv;
  421. uint8_t tmp;
  422. RxCnt++;
  423. StrobeCMD(CMD_RFR); //RX FIFO address pointer reset
  424. BOARD_A7169_SCS_L();
  425. myRadioSpi_wByte(CMD_FIFO_R); //RX FIFO read command
  426. for(i=0; i <64; i++)
  427. {
  428. fuffer[i] = myRadioSpi_rByte();
  429. }
  430. BOARD_A7169_SCS_H();
  431. }
  432. /*********************************************************************
  433. ** Err_State
  434. *********************************************************************/
  435. void Err_State(void)
  436. {
  437. //ERR display
  438. //Error Proc...
  439. //...
  440. while(1);
  441. }
  442. /*********************************************************************
  443. ** entry_deep_sleep_mode
  444. *********************************************************************/
  445. void entry_deep_sleep_mode(void)
  446. {
  447. StrobeCMD(CMD_RF_RST); //RF reset
  448. A7169_WriteReg(PIN_REG, A7169ConfigBuffer.config[PIN_REG] | 0x0800); //SCMDS=1
  449. A7169_WritePageA(PM_PAGEA, A7169ConfigBuffer.pageA[PM_PAGEA] | 0x0010); //QDS=1
  450. StrobeCMD(CMD_SLEEP); //entry sleep mode
  451. A7169_delayUs(600); //delay 600us for VDD_A shutdown, C load=0.1uF
  452. StrobeCMD(CMD_DEEP_SLEEP); //entry deep sleep mode
  453. A7169_delayUs(200); //delay 200us for VDD_D shutdown, C load=0.1uF
  454. }
  455. /*********************************************************************
  456. ** wake_up_from_deep_sleep_mode
  457. *********************************************************************/
  458. void wake_up_from_deep_sleep_mode(void)
  459. {
  460. StrobeCMD(CMD_STBY); //wake up
  461. A7169_delayMs(2); //delay 2ms for VDD_D stabilized
  462. //InitRF();
  463. }
  464. /*********************************************************************
  465. ** BODF_Detect
  466. *********************************************************************/
  467. uint8_t BODF_Detect(void)
  468. {
  469. uint16_t tmp;
  470. tmp = A7169_ReadPageB(TCODE_PAGEB);
  471. BODF = ((tmp>>12) & 0x01);
  472. if(BODF)
  473. {
  474. return 1;
  475. }
  476. return 0;
  477. }
  478. void A7169_SetConfig(A7169Config_ts config)
  479. {
  480. A7169ConfigBuffer = config;
  481. }