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

m2m_hif.c

Go to the documentation of this file.
00001 /**
00002  *
00003  * \file
00004  *
00005  * \brief This module contains M2M host interface 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 "m2m_hif.h"
00046 #include "driver/include/m2m_types.h"
00047 #include "driver/source/nmasic.h"
00048 #include "driver/include/m2m_periph.h"
00049 
00050 #if (defined NM_EDGE_INTERRUPT)&&(defined NM_LEVEL_INTERRUPT)
00051 #error "only one type of interrupt NM_EDGE_INTERRUPT,NM_LEVEL_INTERRUPT"
00052 #endif
00053 
00054 #if !((defined NM_EDGE_INTERRUPT)||(defined NM_LEVEL_INTERRUPT))
00055 #error "define interrupt type NM_EDGE_INTERRUPT,NM_LEVEL_INTERRUPT"
00056 #endif
00057 
00058 #ifndef CORTUS_APP
00059 #define NMI_AHB_DATA_MEM_BASE  0x30000
00060 #define NMI_AHB_SHARE_MEM_BASE 0xd0000
00061 
00062 #define WIFI_HOST_RCV_CTRL_0    (0x1070)
00063 #define WIFI_HOST_RCV_CTRL_1    (0x1084)
00064 #define WIFI_HOST_RCV_CTRL_2    (0x1078)
00065 #define WIFI_HOST_RCV_CTRL_3    (0x106c)
00066 #define WIFI_HOST_RCV_CTRL_4    (0x150400)
00067 #define WIFI_HOST_RCV_CTRL_5    (0x1088)
00068 
00069 typedef struct {
00070     uint8 u8ChipMode;
00071     uint8 u8ChipSleep;
00072     uint8 u8HifRXDone;
00073     uint8 u8Interrupt;
00074     uint32 u32RxAddr;
00075     uint32 u32RxSize;
00076     tpfHifCallBack pfWifiCb;
00077     tpfHifCallBack pfIpCb;
00078     tpfHifCallBack pfOtaCb;
00079     tpfHifCallBack pfSigmaCb;
00080     tpfHifCallBack pfHifCb;
00081     tpfHifCallBack pfCryptoCb;
00082     tpfHifCallBack pfSslCb;
00083 }tstrHifContext;
00084 
00085 volatile tstrHifContext gstrHifCxt;
00086 
00087 static void isr(void)
00088 {
00089     gstrHifCxt.u8Interrupt++;
00090 #ifdef NM_LEVEL_INTERRUPT
00091     nm_bsp_interrupt_ctrl(0);
00092 #endif
00093 }
00094 static sint8 hif_set_rx_done(void)
00095 {
00096     uint32 reg;
00097     sint8 ret = M2M_SUCCESS;
00098 
00099     gstrHifCxt.u8HifRXDone = 0;
00100 #ifdef NM_EDGE_INTERRUPT
00101     nm_bsp_interrupt_ctrl(1);
00102 #endif
00103     ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0,&reg);
00104     if(ret != M2M_SUCCESS)goto ERR1;
00105     /* Set RX Done */
00106     reg |= NBIT1;
00107     ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0,reg);
00108     if(ret != M2M_SUCCESS)goto ERR1;
00109 #ifdef NM_LEVEL_INTERRUPT
00110     nm_bsp_interrupt_ctrl(1);
00111 #endif
00112 ERR1:
00113     return ret;
00114 
00115 }
00116 /**
00117 *   @fn         static void m2m_hif_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
00118 *   @brief      WiFi call back function
00119 *   @param [in] u8OpCode
00120 *                   HIF Opcode type.
00121 *   @param [in] u16DataSize
00122 *                   HIF data length.
00123 *   @param [in] u32Addr
00124 *                   HIF address.
00125 *   @param [in] grp
00126 *                   HIF group type.
00127 *   @author
00128 *   @date
00129 *   @version    1.0
00130 */
00131 static void m2m_hif_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
00132 {
00133 
00134 
00135 }
00136 /**
00137 *   @fn     NMI_API sint8 hif_chip_wake(void);
00138 *   @brief  To Wakeup the chip.
00139 *    @return        The function shall return ZERO for successful operation and a negative value otherwise.
00140 */
00141 
00142 sint8 hif_chip_wake(void)
00143 {
00144     sint8 ret = M2M_SUCCESS;
00145     if(gstrHifCxt.u8HifRXDone)
00146     {
00147         /*chip already wake for the rx not done no need to send wake request*/
00148         return ret;
00149     }
00150     if(gstrHifCxt.u8ChipSleep == 0)
00151     {
00152         if(gstrHifCxt.u8ChipMode != M2M_NO_PS )
00153         {
00154             ret = chip_wake();
00155             if(ret != M2M_SUCCESS)goto ERR1;
00156         }
00157         else
00158         {
00159         }
00160     }
00161     gstrHifCxt.u8ChipSleep++;
00162 ERR1:
00163     return ret;
00164 }
00165 /*!
00166 @fn \
00167     NMI_API void hif_set_sleep_mode(uint8 u8Pstype);
00168 
00169 @brief
00170     Set the sleep mode of the HIF layer.
00171 
00172 @param [in] u8Pstype
00173                 Sleep mode.
00174 
00175 @return
00176     The function SHALL return 0 for success and a negative value otherwise.
00177 */
00178 
00179 void hif_set_sleep_mode(uint8 u8Pstype)
00180 {
00181     gstrHifCxt.u8ChipMode = u8Pstype;
00182 }
00183 /*!
00184 @fn \
00185     NMI_API uint8 hif_get_sleep_mode(void);
00186 
00187 @brief
00188     Get the sleep mode of the HIF layer.
00189 
00190 @return
00191     The function SHALL return the sleep mode of the HIF layer.
00192 */
00193 
00194 uint8 hif_get_sleep_mode(void)
00195 {
00196     return gstrHifCxt.u8ChipMode;
00197 }
00198 
00199 /**
00200 *   @fn     NMI_API sint8 hif_chip_sleep_sc(void);
00201 *   @brief  To clear the chip sleep but keep the chip sleep
00202 *    @return        The function shall return ZERO for successful operation and a negative value otherwise.
00203 */
00204 
00205 sint8 hif_chip_sleep_sc(void)
00206 {
00207     if(gstrHifCxt.u8ChipSleep >= 1)
00208     {
00209         gstrHifCxt.u8ChipSleep--;
00210     }
00211     return M2M_SUCCESS;
00212 }
00213 /**
00214 *   @fn     NMI_API sint8 hif_chip_sleep(void);
00215 *   @brief  To make the chip sleep.
00216 *    @return        The function shall return ZERO for successful operation and a negative value otherwise.
00217 */
00218 
00219 sint8 hif_chip_sleep(void)
00220 {
00221     sint8 ret = M2M_SUCCESS;
00222 
00223     if(gstrHifCxt.u8ChipSleep >= 1)
00224     {
00225         gstrHifCxt.u8ChipSleep--;
00226     }
00227     
00228     if(gstrHifCxt.u8ChipSleep == 0)
00229     {
00230         if(gstrHifCxt.u8ChipMode != M2M_NO_PS )
00231         {
00232             ret = chip_sleep();
00233             if(ret != M2M_SUCCESS)goto ERR1;
00234 
00235         }
00236         else
00237         {
00238         }
00239     }
00240 ERR1:
00241     return ret;
00242 }
00243 /**
00244 *   @fn     NMI_API sint8 hif_init(void * arg);
00245 *   @brief  To initialize HIF layer.
00246 *   @param [in] arg
00247 *               Pointer to the arguments.
00248 *   @return     The function shall return ZERO for successful operation and a negative value otherwise.
00249 */
00250 
00251 sint8 hif_init(void * arg)
00252 {
00253     m2m_memset((uint8*)&gstrHifCxt,0,sizeof(tstrHifContext));
00254     nm_bsp_register_isr(isr);
00255     hif_register_cb(M2M_REQ_GROUP_HIF,m2m_hif_cb);
00256     return M2M_SUCCESS;
00257 }
00258 /**
00259 *   @fn     NMI_API sint8 hif_deinit(void * arg);
00260 *   @brief  To De-initialize HIF layer.
00261 *    @param [in]    arg
00262 *               Pointer to the arguments.
00263 *    @return        The function shall return ZERO for successful operation and a negative value otherwise.
00264 */
00265 sint8 hif_deinit(void * arg)
00266 {
00267     sint8 ret = M2M_SUCCESS;
00268     ret = hif_chip_wake();
00269     m2m_memset((uint8*)&gstrHifCxt,0,sizeof(tstrHifContext));
00270     return ret;
00271 }
00272 /**
00273 *   @fn     NMI_API sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize,
00274                        uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset)
00275 *   @brief  Send packet using host interface.
00276 
00277 *   @param [in] u8Gid
00278 *               Group ID.
00279 *   @param [in] u8Opcode
00280 *               Operation ID.
00281 *   @param [in] pu8CtrlBuf
00282 *               Pointer to the Control buffer.
00283 *   @param [in] u16CtrlBufSize
00284                 Control buffer size.
00285 *   @param [in] u16DataOffset
00286                 Packet Data offset.
00287 *   @param [in] pu8DataBuf
00288 *               Packet buffer Allocated by the caller.
00289 *   @param [in] u16DataSize
00290                 Packet buffer size (including the HIF header).
00291 *    @return        The function shall return ZERO for successful operation and a negative value otherwise.
00292 */
00293 
00294 sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize,
00295                uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset)
00296 {
00297     sint8       ret = M2M_ERR_SEND;
00298     volatile tstrHifHdr strHif;
00299 
00300     strHif.u8Opcode      = u8Opcode&(~NBIT7);
00301     strHif.u8Gid         = u8Gid;
00302     strHif.u16Length     = M2M_HIF_HDR_OFFSET;
00303     if(pu8DataBuf != NULL)
00304     {
00305         strHif.u16Length  += u16DataOffset + u16DataSize;
00306     }
00307     else
00308     {
00309         strHif.u16Length  += u16CtrlBufSize;
00310     }
00311     ret = hif_chip_wake();
00312     if(ret == M2M_SUCCESS)
00313     {
00314         volatile uint32 reg, dma_addr = 0;
00315         volatile uint16 cnt = 0;
00316 //#define OPTIMIZE_BUS 
00317 /*please define in firmware also*/
00318 #ifndef OPTIMIZE_BUS
00319         reg = 0UL;
00320         reg |= (uint32)u8Gid;
00321         reg |= ((uint32)u8Opcode<<8);
00322         reg |= ((uint32)strHif.u16Length <<16);
00323         ret = nm_write_reg(NMI_STATE_REG,reg);
00324         if(M2M_SUCCESS != ret) goto ERR1;
00325 
00326         reg = 0UL;
00327         reg |= NBIT1;
00328         ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg);
00329         if(M2M_SUCCESS != ret) goto ERR1;
00330 #else
00331         reg = 0UL;
00332         reg |= NBIT1;
00333         reg |= ((u8Opcode & NBIT7) ? (NBIT2):(0)); /*Data = 1 or config*/
00334         reg |= (u8Gid == M2M_REQ_GROUP_IP) ? (NBIT3):(0); /*IP = 1 or non IP*/
00335         reg |= ((uint32)strHif.u16Length  << 4); /*length of pkt max = 4096*/
00336         ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg);
00337         if(M2M_SUCCESS != ret) goto ERR1;
00338 #endif
00339         dma_addr = 0;
00340         
00341         for(cnt = 0; cnt < 1000; cnt ++)
00342         {
00343             ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_2,(uint32 *)&reg);
00344             if(ret != M2M_SUCCESS) break;
00345             /*
00346              * If it takes too long to get a response, the slow down to 
00347              * avoid back-to-back register read operations.
00348              */
00349             if(cnt >= 500) {
00350                 if(cnt < 501) {
00351                     M2M_INFO("Slowing down...\n");
00352                 }
00353                 nm_bsp_sleep(1);
00354             }
00355             if (!(reg & NBIT1))
00356             {
00357                 ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_4,(uint32 *)&dma_addr);
00358                 if(ret != M2M_SUCCESS) {
00359                     /*in case of read error clear the DMA address and return error*/
00360                     dma_addr = 0;
00361                     goto ERR1;
00362                 }
00363                 /*in case of success break */
00364                 break;
00365             }
00366         }
00367 
00368         if (dma_addr != 0)
00369         {
00370             volatile uint32 u32CurrAddr;
00371             u32CurrAddr = dma_addr;
00372             strHif.u16Length =NM_BSP_B_L_16(strHif.u16Length );
00373             ret = nm_write_block(u32CurrAddr, (uint8*)&strHif, M2M_HIF_HDR_OFFSET);
00374             if(M2M_SUCCESS != ret) goto ERR1;
00375             u32CurrAddr += M2M_HIF_HDR_OFFSET;
00376             if(pu8CtrlBuf != NULL)
00377             {
00378                 ret = nm_write_block(u32CurrAddr, pu8CtrlBuf, u16CtrlBufSize);
00379                 if(M2M_SUCCESS != ret) goto ERR1;
00380                 u32CurrAddr += u16CtrlBufSize;
00381             }
00382             if(pu8DataBuf != NULL)
00383             {
00384                 u32CurrAddr += (u16DataOffset - u16CtrlBufSize);
00385                 ret = nm_write_block(u32CurrAddr, pu8DataBuf, u16DataSize);
00386                 if(M2M_SUCCESS != ret) goto ERR1;
00387                 u32CurrAddr += u16DataSize;
00388             }
00389 
00390             reg = dma_addr << 2;
00391             reg |= NBIT1;
00392             ret = nm_write_reg(WIFI_HOST_RCV_CTRL_3, reg);
00393             if(M2M_SUCCESS != ret) goto ERR1;
00394         }
00395         else
00396         {
00397             ret = hif_chip_sleep();
00398             M2M_DBG("Failed to alloc rx size %d\r",ret);
00399             ret = M2M_ERR_MEM_ALLOC;
00400             goto ERR2;
00401         }
00402 
00403     }
00404     else
00405     {
00406         M2M_ERR("(HIF)Fail to wakup the chip\n");
00407         goto ERR2;
00408     }
00409     /*actual sleep ret = M2M_SUCCESS*/
00410     ret = hif_chip_sleep();
00411     return ret;
00412 ERR1:
00413     /*reset the count but no actual sleep as it already bus error*/
00414     hif_chip_sleep_sc();
00415 ERR2:
00416     /*logical error*/
00417     return ret;
00418 }
00419 /**
00420 *   @fn     hif_isr
00421 *   @brief  Host interface interrupt service routine
00422 *   @author M. Abdelmawla
00423 *   @date   15 July 2012
00424 *   @return 1 in case of interrupt received else 0 will be returned
00425 *   @version    1.0
00426 */
00427 static sint8 hif_isr(void)
00428 {
00429     sint8 ret = M2M_SUCCESS;
00430     uint32 reg;
00431     volatile tstrHifHdr strHif;
00432 
00433     ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, &reg);
00434     if(M2M_SUCCESS == ret)
00435     {
00436         if(reg & 0x1)   /* New interrupt has been received */
00437         {
00438             uint16 size;
00439 
00440             nm_bsp_interrupt_ctrl(0);
00441             /*Clearing RX interrupt*/
00442             reg &= ~NBIT0;
00443             ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0,reg);
00444             if(ret != M2M_SUCCESS)goto ERR1;
00445             gstrHifCxt.u8HifRXDone = 1;
00446             size = (uint16)((reg >> 2) & 0xfff);
00447             if (size > 0) {
00448                 uint32 address = 0;
00449                 /**
00450                 start bus transfer
00451                 **/
00452                 ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_1, &address);
00453                 if(M2M_SUCCESS != ret)
00454                 {
00455                     M2M_ERR("(hif) WIFI_HOST_RCV_CTRL_1 bus fail\n");
00456                     nm_bsp_interrupt_ctrl(1);
00457                     goto ERR1;
00458                 }
00459                 gstrHifCxt.u32RxAddr = address;
00460                 gstrHifCxt.u32RxSize = size;
00461                 ret = nm_read_block(address, (uint8*)&strHif, sizeof(tstrHifHdr));
00462                 strHif.u16Length = NM_BSP_B_L_16(strHif.u16Length);
00463                 if(M2M_SUCCESS != ret)
00464                 {
00465                     M2M_ERR("(hif) address bus fail\n");
00466                     nm_bsp_interrupt_ctrl(1);
00467                     goto ERR1;
00468                 }
00469                 if(strHif.u16Length != size)
00470                 {
00471                     if((size - strHif.u16Length) > 4)
00472                     {
00473                         M2M_ERR("(hif) Corrupted packet Size = %u <L = %u, G = %u, OP = %02X>\n",
00474                             size, strHif.u16Length, strHif.u8Gid, strHif.u8Opcode);
00475                         nm_bsp_interrupt_ctrl(1);
00476                         ret = M2M_ERR_BUS_FAIL;
00477                         goto ERR1;
00478                     }
00479                 }
00480 
00481                 if(M2M_REQ_GROUP_WIFI == strHif.u8Gid)
00482                 {
00483                     if(gstrHifCxt.pfWifiCb)
00484                         gstrHifCxt.pfWifiCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
00485                     else
00486                         M2M_ERR("WIFI callback is not registered\n");
00487 
00488                 }
00489                 else if(M2M_REQ_GROUP_IP == strHif.u8Gid)
00490                 {
00491                     if(gstrHifCxt.pfIpCb)
00492                         gstrHifCxt.pfIpCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
00493                     else
00494                         M2M_ERR("Scoket callback is not registered\n");
00495 
00496                 }
00497                 else if(M2M_REQ_GROUP_OTA == strHif.u8Gid)
00498                 {
00499                     if(gstrHifCxt.pfOtaCb)
00500                         gstrHifCxt.pfOtaCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
00501                     else
00502                         M2M_ERR("Ota callback is not registered\n");
00503 
00504                 }
00505                 else if(M2M_REQ_GROUP_CRYPTO == strHif.u8Gid)
00506                 {
00507                     if(gstrHifCxt.pfCryptoCb)
00508                         gstrHifCxt.pfCryptoCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
00509 
00510                     else
00511                         M2M_ERR("Crypto callback is not registered\n");
00512                 }
00513                 else if(M2M_REQ_GROUP_SIGMA == strHif.u8Gid)
00514                 {
00515                     if(gstrHifCxt.pfSigmaCb)
00516                         gstrHifCxt.pfSigmaCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
00517                     else
00518                         M2M_ERR("Sigma callback is not registered\n");
00519                 }
00520                 else if(M2M_REQ_GROUP_SSL == strHif.u8Gid)
00521                 {
00522                     if(gstrHifCxt.pfSslCb)
00523                         gstrHifCxt.pfSslCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
00524                 }
00525                 else
00526                 {
00527                     M2M_ERR("(hif) invalid group ID\n");
00528                     ret = M2M_ERR_BUS_FAIL;
00529                     goto ERR1;
00530                 }
00531                 if(gstrHifCxt.u8HifRXDone)
00532                 {
00533                     M2M_ERR("(hif) host app didn't set RX Done <%u><%X>\n", strHif.u8Gid, strHif.u8Opcode);
00534                     ret = hif_set_rx_done();
00535                     if(ret != M2M_SUCCESS) goto ERR1;
00536                 }
00537             }
00538             else
00539             {
00540                 M2M_ERR("(hif) Wrong Size\n");
00541                 ret = M2M_ERR_RCV;
00542                 goto ERR1;
00543             }
00544         }
00545         else
00546         {
00547 #ifndef WIN32
00548             M2M_ERR("(hif) False interrupt %lx",reg);
00549             ret = M2M_ERR_FAIL;
00550             goto ERR1;
00551 #else
00552 #endif
00553         }
00554     }
00555     else
00556     {
00557         M2M_ERR("(hif) Fail to Read interrupt reg\n");
00558         goto ERR1;
00559     }
00560 
00561 ERR1:
00562     return ret;
00563 }
00564 
00565 /**
00566 *   @fn     hif_handle_isr(void)
00567 *   @brief  Handle interrupt received from NMC1500 firmware.
00568 *   @return     The function SHALL return 0 for success and a negative value otherwise.
00569 */
00570 
00571 sint8 hif_handle_isr(void)
00572 {
00573     sint8 ret = M2M_SUCCESS;    
00574     while (gstrHifCxt.u8Interrupt) {
00575         /*must be at that place because of the race of interrupt increment and that decrement*/
00576         /*when the interrupt enabled*/
00577         gstrHifCxt.u8Interrupt--;
00578         while(1)
00579         {
00580             ret = hif_isr();
00581             if(ret == M2M_SUCCESS) {
00582                 /*we will try forever untill we get that interrupt*/
00583                 /*Fail return errors here due to bus errors (reading expected values)*/
00584                 break;
00585             } else {
00586                 M2M_ERR("(HIF) Fail to handle interrupt %d try Again..\n",ret);
00587             }
00588         }
00589     }
00590 
00591     return ret;
00592 }
00593 /*
00594 *   @fn     hif_receive
00595 *   @brief  Host interface interrupt serviece routine
00596 *   @param [in] u32Addr
00597 *               Receive start address
00598 *   @param [out]    pu8Buf
00599 *               Pointer to receive buffer. Allocated by the caller
00600 *   @param [in] u16Sz
00601 *               Receive buffer size
00602 *   @param [in] isDone
00603 *               If you don't need any more packets send True otherwise send false
00604 *    @return        The function shall return ZERO for successful operation and a negative value otherwise.
00605 */
00606 sint8 hif_receive(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz, uint8 isDone)
00607 {
00608     sint8 ret = M2M_SUCCESS;
00609     if((u32Addr == 0)||(pu8Buf == NULL) || (u16Sz == 0))
00610     {
00611         if(isDone)
00612         {           
00613             /* set RX done */
00614             ret = hif_set_rx_done();
00615         }
00616         else
00617         {
00618             ret = M2M_ERR_FAIL;
00619             M2M_ERR(" hif_receive: Invalid argument\n");
00620         }
00621         goto ERR1;
00622     }
00623 
00624     if(u16Sz > gstrHifCxt.u32RxSize)
00625     {
00626         ret = M2M_ERR_FAIL;
00627         M2M_ERR("APP Requested Size is larger than the recived buffer size <%u><%lu>\n",u16Sz, gstrHifCxt.u32RxSize);
00628         goto ERR1;
00629     }
00630     if((u32Addr < gstrHifCxt.u32RxAddr)||((u32Addr + u16Sz)>(gstrHifCxt.u32RxAddr + gstrHifCxt.u32RxSize)))
00631     {
00632         ret = M2M_ERR_FAIL;
00633         M2M_ERR("APP Requested Address beyond the recived buffer address and length\n");
00634         goto ERR1;
00635     }
00636     
00637     /* Receive the payload */
00638     ret = nm_read_block(u32Addr, pu8Buf, u16Sz);
00639     if(ret != M2M_SUCCESS)goto ERR1;
00640 
00641     /* check if this is the last packet */
00642     if((((gstrHifCxt.u32RxAddr + gstrHifCxt.u32RxSize) - (u32Addr + u16Sz)) <= 0) || isDone)
00643     {
00644         /* set RX done */
00645         ret = hif_set_rx_done();
00646     }
00647 
00648 ERR1:
00649     return ret;
00650 }
00651 
00652 /**
00653 *   @fn     hif_register_cb
00654 *   @brief  To set Callback function for every compantent Component
00655 *   @param [in] u8Grp
00656 *               Group to which the Callback function should be set.
00657 *   @param [in] fn
00658 *               function to be set
00659 *    @return        The function shall return ZERO for successful operation and a negative value otherwise.
00660 */
00661 
00662 sint8 hif_register_cb(uint8 u8Grp,tpfHifCallBack fn)
00663 {
00664     sint8 ret = M2M_SUCCESS;
00665     switch(u8Grp)
00666     {
00667         case M2M_REQ_GROUP_IP:
00668             gstrHifCxt.pfIpCb = fn;
00669             break;
00670         case M2M_REQ_GROUP_WIFI:
00671             gstrHifCxt.pfWifiCb = fn;
00672             break;
00673         case M2M_REQ_GROUP_OTA:
00674             gstrHifCxt.pfOtaCb = fn;
00675             break;
00676         case M2M_REQ_GROUP_HIF:
00677             gstrHifCxt.pfHifCb = fn;
00678             break;
00679         case M2M_REQ_GROUP_CRYPTO:
00680             gstrHifCxt.pfCryptoCb = fn;
00681             break;
00682         case M2M_REQ_GROUP_SIGMA:
00683             gstrHifCxt.pfSigmaCb = fn;
00684             break;
00685         case M2M_REQ_GROUP_SSL:
00686             gstrHifCxt.pfSslCb = fn;
00687             break;
00688         default:
00689             M2M_ERR("GRp ? %d\n",u8Grp);
00690             ret = M2M_ERR_FAIL;
00691             break;
00692     }
00693     return ret;
00694 }
00695 
00696 #endif
00697