You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

771 regels
20 KiB

  1. /**
  2. *
  3. * \file
  4. *
  5. * \brief WINC3400 Peripherials Application Interface.
  6. *
  7. * Copyright (c) 2017-2018 Microchip Technology Inc. and its subsidiaries.
  8. *
  9. * \asf_license_start
  10. *
  11. * \page License
  12. *
  13. * Subject to your compliance with these terms, you may use Microchip
  14. * software and any derivatives exclusively with Microchip products.
  15. * It is your responsibility to comply with third party license terms applicable
  16. * to your use of third party software (including open source software) that
  17. * may accompany Microchip software.
  18. *
  19. * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
  20. * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
  21. * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
  22. * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
  23. * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
  24. * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
  25. * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
  26. * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
  27. * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
  28. * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
  29. * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
  30. *
  31. * \asf_license_stop
  32. *
  33. */
  34. #ifdef _M2M_ATE_FW_
  35. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  36. INCLUDES
  37. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  38. #include "driver/include/m2m_ate_mode.h"
  39. #include "driver/source/nmasic.h"
  40. #include "driver/source/nmdrv.h"
  41. #include "m2m_hif.h"
  42. #include "driver/source/nmbus.h"
  43. #include "bsp/include/nm_bsp.h"
  44. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  45. MACROS
  46. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  47. #define rInterrupt_CORTUS_0 (0x10a8)
  48. #define rInterrupt_CORTUS_1 (0x10ac)
  49. #define rInterrupt_CORTUS_2 (0x10b0)
  50. #define rBurstTx_NMI_TX_RATE (0x161d00)
  51. #define rBurstTx_NMI_NUM_TX_FRAMES (0x161d04)
  52. #define rBurstTx_NMI_TX_FRAME_LEN (0x161d08)
  53. #define rBurstTx_NMI_TX_CW_PARAM (0x161d0c)
  54. #define rBurstTx_NMI_TX_GAIN (0x161d10)
  55. #define rBurstTx_NMI_TX_DPD_CTRL (0x161d14)
  56. #define rBurstTx_NMI_USE_PMU (0x161d18)
  57. #define rBurstTx_NMI_TEST_CH (0x161d1c)
  58. #define rBurstTx_NMI_TX_PHY_CONT (0x161d20)
  59. #define rBurstTx_NMI_TX_CW_MODE (0x161d24)
  60. #define rBurstTx_NMI_TEST_XO_OFF (0x161d28)
  61. #define rBurstTx_NMI_USE_EFUSE_XO_OFF (0x161d2c)
  62. #define rBurstTx_NMI_MAC_FILTER_ENABLE_DA (0x161d30)
  63. #define rBurstTx_NMI_MAC_ADDR_LO_PEER (0x161d34)
  64. #define rBurstTx_NMI_MAC_ADDR_LO_SELF (0x161d38)
  65. #define rBurstTx_NMI_MAC_ADDR_HI_PEER (0x161d3c)
  66. #define rBurstTx_NMI_MAC_ADDR_HI_SELF (0x161d40)
  67. #define rBurstTx_NMI_RX_PKT_CNT_SUCCESS (0x161d44)
  68. #define rBurstTx_NMI_RX_PKT_CNT_FAIL (0x161d48)
  69. #define rBurstTx_NMI_SET_SELF_MAC_ADDR (0x161d4c)
  70. #define rBurstTx_NMI_MAC_ADDR_LO_SA (0x161d50)
  71. #define rBurstTx_NMI_MAC_ADDR_HI_SA (0x161d54)
  72. #define rBurstTx_NMI_MAC_FILTER_ENABLE_SA (0x161d58)
  73. #define rBurstRx_NMI_RX_ALL_PKTS_CONT (0x9898)
  74. #define rBurstRx_NMI_RX_ERR_PKTS_CONT (0x988c)
  75. #define TX_DGAIN_MAX_NUM_REGS (4)
  76. #define TX_DGAIN_REG_BASE_ADDRESS (0x1240)
  77. #define TX_GAIN_CODE_MAX_NUM_REGS (3)
  78. #define TX_GAIN_CODE_BASE_ADDRESS (0x1250)
  79. #define TX_PA_MAX_NUM_REGS (3)
  80. #define TX_PA_BASE_ADDRESS (0x1e58)
  81. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  82. VARIABLES
  83. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  84. volatile static uint8 gu8AteIsRunning = 0; /*!< ATE firmware status, 1 means ATE is running otherwise stopped */
  85. volatile static uint8 gu8RxState = 0; /*!< RX status, 1 means Rx is running otherwise stopped */
  86. volatile static uint8 gu8TxState = 0; /*!< TX status, 1 means Tx is running otherwise stopped */
  87. volatile static uint32 gaAteFwTxRates[M2M_ATE_MAX_NUM_OF_RATES] =
  88. {
  89. 0x01, 0x02, 0x05, 0x0B, /*B-Rats*/
  90. 0x06, 0x09, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x36, /*G-Rats*/
  91. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87 /*N-Rats*/
  92. };
  93. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  94. STATIC FUNCTIONS
  95. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  96. static void m2m_ate_set_rx_status(uint8 u8Value)
  97. {
  98. gu8RxState = u8Value;
  99. }
  100. static void m2m_ate_set_tx_status(uint8 u8Value)
  101. {
  102. gu8TxState = u8Value;
  103. }
  104. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  105. FUNCTION IMPLEMENTATION
  106. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  107. /*!
  108. @fn \
  109. sint8 m2m_ate_init(void);
  110. @brief
  111. This function used to download ATE firmware from flash and start it
  112. @return
  113. The function SHALL return 0 for success and a negative value otherwise.
  114. */
  115. sint8 m2m_ate_init(uint32 req_serial_number)
  116. {
  117. sint8 s8Ret = M2M_SUCCESS;
  118. uint8 u8WifiMode = M2M_WIFI_MODE_CONFIG;
  119. s8Ret = nm_drv_init(&u8WifiMode, req_serial_number);
  120. return s8Ret;
  121. }
  122. /*!
  123. @fn \
  124. sint8 m2m_ate_deinit(void);
  125. @brief
  126. De-Initialization of ATE firmware mode
  127. @return
  128. The function SHALL return 0 for success and a negative value otherwise.
  129. */
  130. sint8 m2m_ate_deinit(void)
  131. {
  132. return nm_drv_deinit(NULL);
  133. }
  134. /*!
  135. @fn \
  136. sint8 m2m_ate_set_fw_state(uint8);
  137. @brief
  138. This function used to change ATE firmware status from running to stopped or vice versa.
  139. @param [in] u8State
  140. Required state of ATE firmware, one of \ref tenuM2mAteFwState enumeration values.
  141. @return
  142. The function SHALL return 0 for success and a negative value otherwise.
  143. \sa
  144. m2m_ate_init
  145. */
  146. sint8 m2m_ate_set_fw_state(uint8 u8State)
  147. {
  148. sint8 s8Ret = M2M_SUCCESS;
  149. uint32_t u32Val = 0;
  150. if((M2M_ATE_FW_STATE_STOP == u8State) && (M2M_ATE_FW_STATE_STOP != gu8AteIsRunning))
  151. {
  152. u32Val = nm_read_reg(rNMI_GLB_RESET);
  153. u32Val &= ~(1 << 10);
  154. s8Ret = nm_write_reg(rNMI_GLB_RESET, u32Val);
  155. gu8AteIsRunning = M2M_ATE_FW_STATE_STOP;
  156. }
  157. else if((M2M_ATE_FW_STATE_RUN == u8State) && (M2M_ATE_FW_STATE_RUN != gu8AteIsRunning))
  158. {
  159. /* 0x1118[0]=0 at power-on-reset: pad-based control. */
  160. /* Switch cortus reset register to register control. 0x1118[0]=1. */
  161. u32Val = nm_read_reg(rNMI_BOOT_RESET_MUX);
  162. u32Val |= (1 << 0);
  163. s8Ret = nm_write_reg(rNMI_BOOT_RESET_MUX, u32Val);
  164. if(M2M_SUCCESS != s8Ret)
  165. {
  166. goto __EXIT;
  167. }
  168. /**
  169. Write the firmware download complete magic value 0x10ADD09E at
  170. location 0xFFFF000C (Cortus map) or C000C (AHB map).
  171. This will let the boot-rom code execute from RAM.
  172. **/
  173. s8Ret = nm_write_reg(0xc0000, 0x71);
  174. if(M2M_SUCCESS != s8Ret)
  175. {
  176. goto __EXIT;
  177. }
  178. u32Val = nm_read_reg(rNMI_GLB_RESET);
  179. if((u32Val & (1ul << 10)) == (1ul << 10))
  180. {
  181. u32Val &= ~(1ul << 10);
  182. s8Ret = nm_write_reg(rNMI_GLB_RESET, u32Val);
  183. if(M2M_SUCCESS != s8Ret)
  184. {
  185. goto __EXIT;
  186. }
  187. }
  188. u32Val |= (1ul << 10);
  189. s8Ret = nm_write_reg(rNMI_GLB_RESET, u32Val);
  190. if(M2M_SUCCESS != s8Ret)
  191. {
  192. goto __EXIT;
  193. }
  194. gu8AteIsRunning = M2M_ATE_FW_STATE_RUN;
  195. }
  196. else
  197. {
  198. s8Ret = M2M_ATE_ERR_UNHANDLED_CASE;
  199. }
  200. __EXIT:
  201. if((M2M_SUCCESS == s8Ret) && (M2M_ATE_FW_STATE_RUN == gu8AteIsRunning))
  202. {
  203. nm_bsp_sleep(500); /*wait for ATE firmware start up*/
  204. }
  205. return s8Ret;
  206. }
  207. /*!
  208. @fn \
  209. sint8 m2m_ate_get_fw_state(uint8);
  210. @brief
  211. This function used to return status of ATE firmware.
  212. @return
  213. The function SHALL return status of ATE firmware, one of \ref tenuM2mAteFwState enumeration values.
  214. \sa
  215. m2m_ate_init, m2m_ate_set_fw_state
  216. */
  217. sint8 m2m_ate_get_fw_state(void)
  218. {
  219. return gu8AteIsRunning;
  220. }
  221. /*!
  222. @fn \
  223. uint32 m2m_ate_get_tx_rate(uint8);
  224. @brief
  225. This function used to return value of TX rate required by application developer.
  226. @param [in] u8Index
  227. Index of required rate , one of \ref tenuM2mAteTxIndexOfRates enumeration values.
  228. @return
  229. The function SHALL return 0 for in case of failure otherwise selected rate value.
  230. \sa
  231. tenuM2mAteTxIndexOfRates
  232. */
  233. uint32 m2m_ate_get_tx_rate(uint8 u8Index)
  234. {
  235. if(M2M_ATE_MAX_NUM_OF_RATES <= u8Index)
  236. {
  237. return 0;
  238. }
  239. return gaAteFwTxRates[u8Index];
  240. }
  241. /*!
  242. @fn \
  243. sint8 m2m_ate_get_tx_status(void);
  244. @brief
  245. This function used to return status of TX test case either running or stopped.
  246. @return
  247. The function SHALL return status of ATE firmware, 1 if TX is running otherwise 0.
  248. \sa
  249. m2m_ate_start_tx, m2m_ate_stop_tx
  250. */
  251. sint8 m2m_ate_get_tx_status(void)
  252. {
  253. return gu8TxState;
  254. }
  255. /*!
  256. @fn \
  257. sint8 m2m_ate_start_tx(tstrM2mAteTx *)
  258. @brief
  259. This function used to start TX test case.
  260. @param [in] strM2mAteTx
  261. Type of \ref tstrM2mAteTx, with the values required to enable TX test case. You must use \ref m2m_ate_init first.
  262. @return
  263. The function SHALL return 0 for success and a negative value otherwise.
  264. \sa
  265. m2m_ate_init, m2m_ate_stop_tx, m2m_ate_get_tx_status
  266. */
  267. sint8 m2m_ate_start_tx(tstrM2mAteTx * strM2mAteTx)
  268. {
  269. sint8 s8Ret = M2M_SUCCESS;
  270. uint8 u8LoopCntr = 0;
  271. uint32_t val32;
  272. if(NULL == strM2mAteTx)
  273. {
  274. s8Ret = M2M_ATE_ERR_VALIDATE;
  275. goto __EXIT;
  276. }
  277. if(0 != m2m_ate_get_tx_status())
  278. {
  279. s8Ret = M2M_ATE_ERR_TX_ALREADY_RUNNING;
  280. goto __EXIT;
  281. }
  282. if(0 != m2m_ate_get_rx_status())
  283. {
  284. s8Ret = M2M_ATE_ERR_RX_ALREADY_RUNNING;
  285. goto __EXIT;
  286. }
  287. if( (strM2mAteTx->channel_num < M2M_ATE_CHANNEL_1) ||
  288. (strM2mAteTx->channel_num > M2M_ATE_CHANNEL_14) ||
  289. (strM2mAteTx->tx_gain_sel < M2M_ATE_TX_GAIN_DYNAMIC) ||
  290. (strM2mAteTx->tx_gain_sel > M2M_ATE_TX_GAIN_TELEC) ||
  291. (strM2mAteTx->frame_len > M2M_ATE_MAX_FRAME_LENGTH) ||
  292. (strM2mAteTx->frame_len < M2M_ATE_MIN_FRAME_LENGTH)
  293. )
  294. {
  295. s8Ret = M2M_ATE_ERR_VALIDATE;
  296. goto __EXIT;
  297. }
  298. if( (strM2mAteTx->duty_cycle < M2M_ATE_TX_DUTY_MAX_VALUE /*1*/) ||
  299. (strM2mAteTx->duty_cycle > M2M_ATE_TX_DUTY_MIN_VALUE /*10*/ ) ||
  300. (strM2mAteTx->dpd_ctrl < M2M_ATE_TX_DPD_DYNAMIC) ||
  301. (strM2mAteTx->dpd_ctrl > M2M_ATE_TX_DPD_ENABLED) ||
  302. (strM2mAteTx->use_pmu < M2M_ATE_PMU_DISBLE) ||
  303. (strM2mAteTx->use_pmu > M2M_ATE_PMU_ENABLE) ||
  304. (strM2mAteTx->phy_burst_tx < M2M_ATE_TX_SRC_MAC) ||
  305. (strM2mAteTx->phy_burst_tx > M2M_ATE_TX_SRC_PHY) ||
  306. (strM2mAteTx->cw_tx < M2M_ATE_TX_MODE_NORM) ||
  307. (strM2mAteTx->cw_tx > M2M_ATE_TX_MODE_CW)
  308. )
  309. {
  310. s8Ret = M2M_ATE_ERR_VALIDATE;
  311. goto __EXIT;
  312. }
  313. for(u8LoopCntr=0; u8LoopCntr<M2M_ATE_MAX_NUM_OF_RATES; u8LoopCntr++)
  314. {
  315. if(gaAteFwTxRates[u8LoopCntr] == strM2mAteTx->data_rate)
  316. {
  317. break;
  318. }
  319. }
  320. if(M2M_ATE_MAX_NUM_OF_RATES == u8LoopCntr)
  321. {
  322. s8Ret = M2M_ATE_ERR_VALIDATE;
  323. goto __EXIT;
  324. }
  325. s8Ret += nm_write_reg(rBurstTx_NMI_USE_PMU, strM2mAteTx->use_pmu);
  326. s8Ret += nm_write_reg(rBurstTx_NMI_TX_PHY_CONT, strM2mAteTx->phy_burst_tx);
  327. s8Ret += nm_write_reg(rBurstTx_NMI_NUM_TX_FRAMES, strM2mAteTx->num_frames);
  328. s8Ret += nm_write_reg(rBurstTx_NMI_TX_GAIN, strM2mAteTx->tx_gain_sel);
  329. s8Ret += nm_write_reg(rBurstTx_NMI_TEST_CH, strM2mAteTx->channel_num);
  330. s8Ret += nm_write_reg(rBurstTx_NMI_TX_FRAME_LEN, strM2mAteTx->frame_len);
  331. s8Ret += nm_write_reg(rBurstTx_NMI_TX_CW_PARAM, strM2mAteTx->duty_cycle);
  332. s8Ret += nm_write_reg(rBurstTx_NMI_TX_DPD_CTRL, strM2mAteTx->dpd_ctrl);
  333. s8Ret += nm_write_reg(rBurstTx_NMI_TX_RATE, strM2mAteTx->data_rate);
  334. s8Ret += nm_write_reg(rBurstTx_NMI_TX_CW_MODE, strM2mAteTx->cw_tx);
  335. s8Ret += nm_write_reg(rBurstTx_NMI_TEST_XO_OFF, strM2mAteTx->xo_offset_x1000);
  336. s8Ret += nm_write_reg(rBurstTx_NMI_USE_EFUSE_XO_OFF, strM2mAteTx->use_efuse_xo_offset);
  337. val32 = strM2mAteTx->peer_mac_addr[5] << 0;
  338. val32 |= strM2mAteTx->peer_mac_addr[4] << 8;
  339. val32 |= strM2mAteTx->peer_mac_addr[3] << 16;
  340. nm_write_reg(rBurstTx_NMI_MAC_ADDR_LO_PEER, val32 );
  341. val32 = strM2mAteTx->peer_mac_addr[2] << 0;
  342. val32 |= strM2mAteTx->peer_mac_addr[1] << 8;
  343. val32 |= strM2mAteTx->peer_mac_addr[0] << 16;
  344. nm_write_reg(rBurstTx_NMI_MAC_ADDR_HI_PEER, val32 );
  345. if(M2M_SUCCESS == s8Ret)
  346. {
  347. s8Ret += nm_write_reg(rInterrupt_CORTUS_0, 1); /*Interrupt Cortus*/
  348. m2m_ate_set_tx_status(1);
  349. nm_bsp_sleep(200); /*Recommended*/
  350. }
  351. __EXIT:
  352. return s8Ret;
  353. }
  354. /*!
  355. @fn \
  356. sint8 m2m_ate_stop_tx(void)
  357. @brief
  358. This function used to stop TX test case.
  359. @return
  360. The function SHALL return 0 for success and a negative value otherwise.
  361. \sa
  362. m2m_ate_init, m2m_ate_start_tx, m2m_ate_get_tx_status
  363. */
  364. sint8 m2m_ate_stop_tx(void)
  365. {
  366. sint8 s8Ret = M2M_SUCCESS;
  367. s8Ret = nm_write_reg(rInterrupt_CORTUS_1, 1);
  368. if(M2M_SUCCESS == s8Ret)
  369. {
  370. m2m_ate_set_tx_status(0);
  371. }
  372. return s8Ret;
  373. }
  374. /*!
  375. @fn \
  376. sint8 m2m_ate_get_rx_status(uint8);
  377. @brief
  378. This function used to return status of RX test case either running or stopped.
  379. @return
  380. The function SHALL return status of ATE firmware, 1 if RX is running otherwise 0.
  381. \sa
  382. m2m_ate_start_rx, m2m_ate_stop_rx
  383. */
  384. sint8 m2m_ate_get_rx_status(void)
  385. {
  386. return gu8RxState;
  387. }
  388. /*!
  389. @fn \
  390. sint8 m2m_ate_start_rx(tstrM2mAteRx *)
  391. @brief
  392. This function used to start RX test case.
  393. @param [in] strM2mAteRx
  394. Type of \ref tstrM2mAteRx, with the values required to enable RX test case. You must use \ref m2m_ate_init first.
  395. @return
  396. The function SHALL return 0 for success and a negative value otherwise.
  397. \sa
  398. m2m_ate_init, m2m_ate_stop_rx, m2m_ate_get_rx_status
  399. */
  400. sint8 m2m_ate_start_rx(tstrM2mAteRx * strM2mAteRxStr)
  401. {
  402. sint8 s8Ret = M2M_SUCCESS;
  403. uint32 val32;
  404. if(NULL == strM2mAteRxStr)
  405. {
  406. s8Ret = M2M_ATE_ERR_VALIDATE;
  407. goto __EXIT;
  408. }
  409. if(0 != m2m_ate_get_tx_status())
  410. {
  411. s8Ret = M2M_ATE_ERR_TX_ALREADY_RUNNING;
  412. goto __EXIT;
  413. }
  414. if(0 != m2m_ate_get_rx_status())
  415. {
  416. s8Ret = M2M_ATE_ERR_RX_ALREADY_RUNNING;
  417. goto __EXIT;
  418. }
  419. if( (strM2mAteRxStr->channel_num < M2M_ATE_CHANNEL_1) ||
  420. (strM2mAteRxStr->channel_num > M2M_ATE_CHANNEL_14)||
  421. (strM2mAteRxStr->use_pmu < M2M_ATE_PMU_DISBLE) ||
  422. (strM2mAteRxStr->use_pmu > M2M_ATE_PMU_ENABLE)
  423. )
  424. {
  425. s8Ret = M2M_ATE_ERR_VALIDATE;
  426. goto __EXIT;
  427. }
  428. s8Ret += nm_write_reg(rBurstTx_NMI_TEST_CH, strM2mAteRxStr->channel_num);
  429. s8Ret += nm_write_reg(rBurstTx_NMI_USE_PMU, strM2mAteRxStr->use_pmu);
  430. s8Ret += nm_write_reg(rBurstTx_NMI_TEST_XO_OFF, strM2mAteRxStr->xo_offset_x1000);
  431. s8Ret += nm_write_reg(rBurstTx_NMI_USE_EFUSE_XO_OFF, strM2mAteRxStr->use_efuse_xo_offset);
  432. if(strM2mAteRxStr->override_self_mac_addr)
  433. {
  434. val32 = strM2mAteRxStr->self_mac_addr[5] << 0;
  435. val32 |= strM2mAteRxStr->self_mac_addr[4] << 8;
  436. val32 |= strM2mAteRxStr->self_mac_addr[3] << 16;
  437. nm_write_reg(rBurstTx_NMI_MAC_ADDR_LO_SELF, val32 );
  438. val32 = strM2mAteRxStr->self_mac_addr[2] << 0;
  439. val32 |= strM2mAteRxStr->self_mac_addr[1] << 8;
  440. val32 |= strM2mAteRxStr->self_mac_addr[0] << 16;
  441. nm_write_reg(rBurstTx_NMI_MAC_ADDR_HI_SELF, val32 );
  442. }
  443. if(strM2mAteRxStr->mac_filter_en_sa)
  444. {
  445. val32 = strM2mAteRxStr->sa_mac_addr[5] << 0;
  446. val32 |= strM2mAteRxStr->sa_mac_addr[4] << 8;
  447. val32 |= strM2mAteRxStr->sa_mac_addr[3] << 16;
  448. nm_write_reg(rBurstTx_NMI_MAC_ADDR_LO_SA, val32 );
  449. val32 = strM2mAteRxStr->sa_mac_addr[2] << 0;
  450. val32 |= strM2mAteRxStr->sa_mac_addr[1] << 8;
  451. val32 |= strM2mAteRxStr->sa_mac_addr[0] << 16;
  452. nm_write_reg(rBurstTx_NMI_MAC_ADDR_HI_SA, val32 );
  453. }
  454. nm_write_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_DA, strM2mAteRxStr->mac_filter_en_da);
  455. nm_write_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_SA, strM2mAteRxStr->mac_filter_en_sa);
  456. nm_write_reg(rBurstTx_NMI_SET_SELF_MAC_ADDR, strM2mAteRxStr->override_self_mac_addr);
  457. if(M2M_SUCCESS == s8Ret)
  458. {
  459. s8Ret += nm_write_reg(rInterrupt_CORTUS_2, 1); /*Interrupt Cortus*/
  460. m2m_ate_set_rx_status(1);
  461. nm_bsp_sleep(10); /*Recommended*/
  462. }
  463. __EXIT:
  464. return s8Ret;
  465. }
  466. /*!
  467. @fn \
  468. sint8 m2m_ate_stop_rx(void)
  469. @brief
  470. This function used to stop RX test case.
  471. @return
  472. The function SHALL return 0 for success and a negative value otherwise.
  473. \sa
  474. m2m_ate_init, m2m_ate_start_rx, m2m_ate_get_rx_status
  475. */
  476. sint8 m2m_ate_stop_rx(void)
  477. {
  478. m2m_ate_set_rx_status(0);
  479. nm_bsp_sleep(200); /*Recommended*/
  480. return M2M_SUCCESS;
  481. }
  482. /*!
  483. @fn \
  484. sint8 m2m_ate_read_rx_status(tstrM2mAteRxStatus *)
  485. @brief
  486. This function used to read RX statistics from ATE firmware.
  487. @param [out] strM2mAteRxStatus
  488. Type of \ref tstrM2mAteRxStatus used to save statistics of RX test case. You must use \ref m2m_ate_start_rx first.
  489. @return
  490. The function SHALL return 0 for success and a negative value otherwise.
  491. \sa
  492. m2m_ate_init, m2m_ate_start_rx
  493. */
  494. sint8 m2m_ate_read_rx_status(tstrM2mAteRxStatus *strM2mAteRxStatus)
  495. {
  496. sint8 s8Ret = M2M_SUCCESS;
  497. if(NULL == strM2mAteRxStatus)
  498. {
  499. s8Ret = M2M_ATE_ERR_VALIDATE;
  500. goto __EXIT;
  501. }
  502. if(0 != m2m_ate_get_tx_status())
  503. {
  504. s8Ret = M2M_ATE_ERR_TX_ALREADY_RUNNING;
  505. goto __EXIT;
  506. }
  507. if (nm_read_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_DA) || nm_read_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_SA))
  508. {
  509. strM2mAteRxStatus->num_rx_pkts = nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_SUCCESS) + nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_FAIL);
  510. strM2mAteRxStatus->num_good_pkts = nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_SUCCESS);
  511. strM2mAteRxStatus->num_err_pkts = nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_FAIL);
  512. }
  513. else
  514. {
  515. strM2mAteRxStatus->num_rx_pkts = nm_read_reg(rBurstRx_NMI_RX_ALL_PKTS_CONT) + nm_read_reg(0x989c);
  516. strM2mAteRxStatus->num_err_pkts = nm_read_reg(rBurstRx_NMI_RX_ERR_PKTS_CONT);
  517. strM2mAteRxStatus->num_good_pkts = strM2mAteRxStatus->num_rx_pkts - strM2mAteRxStatus->num_err_pkts;
  518. }
  519. __EXIT:
  520. return s8Ret;
  521. }
  522. /*!
  523. @fn \
  524. sint8 m2m_ate_set_dig_gain(double dGaindB)
  525. @brief
  526. This function is used to set the digital gain
  527. @param [in] double dGaindB
  528. The digital gain value required to be set.
  529. @return
  530. The function SHALL return 0 for success and a negative value otherwise.
  531. */
  532. sint8 m2m_ate_set_dig_gain(double dGaindB)
  533. {
  534. uint32_t dGain, val32;
  535. dGain = (uint32_t)(pow(10, dGaindB/20.0) * 1024.0);
  536. val32 = nm_read_reg(0x160cd0);
  537. val32 &= ~(0x1ffful << 0);
  538. val32 |= (((uint32_t)dGain) << 0);
  539. nm_write_reg(0x160cd0, val32);
  540. return M2M_SUCCESS;
  541. }
  542. /*!
  543. @fn \
  544. sint8 m2m_ate_get_dig_gain(double * pdGaindB)
  545. @brief
  546. This function is used to get the digital gain
  547. @param [out] double * pdGaindB
  548. The retrieved digital gain value obtained from HW registers.
  549. @return
  550. The function SHALL return 0 for success and a negative value otherwise.
  551. */
  552. sint8 m2m_ate_get_dig_gain(double * pdGaindB)
  553. {
  554. uint32 dGain, val32;
  555. if(!pdGaindB) return M2M_ERR_INVALID_ARG;
  556. val32 = nm_read_reg(0x160cd0);
  557. dGain = (val32 >> 0) & 0x1ffful;
  558. *pdGaindB = 20.0*log10((double)dGain / 1024.0);
  559. return M2M_SUCCESS;
  560. }
  561. /*!
  562. @fn \
  563. sint8 m2m_ate_get_pa_gain(uint32 *paGain)
  564. @brief
  565. This function is used to get the pa gain
  566. @param [out] uint32 *paGain
  567. The retrieved pa gain value obtained from HW registers.
  568. @return
  569. The function SHALL return 0 for success and a negative value otherwise.
  570. */
  571. sint8 m2m_ate_get_pa_gain(uint32 *paGain)
  572. {
  573. uint32 val32;
  574. if(!paGain)
  575. return M2M_ERR_INVALID_ARG;
  576. val32 = nm_read_reg(0x1e9c);
  577. * paGain = (val32 >> 8) & 0x3f;
  578. return M2M_SUCCESS;
  579. }
  580. /*!
  581. @fn \
  582. sint8 m2m_ate_get_ppa_gain(uint32 * ppaGain)
  583. @brief
  584. This function is used to get the ppa gain
  585. @param [out] uint32 * ppaGain
  586. The retrieved ppa gain value obtained from HW registers.
  587. @return
  588. The function SHALL return 0 for success and a negative value otherwise.
  589. */
  590. sint8 m2m_ate_get_ppa_gain(uint32 * ppaGain)
  591. {
  592. uint32 val32;
  593. if(!ppaGain) return M2M_ERR_INVALID_ARG;
  594. val32 = nm_read_reg(0x1ea0);
  595. * ppaGain = (val32 >> 5) & 0x7;
  596. return M2M_SUCCESS;
  597. }
  598. /*!
  599. @fn \
  600. sint8 m2m_ate_get_tot_gain(double * pTotGaindB)
  601. @brief
  602. This function is used to calculate the total gain
  603. @param [out] double * pTotGaindB
  604. The retrieved total gain value obtained from calculations made based on the digital gain, pa and ppa gain values.
  605. @return
  606. The function SHALL return 0 for success and a negative value otherwise.
  607. */
  608. sint8 m2m_ate_get_tot_gain(double * pTotGaindB)
  609. {
  610. double totGaindB, dGaindB;
  611. uint32 paGain,ppaGain,m_cmbPAGainStep,m_cmbPPAGainStep;
  612. m2m_ate_get_pa_gain(&paGain);
  613. m2m_ate_get_ppa_gain(&ppaGain);
  614. m2m_ate_get_dig_gain(&dGaindB);
  615. switch(paGain){
  616. case 0x1:
  617. m_cmbPAGainStep = 5;
  618. break;
  619. case 0x3:
  620. m_cmbPAGainStep = 4;
  621. break;
  622. case 0x7:
  623. m_cmbPAGainStep = 3;
  624. break;
  625. case 0xf:
  626. m_cmbPAGainStep = 2;
  627. break;
  628. case 0x1f:
  629. m_cmbPAGainStep = 1;
  630. break;
  631. case 0x3f:
  632. m_cmbPAGainStep = 0;
  633. break;
  634. default:
  635. m_cmbPAGainStep = 0;
  636. break;
  637. }
  638. switch(ppaGain){
  639. case 0x1:
  640. m_cmbPPAGainStep = 2;
  641. break;
  642. case 0x3:
  643. m_cmbPPAGainStep = 1;
  644. break;
  645. case 0x7:
  646. m_cmbPPAGainStep = 0;
  647. break;
  648. default:
  649. m_cmbPPAGainStep = 3;
  650. break;
  651. }
  652. totGaindB = dGaindB + 18 - m_cmbPAGainStep*3;
  653. totGaindB += 9 - m_cmbPPAGainStep*3;
  654. *pTotGaindB = totGaindB;
  655. return M2M_SUCCESS;
  656. }
  657. #endif //_M2M_ATE_FW_