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 nmdrv.c Source File

nmdrv.c

Go to the documentation of this file.
00001 /**
00002  *
00003  * \file
00004  *
00005  * \brief This module contains NMC1000 M2M driver APIs implementation.
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 #include "common/include/nm_common.h"
00043 #include "driver/source/nmbus.h"
00044 #include "bsp/include/nm_bsp.h"
00045 #include "driver/source/nmdrv.h"
00046 #include "driver/source/nmasic.h"
00047 #include "driver/include/m2m_types.h"
00048 #include "spi_flash/include/spi_flash.h"
00049 
00050 #ifdef CONF_WINC_USE_SPI
00051 #include "driver/source/nmspi.h"
00052 #endif
00053 
00054 /**
00055 *   @fn     nm_get_firmware_info(tstrM2mRev* M2mRev)
00056 *   @brief  Get Firmware version info
00057 *   @param [out]    M2mRev
00058 *               pointer holds address of structure "tstrM2mRev" that contains the firmware version parameters
00059 *   @version    1.0
00060 */
00061 sint8 nm_get_firmware_info(tstrM2mRev* M2mRev)
00062 {
00063     uint16  curr_drv_ver, min_req_drv_ver,curr_firm_ver;
00064     uint32  reg = 0;
00065     sint8   ret = M2M_SUCCESS;
00066 
00067     ret = nm_read_reg_with_ret(NMI_REV_REG, &reg);
00068     //In case the Firmware running is ATE fw
00069     if(M2M_ATE_FW_IS_UP_VALUE == reg)
00070     {
00071         //Read FW info again from the register specified for ATE
00072         ret = nm_read_reg_with_ret(NMI_REV_REG_ATE, &reg);
00073     }
00074     M2mRev->u8DriverMajor   = M2M_GET_DRV_MAJOR(reg);
00075     M2mRev->u8DriverMinor   = M2M_GET_DRV_MINOR(reg);
00076     M2mRev->u8DriverPatch   = M2M_GET_DRV_PATCH(reg);
00077     M2mRev->u8FirmwareMajor = M2M_GET_FW_MAJOR(reg);
00078     M2mRev->u8FirmwareMinor = M2M_GET_FW_MINOR(reg);
00079     M2mRev->u8FirmwarePatch = M2M_GET_FW_PATCH(reg);
00080     M2mRev->u32Chipid   = nmi_get_chipid();
00081     M2mRev->u16FirmwareSvnNum = 0;
00082     
00083     curr_firm_ver   = M2M_MAKE_VERSION(M2mRev->u8FirmwareMajor, M2mRev->u8FirmwareMinor,M2mRev->u8FirmwarePatch);
00084     curr_drv_ver    = M2M_MAKE_VERSION(M2M_RELEASE_VERSION_MAJOR_NO, M2M_RELEASE_VERSION_MINOR_NO, M2M_RELEASE_VERSION_PATCH_NO);
00085     min_req_drv_ver = M2M_MAKE_VERSION(M2mRev->u8DriverMajor, M2mRev->u8DriverMinor,M2mRev->u8DriverPatch);
00086     if(curr_drv_ver <  min_req_drv_ver) {
00087         /*The current driver version should be larger or equal 
00088         than the min driver that the current firmware support  */
00089         ret = M2M_ERR_FW_VER_MISMATCH;
00090     }
00091     if(curr_drv_ver >  curr_firm_ver) {
00092         /*The current driver should be equal or less than the firmware version*/
00093         ret = M2M_ERR_FW_VER_MISMATCH;
00094     }
00095     return ret;
00096 }
00097 /**
00098 *   @fn     nm_get_firmware_info(tstrM2mRev* M2mRev)
00099 *   @brief  Get Firmware version info
00100 *   @param [out]    M2mRev
00101 *               pointer holds address of structure "tstrM2mRev" that contains the firmware version parameters
00102 *   @version    1.0
00103 */
00104 sint8 nm_get_firmware_full_info(tstrM2mRev* pstrRev)
00105 {
00106     uint16  curr_drv_ver, min_req_drv_ver,curr_firm_ver;
00107     uint32  reg = 0;
00108     sint8   ret = M2M_SUCCESS;
00109     tstrGpRegs strgp = {0};
00110     if (pstrRev != NULL)
00111     {
00112         m2m_memset((uint8*)pstrRev,0,sizeof(tstrM2mRev));
00113         ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &reg);
00114         if(ret == M2M_SUCCESS)
00115         {
00116             if(reg != 0)
00117             {
00118                 ret = nm_read_block(reg|0x30000,(uint8*)&strgp,sizeof(tstrGpRegs));
00119                 if(ret == M2M_SUCCESS)
00120                 {
00121                     reg = strgp.u32Firmware_Ota_rev;
00122                     reg &= 0x0000ffff;
00123                     if(reg != 0)
00124                     {
00125                         ret = nm_read_block(reg|0x30000,(uint8*)pstrRev,sizeof(tstrM2mRev));
00126                         if(ret == M2M_SUCCESS)
00127                         {
00128                             curr_firm_ver   = M2M_MAKE_VERSION(pstrRev->u8FirmwareMajor, pstrRev->u8FirmwareMinor,pstrRev->u8FirmwarePatch);
00129                             curr_drv_ver    = M2M_MAKE_VERSION(M2M_RELEASE_VERSION_MAJOR_NO, M2M_RELEASE_VERSION_MINOR_NO, M2M_RELEASE_VERSION_PATCH_NO);
00130                             min_req_drv_ver = M2M_MAKE_VERSION(pstrRev->u8DriverMajor, pstrRev->u8DriverMinor,pstrRev->u8DriverPatch);
00131                             if((curr_firm_ver == 0)||(min_req_drv_ver == 0)||(min_req_drv_ver == 0)){
00132                                 ret = M2M_ERR_FAIL;
00133                                 goto EXIT;
00134                             }
00135                             if(curr_drv_ver <  min_req_drv_ver) {
00136                                 /*The current driver version should be larger or equal 
00137                                 than the min driver that the current firmware support  */
00138                                 ret = M2M_ERR_FW_VER_MISMATCH;
00139                                 goto EXIT;
00140                             }
00141                             if(curr_drv_ver >  curr_firm_ver) {
00142                                 /*The current driver should be equal or less than the firmware version*/
00143                                 ret = M2M_ERR_FW_VER_MISMATCH;
00144                                 goto EXIT;
00145                             }
00146                         }
00147                     }else {
00148                         ret = M2M_ERR_FAIL;
00149                     }
00150                 }
00151             }else{
00152                 ret = M2M_ERR_FAIL;
00153             }
00154         }
00155     }
00156 EXIT:
00157     return ret;
00158 }
00159 /**
00160 *   @fn     nm_get_ota_firmware_info(tstrM2mRev* pstrRev)
00161 *   @brief  Get Firmware version info
00162 *   @param [out]    M2mRev
00163 *               pointer holds address of structure "tstrM2mRev" that contains the firmware version parameters
00164             
00165 *   @version    1.0
00166 */
00167 sint8 nm_get_ota_firmware_info(tstrM2mRev* pstrRev)
00168 {
00169     uint16  curr_drv_ver, min_req_drv_ver,curr_firm_ver;
00170     uint32  reg = 0;
00171     sint8   ret;
00172     tstrGpRegs strgp = {0};
00173 
00174     if (pstrRev != NULL)
00175     {
00176         m2m_memset((uint8*)pstrRev,0,sizeof(tstrM2mRev));
00177         ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &reg);
00178         if(ret == M2M_SUCCESS)
00179         {
00180             if(reg != 0)
00181             {
00182                 ret = nm_read_block(reg|0x30000,(uint8*)&strgp,sizeof(tstrGpRegs));
00183                 if(ret == M2M_SUCCESS)
00184                 {
00185                     reg = strgp.u32Firmware_Ota_rev;
00186                     reg >>= 16;
00187                     if(reg != 0)
00188                     {
00189                         ret = nm_read_block(reg|0x30000,(uint8*)pstrRev,sizeof(tstrM2mRev));
00190                         if(ret == M2M_SUCCESS)
00191                         {
00192                             curr_firm_ver   = M2M_MAKE_VERSION(pstrRev->u8FirmwareMajor, pstrRev->u8FirmwareMinor,pstrRev->u8FirmwarePatch);
00193                             curr_drv_ver    = M2M_MAKE_VERSION(M2M_RELEASE_VERSION_MAJOR_NO, M2M_RELEASE_VERSION_MINOR_NO, M2M_RELEASE_VERSION_PATCH_NO);
00194                             min_req_drv_ver = M2M_MAKE_VERSION(pstrRev->u8DriverMajor, pstrRev->u8DriverMinor,pstrRev->u8DriverPatch);
00195                             if((curr_firm_ver == 0)||(min_req_drv_ver == 0)||(min_req_drv_ver == 0)){
00196                                 ret = M2M_ERR_FAIL;
00197                                 goto EXIT;
00198                             }
00199                             if(curr_drv_ver <  min_req_drv_ver) {
00200                                 /*The current driver version should be larger or equal 
00201                                 than the min driver that the current firmware support  */
00202                                 ret = M2M_ERR_FW_VER_MISMATCH;
00203                             }
00204                             if(curr_drv_ver >  curr_firm_ver) {
00205                                 /*The current driver should be equal or less than the firmware version*/
00206                                 ret = M2M_ERR_FW_VER_MISMATCH;
00207                             }
00208                         }
00209                     }else{
00210                         ret = M2M_ERR_INVALID;
00211                     }
00212                 }
00213             }else{
00214                 ret = M2M_ERR_FAIL;
00215             }
00216         }
00217     } else {
00218         ret = M2M_ERR_INVALID_ARG;
00219     }
00220 EXIT:
00221     return ret;
00222 }
00223 
00224 
00225 
00226 /*
00227 *   @fn     nm_drv_init_download_mode
00228 *   @brief  Initialize NMC1000 driver
00229 *   @return M2M_SUCCESS in case of success and Negative error code in case of failure
00230 *   @param [in] arg
00231 *               Generic argument
00232 *   @author Viswanathan Murugesan
00233 *   @date   10 Oct 2014
00234 *   @version    1.0
00235 */
00236 sint8 nm_drv_init_download_mode ()
00237 {
00238     sint8 ret = M2M_SUCCESS;
00239 
00240     ret = nm_bus_iface_init(NULL);
00241     if (M2M_SUCCESS != ret) {
00242         M2M_ERR("[nmi start]: fail init bus\n");
00243         goto ERR1;
00244     }
00245 
00246     /**
00247         TODO:reset the chip and halt the cpu in case of no wait efuse is set (add the no wait effuse check)
00248     */
00249     if(!ISNMC3000(GET_CHIPID()))
00250     {
00251         /*Execuate that function only for 1500A/B, no room in 3000, but it may be needed in 3400 no wait*/
00252         chip_reset_and_cpu_halt();
00253     }
00254 
00255 #ifdef CONF_WINC_USE_SPI
00256     /* Must do this after global reset to set SPI data packet size. */
00257     nm_spi_init ();
00258 #endif
00259 
00260     M2M_INFO("Chip ID %lx\n", nmi_get_chipid());
00261 
00262     /*disable all interrupt in ROM (to disable uart) in 2b0 chip*/
00263     nm_write_reg(0x20300,0);
00264 
00265 ERR1:
00266     return ret;
00267 }
00268 
00269 /*
00270 *   @fn     nm_drv_init
00271 *   @brief  Initialize NMC1000 driver
00272 *   @return M2M_SUCCESS in case of success and Negative error code in case of failure
00273 *   @param [in] arg
00274 *               Generic argument
00275 *   @author M. Abdelmawla
00276 *   @date   15 July 2012
00277 *   @version    1.0
00278 */
00279 sint8 nm_drv_init (void * arg)
00280 {
00281     sint8 ret = M2M_SUCCESS;
00282     uint8 u8Mode;
00283     
00284     if(NULL != arg) {
00285         u8Mode = *((uint8 *)arg);
00286         if((u8Mode < M2M_WIFI_MODE_NORMAL )||(u8Mode >= M2M_WIFI_MODE_MAX)) {
00287             u8Mode = M2M_WIFI_MODE_NORMAL ;
00288         }
00289     } else {
00290         u8Mode = M2M_WIFI_MODE_NORMAL ;
00291     }
00292     
00293     ret = nm_bus_iface_init(NULL);
00294     if (M2M_SUCCESS != ret) {
00295         M2M_ERR("[nmi start]: fail init bus\n");
00296         goto ERR1;
00297     }
00298 
00299 #ifdef BUS_ONLY
00300     return;
00301 #endif
00302     
00303     
00304 #ifdef NO_HW_CHIP_EN
00305     ret = chip_wake();
00306     if (M2M_SUCCESS != ret) {
00307         M2M_ERR("[nmi start]: fail chip_wakeup\n");
00308         goto ERR2;
00309     }
00310     /**
00311     Go...
00312     **/
00313     ret = chip_reset();
00314     if (M2M_SUCCESS != ret) {
00315         goto ERR2;
00316     }
00317 #endif
00318     M2M_INFO("Chip ID %lx\n", nmi_get_chipid());
00319 #ifdef CONF_WINC_USE_SPI
00320     /* Must do this after global reset to set SPI data packet size. */
00321     nm_spi_init ();
00322 #endif
00323     ret = wait_for_bootrom(u8Mode);
00324     if (M2M_SUCCESS != ret) {
00325         goto ERR2;
00326     }
00327         
00328     ret = wait_for_firmware_start(u8Mode);
00329     if (M2M_SUCCESS != ret) {
00330         goto ERR2;
00331     }
00332     
00333     if((M2M_WIFI_MODE_ATE_HIGH  == u8Mode)||(M2M_WIFI_MODE_ATE_LOW  == u8Mode)) {
00334         goto ERR1;
00335     } else {
00336         /*continue running*/
00337     }
00338     
00339     ret = enable_interrupts ();
00340     if (M2M_SUCCESS != ret) {
00341         M2M_ERR("failed to enable interrupts..\n");
00342         goto ERR2;
00343     }
00344     return ret;
00345 ERR2:
00346     nm_bus_iface_deinit();
00347 ERR1:
00348     return ret;
00349 }
00350 
00351 /*
00352 *   @fn     nm_drv_deinit
00353 *   @brief  Deinitialize NMC1000 driver
00354 *   @author M. Abdelmawla
00355 *   @date   17 July 2012
00356 *   @version    1.0
00357 */
00358 sint8 nm_drv_deinit(void * arg)
00359 {
00360     sint8 ret;
00361 
00362     ret = chip_deinit ();
00363     if (M2M_SUCCESS != ret) {
00364         M2M_ERR("[nmi stop]: chip_deinit fail\n");
00365         goto ERR1;
00366     }
00367     
00368     /* Disable SPI flash to save power when the chip is off */
00369     ret = spi_flash_enable(0);
00370     if (M2M_SUCCESS != ret) {
00371         M2M_ERR("[nmi stop]: SPI flash disable fail\n");
00372         goto ERR1;
00373     }
00374 
00375     ret = nm_bus_iface_deinit();
00376     if (M2M_SUCCESS != ret) {
00377         M2M_ERR("[nmi stop]: fail init bus\n");
00378         goto ERR1;
00379     }
00380 #ifdef CONF_WINC_USE_SPI
00381     /* Must do this after global reset to set SPI data packet size. */
00382     nm_spi_deinit();
00383 #endif
00384 
00385 ERR1:
00386     return ret;
00387 }
00388 
00389 
00390