Delta / NNN50_WIFI_API

Dependents:   NNN50_CE_Test_UDP NNN50_linux_firmware NNN50_SoftAP_HelloWorld NNN50_BLEWIFISensor ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers m2m_ate_mode.c Source File

m2m_ate_mode.c

Go to the documentation of this file.
00001 /**
00002  *
00003  * \file
00004  *
00005  * \brief NMC1500 Peripherials Application Interface.
00006  *
00007  * Copyright (c) 2016-2017 Atmel Corporation. All rights reserved.
00008  *
00009  * \asf_license_start
00010  *
00011  * \page License
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright notice,
00020  *    this list of conditions and the following disclaimer in the documentation
00021  *    and/or other materials provided with the distribution.
00022  *
00023  * 3. The name of Atmel may not be used to endorse or promote products derived
00024  *    from this software without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
00027  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00028  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00029  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
00030  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00032  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00034  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00035  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  * POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * \asf_license_stop
00039  *
00040  */
00041 
00042 #ifdef _M2M_ATE_FW_
00043 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
00044 INCLUDES
00045 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
00046 #include "driver\include\m2m_ate_mode.h"
00047 #include "driver\source\nmasic.h"
00048 #include "driver\source\nmdrv.h"
00049 #include "m2m_hif.h"
00050 #include "driver\source\nmbus.h"
00051 #include "bsp\include\nm_bsp.h"
00052 #include "math.h"
00053 
00054 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
00055 MACROS
00056 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
00057 #define rInterrupt_CORTUS_0             (0x10a8)
00058 #define rInterrupt_CORTUS_1             (0x10ac)
00059 #define rInterrupt_CORTUS_2             (0x10b0)
00060 
00061 #define rBurstTx_NMI_TX_RATE                (0x161d00)
00062 #define rBurstTx_NMI_NUM_TX_FRAMES          (0x161d04)
00063 #define rBurstTx_NMI_TX_FRAME_LEN           (0x161d08)
00064 #define rBurstTx_NMI_TX_CW_PARAM            (0x161d0c)
00065 #define rBurstTx_NMI_TX_GAIN                (0x161d10)
00066 #define rBurstTx_NMI_TX_DPD_CTRL            (0x161d14)
00067 #define rBurstTx_NMI_USE_PMU                (0x161d18)
00068 #define rBurstTx_NMI_TEST_CH                (0x161d1c)
00069 #define rBurstTx_NMI_TX_PHY_CONT            (0x161d20)
00070 #define rBurstTx_NMI_TX_CW_MODE             (0x161d24)
00071 #define rBurstTx_NMI_TEST_XO_OFF            (0x161d28)
00072 #define rBurstTx_NMI_USE_EFUSE_XO_OFF       (0x161d2c)
00073 
00074 #define rBurstTx_NMI_MAC_FILTER_ENABLE_DA   (0x161d30)
00075 #define rBurstTx_NMI_MAC_ADDR_LO_PEER       (0x161d34)
00076 #define rBurstTx_NMI_MAC_ADDR_LO_SELF       (0x161d38)
00077 #define rBurstTx_NMI_MAC_ADDR_HI_PEER       (0x161d3c)
00078 #define rBurstTx_NMI_MAC_ADDR_HI_SELF       (0x161d40)
00079 #define rBurstTx_NMI_RX_PKT_CNT_SUCCESS     (0x161d44)
00080 #define rBurstTx_NMI_RX_PKT_CNT_FAIL        (0x161d48)
00081 #define rBurstTx_NMI_SET_SELF_MAC_ADDR      (0x161d4c)
00082 #define rBurstTx_NMI_MAC_ADDR_LO_SA         (0x161d50)
00083 #define rBurstTx_NMI_MAC_ADDR_HI_SA         (0x161d54)
00084 #define rBurstTx_NMI_MAC_FILTER_ENABLE_SA   (0x161d58)
00085 
00086 #define rBurstRx_NMI_RX_ALL_PKTS_CONT   (0x9898)
00087 #define rBurstRx_NMI_RX_ERR_PKTS_CONT   (0x988c)
00088 
00089 #define TX_DGAIN_MAX_NUM_REGS           (4)
00090 #define TX_DGAIN_REG_BASE_ADDRESS       (0x1240)
00091 #define TX_GAIN_CODE_MAX_NUM_REGS       (3)
00092 #define TX_GAIN_CODE_BASE_ADDRESS       (0x1250)
00093 #define TX_PA_MAX_NUM_REGS              (3)
00094 #define TX_PA_BASE_ADDRESS              (0x1e58)
00095 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
00096 VARIABLES
00097 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
00098 volatile static uint8   gu8AteIsRunning  = 0;    /*!< ATE firmware status, 1 means ATE is running otherwise stopped */
00099 volatile static uint8   gu8RxState       = 0;    /*!< RX status, 1 means Rx is running otherwise stopped */
00100 volatile static uint8   gu8TxState       = 0;    /*!< TX status, 1 means Tx is running otherwise stopped */
00101 volatile static uint32  gaAteFwTxRates[M2M_ATE_MAX_NUM_OF_RATES] =
00102 {
00103     0x01, 0x02, 0x05, 0x0B,                         /*B-Rats*/
00104     0x06, 0x09, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x36, /*G-Rats*/
00105     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87  /*N-Rats*/
00106 };
00107 
00108 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
00109 STATIC FUNCTIONS
00110 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
00111 static void m2m_ate_set_rx_status(uint8 u8Value)
00112 {
00113     gu8RxState  = u8Value;
00114 }
00115 
00116 static void m2m_ate_set_tx_status(uint8 u8Value)
00117 {
00118     gu8TxState  = u8Value;
00119 }
00120 
00121 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
00122 FUNCTION IMPLEMENTATION
00123 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
00124 /*!
00125 @fn \
00126     sint8 m2m_ate_init(void);
00127 
00128 @brief
00129     This function used to download ATE firmware from flash and start it
00130 
00131 @return
00132     The function SHALL return 0 for success and a negative value otherwise.
00133 */
00134 sint8 m2m_ate_init(void)
00135 {
00136     sint8 s8Ret = M2M_SUCCESS;
00137     uint8 u8WifiMode = M2M_WIFI_MODE_ATE_HIGH ;
00138     
00139     s8Ret = nm_drv_init (&u8WifiMode);
00140     
00141     return s8Ret;
00142 }
00143 
00144 /*!
00145 @fn \
00146     sint8 m2m_ate_init(tstrM2mAteInit *pstrInit);
00147 
00148 @brief
00149     This function used to download ATE firmware from flash and start it
00150 
00151 @return
00152     The function SHALL return 0 for success and a negative value otherwise.
00153 */
00154 sint8 m2m_ate_init_param(tstrM2mAteInit *pstrInit)
00155 {
00156     sint8 s8Ret = M2M_SUCCESS;
00157     
00158     s8Ret = nm_drv_init ((void*)&pstrInit->u8RxPwrMode);
00159     
00160     return s8Ret;
00161 }
00162 
00163 /*!
00164 @fn \
00165     sint8 m2m_ate_deinit(void);
00166 
00167 @brief
00168     De-Initialization of ATE firmware mode 
00169 
00170 @return
00171     The function SHALL return 0 for success and a negative value otherwise.
00172 */
00173 sint8 m2m_ate_deinit(void)
00174 {
00175     return nm_drv_deinit(NULL);
00176 }
00177 
00178 /*!
00179 @fn \
00180     sint8 m2m_ate_set_fw_state(uint8);
00181 
00182 @brief
00183     This function used to change ATE firmware status from running to stopped or vice versa.
00184 
00185 @param [in] u8State
00186         Required state of ATE firmware, one of \ref tenuM2mAteFwState enumeration values.
00187 @return
00188     The function SHALL return 0 for success and a negative value otherwise.
00189 \sa
00190     m2m_ate_init
00191 */
00192 sint8 m2m_ate_set_fw_state(uint8 u8State)
00193 {
00194     sint8       s8Ret   = M2M_SUCCESS;
00195     uint32_t    u32Val  = 0;
00196     
00197     if((M2M_ATE_FW_STATE_STOP  == u8State) && (M2M_ATE_FW_STATE_STOP  != gu8AteIsRunning ))
00198     {
00199         u32Val = nm_read_reg(rNMI_GLB_RESET);
00200         u32Val &= ~(1 << 10);
00201         s8Ret = nm_write_reg(rNMI_GLB_RESET, u32Val);
00202         gu8AteIsRunning  = M2M_ATE_FW_STATE_STOP ;
00203     }
00204     else if((M2M_ATE_FW_STATE_RUN  == u8State) && (M2M_ATE_FW_STATE_RUN  != gu8AteIsRunning ))
00205     {
00206         /* 0x1118[0]=0 at power-on-reset: pad-based control. */
00207         /* Switch cortus reset register to register control. 0x1118[0]=1. */
00208         u32Val = nm_read_reg(rNMI_BOOT_RESET_MUX);
00209         u32Val |= (1 << 0);
00210         s8Ret = nm_write_reg(rNMI_BOOT_RESET_MUX, u32Val);
00211         if(M2M_SUCCESS != s8Ret) 
00212         {
00213             goto __EXIT;
00214         }
00215         /**
00216         Write the firmware download complete magic value 0x10ADD09E at
00217         location 0xFFFF000C (Cortus map) or C000C (AHB map).
00218         This will let the boot-rom code execute from RAM.
00219         **/
00220         s8Ret = nm_write_reg(0xc0000, 0x71);
00221         if(M2M_SUCCESS != s8Ret) 
00222         {
00223             goto __EXIT;
00224         }
00225 
00226         u32Val = nm_read_reg(rNMI_GLB_RESET);
00227         if((u32Val & (1ul << 10)) == (1ul << 10)) 
00228         {
00229             u32Val &= ~(1ul << 10);
00230             s8Ret = nm_write_reg(rNMI_GLB_RESET, u32Val);
00231             if(M2M_SUCCESS != s8Ret) 
00232             {
00233                 goto __EXIT;
00234             }
00235         }
00236         
00237         u32Val |= (1ul << 10);
00238         s8Ret = nm_write_reg(rNMI_GLB_RESET, u32Val);
00239         if(M2M_SUCCESS != s8Ret) 
00240         {
00241             goto __EXIT;
00242         }
00243         gu8AteIsRunning  = M2M_ATE_FW_STATE_RUN ;
00244     }
00245     else
00246     {
00247         s8Ret = M2M_ATE_ERR_UNHANDLED_CASE;
00248     }
00249     
00250 __EXIT:
00251     if((M2M_SUCCESS == s8Ret) && (M2M_ATE_FW_STATE_RUN  == gu8AteIsRunning ))
00252     {
00253         nm_bsp_sleep(500);  /*wait for ATE firmware start up*/
00254     }
00255     return s8Ret;
00256 }
00257 
00258 /*!
00259 @fn \
00260     sint8 m2m_ate_get_fw_state(uint8);
00261 
00262 @brief
00263     This function used to return status of ATE firmware.
00264 
00265 @return
00266     The function SHALL return status of ATE firmware, one of \ref tenuM2mAteFwState enumeration values.
00267 \sa
00268     m2m_ate_init, m2m_ate_set_fw_state
00269 */
00270 sint8 m2m_ate_get_fw_state(void)
00271 {
00272     return gu8AteIsRunning ;
00273 }
00274 
00275 /*!
00276 @fn \
00277     uint32 m2m_ate_get_tx_rate(uint8);
00278 
00279 @brief
00280     This function used to return value of TX rate required by application developer.
00281 
00282 @param [in] u8Index
00283         Index of required rate , one of \ref tenuM2mAteTxIndexOfRates enumeration values.
00284 @return
00285     The function SHALL return 0 for in case of failure otherwise selected rate value.
00286 \sa
00287     tenuM2mAteTxIndexOfRates
00288 */
00289 uint32 m2m_ate_get_tx_rate(uint8 u8Index)
00290 {
00291     if(M2M_ATE_MAX_NUM_OF_RATES <= u8Index)
00292     {
00293         return 0;
00294     }
00295     return gaAteFwTxRates[u8Index];
00296 }
00297 
00298 /*!
00299 @fn \
00300     sint8 m2m_ate_get_tx_status(void);
00301 
00302 @brief
00303     This function used to return status of TX test case either running or stopped.
00304 
00305 @return
00306     The function SHALL return status of ATE firmware, 1 if TX is running otherwise 0.
00307 \sa
00308     m2m_ate_start_tx, m2m_ate_stop_tx
00309 */
00310 sint8 m2m_ate_get_tx_status(void)
00311 {
00312     return gu8TxState ;
00313 }
00314 
00315 /*!
00316 @fn \
00317     sint8 m2m_ate_start_tx(tstrM2mAteTx *)
00318 
00319 @brief
00320     This function used to start TX test case.
00321 
00322 @param [in] strM2mAteTx
00323         Type of \ref tstrM2mAteTx, with the values required to enable TX test case. You must use \ref m2m_ate_init first.
00324 @return
00325     The function SHALL return 0 for success and a negative value otherwise.
00326 \sa
00327     m2m_ate_init, m2m_ate_stop_tx, m2m_ate_get_tx_status
00328 */
00329 sint8 m2m_ate_start_tx(tstrM2mAteTx * strM2mAteTx)
00330 {
00331     sint8       s8Ret = M2M_SUCCESS;
00332     uint8   u8LoopCntr = 0;
00333     uint32_t    val32;
00334 
00335     
00336     if(NULL == strM2mAteTx) 
00337     {
00338         s8Ret = M2M_ATE_ERR_VALIDATE;
00339         goto __EXIT;
00340     }
00341     
00342     if(0 != m2m_ate_get_tx_status()) 
00343     {
00344         s8Ret = M2M_ATE_ERR_TX_ALREADY_RUNNING;
00345         goto __EXIT;
00346     }
00347     
00348     if(0 != m2m_ate_get_rx_status())
00349     {
00350         s8Ret = M2M_ATE_ERR_RX_ALREADY_RUNNING;
00351         goto __EXIT;
00352     }
00353     
00354     if( (strM2mAteTx->channel_num  < M2M_ATE_CHANNEL_1 ) || 
00355         (strM2mAteTx->channel_num  > M2M_ATE_CHANNEL_14 ) || 
00356         (strM2mAteTx->tx_gain_sel  < M2M_ATE_TX_GAIN_DYNAMIC )    ||
00357         (strM2mAteTx->tx_gain_sel  > M2M_ATE_TX_GAIN_TELEC ) ||
00358         (strM2mAteTx->frame_len  > M2M_ATE_MAX_FRAME_LENGTH) ||
00359         (strM2mAteTx->frame_len  < M2M_ATE_MIN_FRAME_LENGTH)
00360     )
00361     {
00362         s8Ret = M2M_ATE_ERR_VALIDATE;
00363         goto __EXIT;
00364     }
00365     
00366     if( (strM2mAteTx->duty_cycle  < M2M_ATE_TX_DUTY_MAX_VALUE /*1*/) ||
00367         (strM2mAteTx->duty_cycle  > M2M_ATE_TX_DUTY_MIN_VALUE /*10*/ ) ||
00368         (strM2mAteTx->dpd_ctrl  < M2M_ATE_TX_DPD_DYNAMIC )    ||
00369         (strM2mAteTx->dpd_ctrl  > M2M_ATE_TX_DPD_ENABLED )  ||
00370         (strM2mAteTx->use_pmu  > M2M_ATE_PMU_ENABLE ) ||
00371         (strM2mAteTx->phy_burst_tx  < M2M_ATE_TX_SRC_MAC ) ||
00372         (strM2mAteTx->phy_burst_tx  > M2M_ATE_TX_SRC_PHY ) ||
00373         (strM2mAteTx->cw_tx  < M2M_ATE_TX_MODE_NORM ) ||
00374         (strM2mAteTx->cw_tx  > M2M_ATE_TX_MODE_CW )
00375     )
00376     {
00377         s8Ret = M2M_ATE_ERR_VALIDATE;
00378         goto __EXIT;
00379     }
00380     
00381     for(u8LoopCntr=0; u8LoopCntr<M2M_ATE_MAX_NUM_OF_RATES; u8LoopCntr++) 
00382     {
00383         if(gaAteFwTxRates[u8LoopCntr] == strM2mAteTx->data_rate )
00384         {
00385             break;
00386         }
00387     }
00388     
00389     if(M2M_ATE_MAX_NUM_OF_RATES == u8LoopCntr) 
00390     {
00391         s8Ret = M2M_ATE_ERR_VALIDATE;
00392         goto __EXIT;
00393     }
00394     
00395 
00396     
00397     s8Ret += nm_write_reg(rBurstTx_NMI_USE_PMU, strM2mAteTx->use_pmu );
00398     s8Ret += nm_write_reg(rBurstTx_NMI_TX_PHY_CONT, strM2mAteTx->phy_burst_tx );
00399     s8Ret += nm_write_reg(rBurstTx_NMI_NUM_TX_FRAMES, strM2mAteTx->num_frames );
00400     s8Ret += nm_write_reg(rBurstTx_NMI_TX_GAIN, strM2mAteTx->tx_gain_sel );
00401     s8Ret += nm_write_reg(rBurstTx_NMI_TEST_CH, strM2mAteTx->channel_num );
00402     s8Ret += nm_write_reg(rBurstTx_NMI_TX_FRAME_LEN, strM2mAteTx->frame_len );
00403     s8Ret += nm_write_reg(rBurstTx_NMI_TX_CW_PARAM, strM2mAteTx->duty_cycle );
00404     s8Ret += nm_write_reg(rBurstTx_NMI_TX_DPD_CTRL, strM2mAteTx->dpd_ctrl );
00405     s8Ret += nm_write_reg(rBurstTx_NMI_TX_RATE, strM2mAteTx->data_rate );
00406     s8Ret += nm_write_reg(rBurstTx_NMI_TX_CW_MODE, strM2mAteTx->cw_tx );
00407     s8Ret += nm_write_reg(rBurstTx_NMI_TEST_XO_OFF, strM2mAteTx->xo_offset_x1000 );
00408     s8Ret += nm_write_reg(rBurstTx_NMI_USE_EFUSE_XO_OFF, strM2mAteTx->use_efuse_xo_offset );
00409 
00410     val32    = strM2mAteTx->peer_mac_addr [5]   << 0;
00411     val32   |= strM2mAteTx->peer_mac_addr [4]  << 8;
00412     val32   |= strM2mAteTx->peer_mac_addr [3]  << 16;
00413     nm_write_reg(rBurstTx_NMI_MAC_ADDR_LO_PEER, val32 );
00414     
00415     val32    = strM2mAteTx->peer_mac_addr [2]  << 0;
00416     val32   |= strM2mAteTx->peer_mac_addr [1] << 8;
00417     val32   |= strM2mAteTx->peer_mac_addr [0] << 16;
00418     nm_write_reg(rBurstTx_NMI_MAC_ADDR_HI_PEER, val32 );
00419 
00420     if(M2M_SUCCESS == s8Ret) 
00421     {
00422         s8Ret += nm_write_reg(rInterrupt_CORTUS_0, 1);  /*Interrupt Cortus*/
00423         m2m_ate_set_tx_status(1);
00424         nm_bsp_sleep(200);  /*Recommended*/ 
00425     }
00426     
00427 __EXIT:
00428     return s8Ret;
00429 }
00430 
00431 /*!
00432 @fn \
00433     sint8 m2m_ate_stop_tx(void)
00434 
00435 @brief
00436     This function used to stop TX test case.
00437 
00438 @return
00439     The function SHALL return 0 for success and a negative value otherwise.
00440 \sa
00441     m2m_ate_init, m2m_ate_start_tx, m2m_ate_get_tx_status
00442 */
00443 sint8 m2m_ate_stop_tx(void)
00444 {
00445     sint8   s8Ret = M2M_SUCCESS;
00446     
00447     s8Ret = nm_write_reg(rInterrupt_CORTUS_1, 1);
00448     if(M2M_SUCCESS == s8Ret)
00449     {
00450         m2m_ate_set_tx_status(0);
00451     }
00452     
00453     return s8Ret;
00454 }
00455 
00456 /*!
00457 @fn \
00458     sint8 m2m_ate_get_rx_status(uint8);
00459 
00460 @brief
00461     This function used to return status of RX test case either running or stopped.
00462 
00463 @return
00464     The function SHALL return status of ATE firmware, 1 if RX is running otherwise 0.
00465 \sa
00466     m2m_ate_start_rx, m2m_ate_stop_rx
00467 */
00468 sint8 m2m_ate_get_rx_status(void)
00469 {
00470     return gu8RxState ;
00471 }
00472 
00473 /*!
00474 @fn \
00475     sint8 m2m_ate_start_rx(tstrM2mAteRx *)
00476 
00477 @brief
00478     This function used to start RX test case.
00479 
00480 @param [in] strM2mAteRx
00481         Type of \ref tstrM2mAteRx, with the values required to enable RX test case. You must use \ref m2m_ate_init first.
00482 @return
00483     The function SHALL return 0 for success and a negative value otherwise.
00484 \sa
00485     m2m_ate_init, m2m_ate_stop_rx, m2m_ate_get_rx_status
00486 */
00487 sint8 m2m_ate_start_rx(tstrM2mAteRx * strM2mAteRxStr)
00488 {
00489     sint8       s8Ret = M2M_SUCCESS;
00490     uint32      val32;
00491     if(NULL == strM2mAteRxStr) 
00492     {
00493         s8Ret = M2M_ATE_ERR_VALIDATE;
00494         goto __EXIT;
00495     }
00496     
00497     if(0 != m2m_ate_get_tx_status()) 
00498     {
00499         s8Ret = M2M_ATE_ERR_TX_ALREADY_RUNNING;
00500         goto __EXIT;
00501     }
00502     
00503     if(0 != m2m_ate_get_rx_status())
00504     {
00505         s8Ret = M2M_ATE_ERR_RX_ALREADY_RUNNING;
00506         goto __EXIT;
00507     }
00508     
00509     if( (strM2mAteRxStr->channel_num  < M2M_ATE_CHANNEL_1 ) ||
00510         (strM2mAteRxStr->channel_num  > M2M_ATE_CHANNEL_14 )||
00511         (strM2mAteRxStr->use_pmu  > M2M_ATE_PMU_ENABLE )
00512     )
00513     {
00514         s8Ret = M2M_ATE_ERR_VALIDATE;
00515         goto __EXIT;
00516     }
00517     
00518     s8Ret += nm_write_reg(rBurstTx_NMI_TEST_CH, strM2mAteRxStr->channel_num );
00519     s8Ret += nm_write_reg(rBurstTx_NMI_USE_PMU, strM2mAteRxStr->use_pmu );
00520     s8Ret += nm_write_reg(rBurstTx_NMI_TEST_XO_OFF, strM2mAteRxStr->xo_offset_x1000 );
00521     s8Ret += nm_write_reg(rBurstTx_NMI_USE_EFUSE_XO_OFF, strM2mAteRxStr->use_efuse_xo_offset );
00522 
00523     if(strM2mAteRxStr->override_self_mac_addr )
00524     {
00525         val32    = strM2mAteRxStr->self_mac_addr [5] << 0;
00526         val32   |= strM2mAteRxStr->self_mac_addr [4] << 8;
00527         val32   |= strM2mAteRxStr->self_mac_addr [3] << 16;
00528         nm_write_reg(rBurstTx_NMI_MAC_ADDR_LO_SELF, val32 );
00529 
00530         val32    = strM2mAteRxStr->self_mac_addr [2] << 0;
00531         val32   |= strM2mAteRxStr->self_mac_addr [1] << 8;
00532         val32   |= strM2mAteRxStr->self_mac_addr [0] << 16;
00533         nm_write_reg(rBurstTx_NMI_MAC_ADDR_HI_SELF, val32 );
00534     }
00535     
00536     if(strM2mAteRxStr->mac_filter_en_sa )
00537     {
00538         val32    = strM2mAteRxStr->peer_mac_addr [5] << 0;
00539         val32   |= strM2mAteRxStr->peer_mac_addr [4] << 8;
00540         val32   |= strM2mAteRxStr->peer_mac_addr [3] << 16;
00541         nm_write_reg(rBurstTx_NMI_MAC_ADDR_LO_SA, val32 );
00542     
00543         val32    = strM2mAteRxStr->peer_mac_addr [2] << 0;
00544         val32   |= strM2mAteRxStr->peer_mac_addr [1] << 8;
00545         val32   |= strM2mAteRxStr->peer_mac_addr [0] << 16;
00546         nm_write_reg(rBurstTx_NMI_MAC_ADDR_HI_SA, val32 );
00547     }
00548     
00549     nm_write_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_DA, strM2mAteRxStr->mac_filter_en_da );
00550     nm_write_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_SA, strM2mAteRxStr->mac_filter_en_sa );
00551     nm_write_reg(rBurstTx_NMI_SET_SELF_MAC_ADDR, strM2mAteRxStr->override_self_mac_addr );
00552     
00553     if(M2M_SUCCESS == s8Ret) 
00554     {
00555         s8Ret += nm_write_reg(rInterrupt_CORTUS_2, 1);  /*Interrupt Cortus*/
00556         m2m_ate_set_rx_status(1);
00557         nm_bsp_sleep(10);  /*Recommended*/  
00558     }
00559     
00560 __EXIT:
00561     return s8Ret;
00562 }
00563 
00564 /*!
00565 @fn \
00566     sint8 m2m_ate_stop_rx(void)
00567 
00568 @brief
00569     This function used to stop RX test case.
00570 
00571 @return
00572     The function SHALL return 0 for success and a negative value otherwise.
00573 \sa
00574     m2m_ate_init, m2m_ate_start_rx, m2m_ate_get_rx_status
00575 */
00576 sint8 m2m_ate_stop_rx(void)
00577 {
00578     m2m_ate_set_rx_status(0);
00579     nm_bsp_sleep(200);  /*Recommended*/ 
00580     return M2M_SUCCESS;
00581 }
00582 
00583 /*!
00584 @fn \
00585     sint8 m2m_ate_read_rx_status(tstrM2mAteRxStatus *)
00586 
00587 @brief
00588     This function used to read RX statistics from ATE firmware.
00589 
00590 @param [out]    strM2mAteRxStatus
00591         Type of \ref tstrM2mAteRxStatus used to save statistics of RX test case. You must use \ref m2m_ate_start_rx first.
00592 @return
00593     The function SHALL return 0 for success and a negative value otherwise.
00594 \sa
00595     m2m_ate_init, m2m_ate_start_rx
00596 */
00597 sint8 m2m_ate_read_rx_status(tstrM2mAteRxStatus *strM2mAteRxStatus)
00598 {
00599     sint8   s8Ret = M2M_SUCCESS;
00600     
00601     if(NULL == strM2mAteRxStatus) 
00602     {
00603         s8Ret = M2M_ATE_ERR_VALIDATE;
00604         goto __EXIT;
00605     }
00606     
00607     if(0 != m2m_ate_get_tx_status()) 
00608     {
00609         s8Ret = M2M_ATE_ERR_TX_ALREADY_RUNNING;
00610         goto __EXIT;
00611     }
00612 
00613     if (nm_read_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_DA) || nm_read_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_SA)) 
00614     {
00615         strM2mAteRxStatus->num_rx_pkts       =       nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_SUCCESS) + nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_FAIL);
00616         strM2mAteRxStatus->num_good_pkts     =       nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_SUCCESS);
00617         strM2mAteRxStatus->num_err_pkts      =       nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_FAIL);
00618     } 
00619     else
00620     {
00621         strM2mAteRxStatus->num_rx_pkts  = nm_read_reg(rBurstRx_NMI_RX_ALL_PKTS_CONT) + nm_read_reg(0x989c);
00622         strM2mAteRxStatus->num_err_pkts  = nm_read_reg(rBurstRx_NMI_RX_ERR_PKTS_CONT);
00623         strM2mAteRxStatus->num_good_pkts  = strM2mAteRxStatus->num_rx_pkts  - strM2mAteRxStatus->num_err_pkts ;
00624     }
00625 
00626 __EXIT:
00627     return s8Ret;
00628 }
00629 /*!
00630 @fn \
00631     sint8 m2m_ate_set_dig_gain(double dGaindB)
00632 
00633 @brief
00634     This function is used to set the digital gain
00635 
00636 @param [in] double dGaindB
00637         The digital gain value required to be set.
00638 @return
00639     The function SHALL return 0 for success and a negative value otherwise.
00640 */
00641 sint8 m2m_ate_set_dig_gain(double dGaindB)
00642 {
00643     uint32_t dGain, val32;
00644     dGain = (uint32_t)(pow(10, dGaindB/20.0) * 1024.0);
00645 
00646     val32 = nm_read_reg(0x160cd0);
00647     val32 &= ~(0x1ffful << 0);
00648     val32 |= (((uint32_t)dGain) << 0);
00649     nm_write_reg(0x160cd0, val32);
00650     return M2M_SUCCESS;
00651 }
00652 /*!
00653 @fn \
00654     sint8 m2m_ate_get_dig_gain(double * dGaindB)
00655 
00656 @brief
00657     This function is used to get the digital gain
00658 
00659 @param [out]    double * dGaindB
00660         The retrieved digital gain value obtained from HW registers in dB.
00661 @return
00662     The function SHALL return 0 for success and a negative value otherwise.
00663 */
00664 sint8 m2m_ate_get_dig_gain(double * dGaindB)
00665 {
00666     uint32 dGain, val32;
00667     
00668     if(!dGaindB) return M2M_ERR_INVALID_ARG;
00669     
00670     val32 = nm_read_reg(0x160cd0);
00671     
00672     dGain = (val32 >> 0) & 0x1ffful;
00673     *dGaindB = 20.0*log10((double)dGain / 1024.0);
00674     
00675     return M2M_SUCCESS;
00676 }
00677 /*!
00678 @fn \
00679     void m2m_ate_set_pa_gain(uint8 gain_db)
00680 
00681 @brief
00682     This function is used to set the PA gain (18/15/12/9/6/3/0 only)
00683 
00684 @param [in] uint8 gain_db
00685         PA gain level allowed (18/15/12/9/6/3/0 only)
00686 
00687 */
00688 void m2m_ate_set_pa_gain(uint8 gain_db)
00689 {
00690     uint32 PA_1e9c;
00691     uint8 aGain[] = {
00692         /* "0 dB"  */ 0x00,
00693         /* "3 dB"  */ 0x01,
00694         /* "6 dB"  */ 0x03,
00695         /* "9 dB"  */ 0x07,
00696         /* "12 dB" */ 0x0f,
00697         /* "15 dB" */ 0x1f,
00698     /* "18 dB" */ 0x3f };
00699     /* The variable PA gain is valid only for High power mode */
00700     PA_1e9c = nm_read_reg(0x1e9c);
00701     /* TX bank 0. */
00702     PA_1e9c &= ~(0x3ful << 8);
00703     PA_1e9c |= (((uint32)aGain[gain_db/3] & 0x3f) << 8);
00704     nm_write_reg(0x1e9c, PA_1e9c);
00705 }
00706 /*!
00707 @fn \
00708     sint8 m2m_ate_get_pa_gain(double *paGaindB)
00709 
00710 @brief
00711     This function is used to get the PA gain
00712 
00713 @param [out]    double *paGaindB
00714         The retrieved PA gain value obtained from HW registers in dB.
00715 @return
00716     The function SHALL return 0 for success and a negative value otherwise.
00717 */
00718 sint8 m2m_ate_get_pa_gain(double *paGaindB)
00719 {
00720     uint32 val32, paGain;
00721     uint32 m_cmbPAGainStep;
00722     
00723     if(!paGaindB) 
00724         return M2M_ERR_INVALID_ARG;
00725     
00726     val32 = nm_read_reg(0x1e9c);
00727     
00728     paGain = (val32 >> 8) & 0x3f;
00729     
00730     switch(paGain){
00731         case 0x1:
00732         m_cmbPAGainStep = 5;
00733         break;
00734         case 0x3:
00735         m_cmbPAGainStep = 4;
00736         break;
00737         case 0x7:
00738         m_cmbPAGainStep = 3;
00739         break;
00740         case 0xf:
00741         m_cmbPAGainStep = 2;
00742         break;
00743         case 0x1f:
00744         m_cmbPAGainStep = 1;
00745         break;
00746         case 0x3f:
00747         m_cmbPAGainStep = 0;
00748         break;
00749         default:
00750         m_cmbPAGainStep = 0;
00751         break;
00752     }
00753     
00754     *paGaindB = 18 - m_cmbPAGainStep*3;
00755 
00756     return M2M_SUCCESS;
00757 }
00758 /*!
00759 @fn \
00760     sint8 m2m_ate_get_ppa_gain(double * ppaGaindB)
00761 
00762 @brief
00763     This function is used to get the PPA gain
00764 
00765 @param [out]    uint32 * ppaGaindB
00766         The retrieved PPA gain value obtained from HW registers in dB.
00767 @return
00768     The function SHALL return 0 for success and a negative value otherwise.
00769 */
00770 sint8 m2m_ate_get_ppa_gain(double * ppaGaindB)
00771 {
00772     uint32 val32, ppaGain, m_cmbPPAGainStep;
00773     
00774     if(!ppaGaindB) return M2M_ERR_INVALID_ARG;
00775 
00776     val32 = nm_read_reg(0x1ea0);
00777         
00778     ppaGain = (val32 >> 5) & 0x7;
00779     
00780     switch(ppaGain){
00781         case 0x1:
00782         m_cmbPPAGainStep = 2;
00783         break;
00784         case 0x3:
00785         m_cmbPPAGainStep = 1;
00786         break;
00787         case 0x7:
00788         m_cmbPPAGainStep = 0;
00789         break;
00790         default:
00791         m_cmbPPAGainStep = 3;
00792         break;
00793     }
00794     
00795     *ppaGaindB = 9 - m_cmbPPAGainStep*3;
00796             
00797     
00798     return M2M_SUCCESS;
00799 }
00800 /*!
00801 @fn \
00802     sint8 m2m_ate_get_tot_gain(double * totGaindB)
00803 
00804 @brief
00805     This function is used to calculate the total gain
00806 
00807 @param [out]    double * totGaindB
00808         The retrieved total gain value obtained from calculations made based on the digital gain, PA and PPA gain values.
00809 @return
00810     The function SHALL return 0 for success and a negative value otherwise.
00811 */
00812 sint8 m2m_ate_get_tot_gain(double * totGaindB)
00813 {
00814     double dGaindB, paGaindB, ppaGaindB;    
00815     
00816     if(!totGaindB) return M2M_ERR_INVALID_ARG;
00817     
00818     m2m_ate_get_pa_gain(&paGaindB);
00819     m2m_ate_get_ppa_gain(&ppaGaindB);
00820     m2m_ate_get_dig_gain(&dGaindB);
00821     
00822     *totGaindB = dGaindB + paGaindB + ppaGaindB;
00823     
00824     return M2M_SUCCESS;
00825 }
00826 
00827 #endif //_M2M_ATE_FW_
00828