|
- /*******************************************************************************
- File Name:
- m2m_hif.c
-
- Summary:
- This module contains M2M host interface API implementations.
-
- Description:
- This module contains M2M host interface API implementations.
- *******************************************************************************/
-
- //DOM-IGNORE-BEGIN
- /*******************************************************************************
- * Copyright (C) 2021 Microchip Technology Inc. and its subsidiaries.
- *
- * Subject to your compliance with these terms, you may use Microchip software
- * and any derivatives exclusively with Microchip products. It is your
- * responsibility to comply with third party license terms applicable to your
- * use of third party software (including open source software) that may
- * accompany Microchip software.
- *
- * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
- * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
- * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
- * PARTICULAR PURPOSE.
- *
- * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
- * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
- * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
- * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
- * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
- * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
- * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
- *******************************************************************************/
-
- #include "nm_common.h"
- #include "nmbus.h"
- #include "nmdrv.h"
- #include "nm_bsp.h"
- #include "m2m_hif.h"
- #include "m2m_types.h"
- #include "nmasic.h"
- #include "m2m_periph.h"
- //#include "wdrv_winc_common.h"
- //#include "osal/osal.h"
-
- #define NMI_AHB_DATA_MEM_BASE 0x30000
- #define NMI_AHB_SHARE_MEM_BASE 0xd0000
-
- #define WIFI_HOST_RCV_CTRL_0 (0x1070)
- #define WIFI_HOST_RCV_CTRL_1 (0x1084)
- #define WIFI_HOST_RCV_CTRL_2 (0x1078)
- #define WIFI_HOST_RCV_CTRL_3 (0x106c)
- #define WIFI_HOST_RCV_CTRL_4 (0x150400)
-
-
- #define INTERRUPT_CORTUS_0_3000D0 (0x10a8)
- #define INTERRUPT_CORTUS_1_3000D0 (0x10ac)
- #define INTERRUPT_CORTUS_2_3000D0 (0x10b0)
- #define INTERRUPT_CORTUS_3_3000D0 (0x10b4)
-
- //static OSAL_SEM_HANDLE_TYPE hifSemaphore;
-
- typedef struct {
- uint8_t u8ChipMode;
- uint8_t u8ChipSleep;
- uint8_t u8HifRXDone;
- uint8_t u8Interrupt;
- uint32_t u32RxAddr;
- uint32_t u32RxSize;
- tpfHifCallBack pfWifiCb;
- tpfHifCallBack pfIpCb;
- tpfHifCallBack pfOtaCb;
- tpfHifCallBack pfSigmaCb;
- tpfHifCallBack pfHifCb;
- //tpfHifCallBack pfCryptoCb;
- tpfHifCallBack pfSslCb;
- } tstrHifContext;
-
- volatile tstrHifContext gstrHifCxt;
-
- /*
- Special codes for managing HIF restriction to OTA rollback/switch only
- */
- #define HIF_OTA_RB_ONLY 0xFFFF
- #define HIFCODE_OTA_RB ((M2M_REQ_GROUP_OTA << 8) | M2M_OTA_REQ_ROLLBACK)
- #define HIFCODE_OTA_SW ((M2M_REQ_GROUP_OTA << 8) | M2M_OTA_REQ_SWITCH_FIRMWARE)
- /*
- Codes for new HIF messages (since last HIF major increase).
- Only need ones which are host->winc.
- Each entry is formed of ((GroupId << 8) | OpCode)
- */
- #define HIFCODE_SSL_WRITECERT ((M2M_REQ_GROUP_SSL << 8) | M2M_SSL_REQ_WRITE_OWN_CERTS)
- #define HIFCODE_WIFI_PASSIVESCAN ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQ_PASSIVE_SCAN)
- #define HIFCODE_WIFI_CONN ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQ_CONN)
- #define HIFCODE_WIFI_CONN_PARAM ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_IND_CONN_PARAM)
- #define HIFCODE_WIFI_DELETE_CRED ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQRSP_DELETE_APID)
- #define HIFCODE_WIFI_START_PROV_MODE ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQ_START_PROVISION_MODE)
- #define HIFCODE_WIFI_ENABLE_AP ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQ_ENABLE_AP)
- #define HIFCODE_IP_RAW_SOCK_OPT ((M2M_REQ_GROUP_IP << 8) | SOCKET_CMD_RAW_SET_SOCK_OPT)
- #define HIFCODE_WIFI_ROAMING ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQ_ROAMING)
- #define HIFCODE_IP_SECURE ((M2M_REQ_GROUP_IP << 8) | SOCKET_CMD_SECURE)
- #define HIFCODE_WIFI_SCAN_SSID_LIST ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQ_SCAN_SSID_LIST)
- #define HIFCODE_WIFI_SET_STOP_SCAN_OPTION ((M2M_REQ_GROUP_WIFI << 8) | M2M_WIFI_REQ_SET_STOP_SCAN_OPTION)
-
- /*
- List of new HIF messages (since last HIF major increase).
- Only need to list ones which are host->winc.
- Additionally, entry 0 used to indicate OTA RB/SW only.
- */
- #define NEW_HIF_LIST \
- HIF_OTA_RB_ONLY, \
- HIFCODE_SSL_WRITECERT, \
- HIFCODE_WIFI_PASSIVESCAN, \
- HIFCODE_WIFI_CONN, \
- HIFCODE_WIFI_CONN_PARAM, \
- HIFCODE_WIFI_DELETE_CRED, \
- HIFCODE_WIFI_START_PROV_MODE, \
- HIFCODE_WIFI_ENABLE_AP, \
- HIFCODE_IP_RAW_SOCK_OPT, \
- HIFCODE_WIFI_ROAMING, \
- HIFCODE_IP_SECURE, \
- HIFCODE_WIFI_SCAN_SSID_LIST, \
- HIFCODE_WIFI_SET_STOP_SCAN_OPTION
- /*
- Array of HIF messages which are not supported by Firmware.
- During hif_init() this array is rebased using an offset determined by Firmware HIF level.
- */
- static uint16_t gau16HifBlacklist[] = {NEW_HIF_LIST};
- #define HIF_BLACKLIST_SZ (sizeof(gau16HifBlacklist)/sizeof(gau16HifBlacklist[0]))
- static uint8_t gu8HifBlOffset = 0;
-
-
- static int8_t hif_set_rx_done(void)
- {
- uint32_t reg;
- int8_t ret = M2M_SUCCESS;
- gstrHifCxt.u8HifRXDone = 0;
- if (ISNMC3400(nmi_get_chipid())) {
- ret = nm_write_reg(INTERRUPT_CORTUS_0_3000D0, 1);
- if(ret != M2M_SUCCESS)goto ERR1;
- } else {
- ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, ®);
- if(ret != M2M_SUCCESS)goto ERR1;
-
- /* Set RX Done */
- reg |= NBIT1;
- ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0, reg);
- if(ret != M2M_SUCCESS)goto ERR1;
- }
-
- ERR1:
- return ret;
- }
-
- /**
- * @fn static void m2m_hif_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr)
- * @brief WiFi call back function
- * @param[in] u8OpCode
- * HIF Opcode type.
- * @param[in] u16DataSize
- * HIF data length.
- * @param[in] u32Addr
- * HIF address.
- */
- static void m2m_hif_cb(uint8_t u8OpCode, uint16_t u16DataSize, uint32_t u32Addr)
- {
- }
-
- /**
- * @fn int8_t hif_chip_wake(void);
- * @brief To Wakeup the chip.
- * @return The function shall return ZERO for successful operation and a negative value otherwise.
- */
- int8_t hif_chip_wake(void)
- {
- int8_t ret = M2M_SUCCESS;
- if(gstrHifCxt.u8HifRXDone)
- {
- /* chip already wake for the rx not done no need to send wake request */
- return ret;
- }
- if(gstrHifCxt.u8ChipSleep == 0)
- {
- if(gstrHifCxt.u8ChipMode != M2M_NO_PS)
- {
- ret = chip_wake();
- if(ret != M2M_SUCCESS)goto ERR1;
- }
- }
- gstrHifCxt.u8ChipSleep++;
- ERR1:
- return ret;
- }
- /*!
- @fn \
- void hif_set_sleep_mode(uint8_t u8Pstype);
-
- @brief
- Set the sleep mode of the HIF layer.
-
- @param [in] u8Pstype
- Sleep mode.
-
- @return
- The function SHALL return 0 for success and a negative value otherwise.
- */
-
- void hif_set_sleep_mode(uint8_t u8Pstype)
- {
- gstrHifCxt.u8ChipMode = u8Pstype;
- }
-
- /*!
- @fn \
- uint8_t hif_get_sleep_mode(void);
-
- @brief
- Get the sleep mode of the HIF layer.
-
- @return
- The function SHALL return the sleep mode of the HIF layer.
- */
- uint8_t hif_get_sleep_mode(void)
- {
- return gstrHifCxt.u8ChipMode;
- }
-
- /**
- * @fn int8_t hif_chip_sleep_sc(void);
- * @brief To clear the chip sleep but keep the chip sleep
- * @return The function shall return ZERO for successful operation and a negative value otherwise.
- */
- static int8_t hif_chip_sleep_sc(void)
- {
- if(gstrHifCxt.u8ChipSleep >= 1)
- {
- gstrHifCxt.u8ChipSleep--;
- }
- return M2M_SUCCESS;
- }
-
-
- /**
- * @fn int8_t hif_chip_sleep(void);
- * @brief To make the chip sleep.
- * @return The function shall return ZERO for successful operation and a negative value otherwise.
- */
- int8_t hif_chip_sleep(void)
- {
- int8_t ret = M2M_SUCCESS;
-
- if(gstrHifCxt.u8ChipSleep >= 1)
- {
- gstrHifCxt.u8ChipSleep--;
- }
-
- if(gstrHifCxt.u8ChipSleep == 0)
- {
- if(gstrHifCxt.u8ChipMode != M2M_NO_PS)
- ret = chip_sleep();
- }
- return ret;
- }
-
- /**
- * @fn int8_t hif_init(void * arg);
- * @brief To initialize HIF layer.
- * @param[in] arg
- * Pointer to the arguments.
- * @return The function shall return ZERO for successful operation and a negative value otherwise.
- */
- int8_t hif_init(void *arg)
- {
- memset((uint8_t*)&gstrHifCxt, 0, sizeof(tstrHifContext));
-
- // if (OSAL_RESULT_TRUE != OSAL_SEM_Create(&hifSemaphore, OSAL_SEM_TYPE_BINARY, 1, 1))
- // return M2M_ERR_INIT;
-
- hif_register_cb(M2M_REQ_GROUP_HIF, m2m_hif_cb);
- return hif_chip_sleep();
- }
-
- /**
- * @fn int8_t hif_deinit(void * arg);
- * @brief To Deinitialize HIF layer.
- * @param[in] arg
- * Pointer to the arguments.
- * @return The function shall return ZERO for successful operation and a negative value otherwise.
- */
- int8_t hif_deinit(void *arg)
- {
- int8_t ret = M2M_SUCCESS;
- ret = hif_chip_wake();
- memset((uint8_t*)&gstrHifCxt, 0, sizeof(tstrHifContext));
- return ret;
- }
-
- /**
- * @fn int8_t hif_check_compatibility(uint16_t u16HifInfo);
- * @brief
- * To check the compatibility of an image with the current driver.
- * @param [in] u16HifInfo
- * HIF info of image to be checked.
- * @return The function shall return ZERO for compatible image and a negative value otherwise.
- */
- int8_t hif_check_compatibility(uint16_t u16HifInfo)
- {
- int8_t ret = M2M_ERR_FW_VER_MISMATCH;
- if((M2M_GET_HIF_BLOCK(u16HifInfo) == M2M_HIF_BLOCK_VALUE) && (M2M_GET_HIF_MAJOR(u16HifInfo) == M2M_HIF_MAJOR_VALUE))
- {
- ret = M2M_SUCCESS;
- }
- return ret;
- }
-
- /**
- * @fn int8_t hif_enable_access(void);
- * @brief
- * To enable access to HIF layer, based on HIF level of Firmware.
- * This function reads HIF level directly from a register written by Firmware.
- * @return The function shall return ZERO for full match operation and a negative value if operation is restricted.
- */
- int8_t hif_enable_access(void)
- {
- int8_t ret = M2M_SUCCESS;
- uint16_t fw_hif_info = 0;
-
- ret = nm_get_hif_info(&fw_hif_info, NULL);
- if(ret == M2M_SUCCESS)
- {
- ret = hif_check_compatibility(fw_hif_info);
- if(ret == M2M_SUCCESS)
- {
- switch(M2M_GET_HIF_MINOR(fw_hif_info))
- {
- case 0:
- gu8HifBlOffset = 1;
- break;
- case 1:
- gu8HifBlOffset = 2;
- break;
- case 2:
- gu8HifBlOffset = 2;
- break;
- case 3:
- gu8HifBlOffset = 3;
- break;
- case 4:
- gu8HifBlOffset = 10;
- break;
- case 5:
- gu8HifBlOffset = 13;
- break;
- // Additional case to be added each time hif minor increments.
- // All additional cases to be removed in the event of a hif major increment.
- // Default catches all cases in which hif minor is greater in Firmware than in Driver.
- default:
- gu8HifBlOffset = HIF_BLACKLIST_SZ;
- break;
- }
- }
- else
- {
- gu8HifBlOffset = 0;
- M2M_ERR("HIF access limited to OTA Switch/Rollback only\r\n");
- }
- }
- return ret;
- }
-
- /**
- * @fn int8_t hif_check_code(uint8_t u8Gid, uint8_t u8OpCode);
- * @brief
- * To check that a particular hif message is supported with the current driver/firmware pair.
- * @param[in] u8Gid
- * Group ID.
- * @param[in] u8Opcode
- * Operation ID.
- * @return The function shall return @ref M2M_SUCCESS for success and a negative value otherwise.
- */
- int8_t hif_check_code(uint8_t u8Gid, uint8_t u8OpCode)
- {
- uint8_t u8BlId;
- uint16_t u16HifCode = ((uint16_t)u8Gid<<8) | u8OpCode;
- if((u16HifCode == HIFCODE_OTA_RB) || (u16HifCode == HIFCODE_OTA_SW))
- {
- return M2M_SUCCESS;
- }
- if(gu8HifBlOffset == 0)
- {
- M2M_ERR("HIF OTA rb/sw only\r\n");
- return M2M_ERR_SEND;
- }
- for(u8BlId = gu8HifBlOffset; u8BlId < HIF_BLACKLIST_SZ; u8BlId++)
- {
- if(u16HifCode == gau16HifBlacklist[u8BlId])
- {
- M2M_ERR("HIF message unsupported\r\n");
- return M2M_ERR_SEND;
- }
- }
- return M2M_SUCCESS;
- }
-
- /**
- * @fn int8_t hif_send(uint8_t u8Gid,uint8_t u8Opcode,uint8_t *pu8CtrlBuf,uint16_t u16CtrlBufSize,
- * uint8_t *pu8DataBuf,uint16_t u16DataSize, uint16_t u16DataOffset)
- * @brief Send packet using host interface.
- *
- * @param[in] u8Gid
- * Group ID.
- * @param[in] u8Opcode
- * Operation ID.
- * @param[in] pu8CtrlBuf
- * Pointer to the Control buffer.
- * @param[in] u16CtrlBufSize
- * Control buffer size.
- * @param[in] u16DataOffset
- * Packet Data offset.
- * @param[in] pu8DataBuf
- * Packet buffer Allocated by the caller.
- * @param[in] u16DataSize
- * Packet buffer size (including the HIF header).
- * @return The function shall return @ref M2M_SUCCESS for successful operation and a negative value otherwise.
- */
- int8_t hif_send(uint8_t u8Gid, uint8_t u8Opcode, uint8_t *pu8CtrlBuf, uint16_t u16CtrlBufSize,
- uint8_t *pu8DataBuf, uint16_t u16DataSize, uint16_t u16DataOffset)
- {
- int8_t ret = M2M_ERR_SEND;
- tstrHifHdr strHif;
- uint32_t u32CtrlDataGap = u16DataOffset;
-
- // while (OSAL_RESULT_FALSE == OSAL_SEM_Pend(&hifSemaphore, OSAL_WAIT_FOREVER))
- {
- }
-
- strHif.u8Opcode = u8Opcode&(~NBIT7);
- strHif.u8Gid = u8Gid;
- strHif.u16Length = M2M_HIF_HDR_OFFSET;
-
- if(pu8CtrlBuf != NULL)
- {
- if(u16CtrlBufSize > M2M_HIF_MAX_PACKET_SIZE-M2M_HIF_HDR_OFFSET)
- {
- M2M_ERR("HIF %s (%dB) exceeds max (%dB)\n", "Ctrl", u16CtrlBufSize, M2M_HIF_MAX_PACKET_SIZE-M2M_HIF_HDR_OFFSET);
- goto ERR2;
- }
- strHif.u16Length += u16CtrlBufSize;
- u32CtrlDataGap -= u16CtrlBufSize;
- }
- if(pu8DataBuf != NULL)
- {
- if((uint32_t)u16DataOffset + u16DataSize > M2M_HIF_MAX_PACKET_SIZE-M2M_HIF_HDR_OFFSET)
- {
- M2M_ERR("HIF %s (%luB) exceeds max (%luB)\n", "Data", (uint32_t)u16DataOffset + u16DataSize, (uint32_t)M2M_HIF_MAX_PACKET_SIZE-M2M_HIF_HDR_OFFSET);
- goto ERR2;
- }
- strHif.u16Length += u32CtrlDataGap + u16DataSize;
- }
-
- ret = hif_check_code(strHif.u8Gid, strHif.u8Opcode);
- if(ret != M2M_SUCCESS)
- {
- goto ERR2;
- }
-
- if(strHif.u16Length <= M2M_HIF_MAX_PACKET_SIZE)
- {
- ret = hif_chip_wake();
- if(ret == M2M_SUCCESS)
- {
- volatile uint32_t reg, dma_addr = 0;
- volatile uint16_t cnt = 0;
-
- reg = 0UL;
- reg |= (uint32_t)u8Gid;
- reg |= ((uint32_t)u8Opcode<<8);
- reg |= ((uint32_t)strHif.u16Length<<16);
- ret = nm_write_reg(NMI_STATE_REG, reg);
- if(M2M_SUCCESS != ret) goto ERR1;
-
- reg = 0UL;
- reg |= NBIT1;
- ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg);
- if(M2M_SUCCESS != ret) goto ERR1;
-
-
- if (ISNMC3400(nmi_get_chipid())) {
-
- ret = nm_write_reg(INTERRUPT_CORTUS_1_3000D0, 1);
- if(M2M_SUCCESS != ret) goto ERR1;
- }
-
- dma_addr = 0;
-
- for(cnt = 0; cnt < 1000*5; cnt ++)
- {
- ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_2, (uint32_t *)®);
- if(ret != M2M_SUCCESS) break;
- /*
- * If it takes too long to get a response, the slow down to
- * avoid back-to-back register read operations.
- */
- if(cnt >= 1000) {
- if(cnt == 1000) {
- M2M_INFO("Slowing down...\n");
- }
- nm_sleep(5);
- }
- if(!(reg & NBIT1))
- {
- ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_4, (uint32_t *)&dma_addr);
- if(ret != M2M_SUCCESS) {
- /*in case of read error clear the DMA address and return error*/
- dma_addr = 0;
- goto ERR1;
- }
- /*in case of success break */
- break;
- }
- }
-
- if (dma_addr != 0)
- {
- volatile uint32_t u32CurrAddr;
- u32CurrAddr = dma_addr;
- strHif.u16Length=NM_BSP_B_L_16(strHif.u16Length);
- M2M_DBG("Writing into %" PRIx32 " %d\r\n", dma_addr, strHif.u16Length);
- ret = nm_write_block(u32CurrAddr, (uint8_t*)&strHif, M2M_HIF_HDR_OFFSET);
- if(M2M_SUCCESS != ret) goto ERR1;
- u32CurrAddr += M2M_HIF_HDR_OFFSET;
- if(pu8CtrlBuf != NULL)
- {
- ret = nm_write_block(u32CurrAddr, pu8CtrlBuf, u16CtrlBufSize);
- if(M2M_SUCCESS != ret) goto ERR1;
- u32CurrAddr += u16CtrlBufSize;
- }
- if(pu8DataBuf != NULL)
- {
- u32CurrAddr += u32CtrlDataGap;
- ret = nm_write_block(u32CurrAddr, pu8DataBuf, u16DataSize);
- if(M2M_SUCCESS != ret) goto ERR1;
- u32CurrAddr += u16DataSize;
- }
-
- reg = dma_addr << 2;
-
- /* Following line of code is to generate the interrupt which is not strictly needed for 3400,
- but has no noticeable side effects
- */
- reg |= NBIT1;
- ret = nm_write_reg(WIFI_HOST_RCV_CTRL_3, reg);
- if(M2M_SUCCESS != ret) goto ERR1;
-
- if (ISNMC3400(nmi_get_chipid())) {
- ret = nm_write_reg(INTERRUPT_CORTUS_2_3000D0, 1);
- if(M2M_SUCCESS != ret) goto ERR1;
- }
- }
- else
- {
- ret = hif_chip_sleep();
- M2M_DBG("Failed to alloc rx size\r\n");
- ret = M2M_ERR_MEM_ALLOC;
- goto ERR2;
- }
- }
- else
- {
- M2M_ERR("(HIF)Failed to wakeup the chip\r\n");
- goto ERR2;
- }
- }
- else
- {
- M2M_ERR("HIF message length (%d) exceeds max length (%d)\r\n", strHif.u16Length, M2M_HIF_MAX_PACKET_SIZE);
- ret = M2M_ERR_SEND;
- goto ERR2;
- }
- // OSAL_SEM_Post(&hifSemaphore);
- /*actual sleep ret = M2M_SUCCESS*/
- ret = hif_chip_sleep();
- return ret;
- ERR1:
- /*reset the count but no actual sleep as it already bus error*/
- hif_chip_sleep_sc();
- ERR2:
- /*logical error*/
- // OSAL_SEM_Post(&hifSemaphore);
- return ret;
- }
- /**
- * @fn hif_isr
- * @brief Host interface interrupt service routine
- * @return @ref M2M_SUCCESS in case of success or a negative vale otherwise
- */
- static int8_t hif_isr(void)
- {
- int8_t ret = M2M_SUCCESS;
- uint32_t reg;
- volatile tstrHifHdr strHif;
-
- // while (OSAL_RESULT_FALSE == OSAL_SEM_Pend(&hifSemaphore, OSAL_WAIT_FOREVER))
- {
- }
-
- ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, ®);
- if(M2M_SUCCESS == ret)
- {
- if(reg & 0x1) /* New interrupt has been received */
- {
- uint16_t size;
-
- /*Clearing RX interrupt*/
- ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, ®);
- if(ret != M2M_SUCCESS)goto ERR1;
- reg &= ~NBIT0;
- ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0, reg);
- if(ret != M2M_SUCCESS)goto ERR1;
- /* read the rx size */
- ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, ®);
- if(M2M_SUCCESS != ret)
- {
- M2M_ERR("(hif) WIFI_HOST_RCV_CTRL_0 bus fail\r\n");
- goto ERR1;
- }
- gstrHifCxt.u8HifRXDone = 1;
- size = (uint16_t)((reg >> 2) & 0xfff);
- if (size > 0) {
- uint32_t address = 0;
- /**
- start bus transfer
- **/
- ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_1, &address);
- if(M2M_SUCCESS != ret)
- {
- M2M_ERR("(hif) WIFI_HOST_RCV_CTRL_1 bus fail\r\n");
- goto ERR1;
- }
- gstrHifCxt.u32RxAddr = address;
- gstrHifCxt.u32RxSize = size;
- ret = nm_read_block(address, (uint8_t*)&strHif, sizeof(tstrHifHdr));
- strHif.u16Length = NM_BSP_B_L_16(strHif.u16Length);
- if(M2M_SUCCESS != ret)
- {
- M2M_ERR("(hif) address bus fail\r\n");
- goto ERR1;
- }
- if(strHif.u16Length != size)
- {
- if((size - strHif.u16Length) > 4)
- {
- M2M_ERR("(hif) Corrupted packet Size = %u <L = %u, G = %u, OP = %02X>\r\n",
- size, strHif.u16Length, strHif.u8Gid, strHif.u8Opcode);
- ret = M2M_ERR_BUS_FAIL;
- goto ERR1;
- }
- }
-
- // OSAL_SEM_Post(&hifSemaphore);
-
- if(M2M_REQ_GROUP_WIFI == strHif.u8Gid)
- {
- if(gstrHifCxt.pfWifiCb)
- gstrHifCxt.pfWifiCb(strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
- else
- M2M_ERR("WIFI callback is not registered\r\n");
- }
- else if(M2M_REQ_GROUP_IP == strHif.u8Gid)
- {
- if(gstrHifCxt.pfIpCb)
- gstrHifCxt.pfIpCb(strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
- else
- M2M_ERR("Socket callback is not registered\r\n");
- }
- else if(M2M_REQ_GROUP_OTA == strHif.u8Gid)
- {
- if(gstrHifCxt.pfOtaCb)
- gstrHifCxt.pfOtaCb(strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
- else
- M2M_ERR("OTA callback is not registered\r\n");
- }
- else if(M2M_REQ_GROUP_SIGMA == strHif.u8Gid)
- {
- if(gstrHifCxt.pfSigmaCb)
- gstrHifCxt.pfSigmaCb(strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
- else
- M2M_ERR("Sigma callback is not registered\r\n");
- }
- else if(M2M_REQ_GROUP_SSL == strHif.u8Gid)
- {
- if(gstrHifCxt.pfSslCb)
- gstrHifCxt.pfSslCb(strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
- else
- M2M_ERR("SSL callback is not registered\r\n");
- }
- else
- {
- M2M_ERR("(hif) invalid group ID\r\n");
- return M2M_ERR_BUS_FAIL;
- }
- if(gstrHifCxt.u8HifRXDone)
- {
- M2M_ERR("(hif) host app didn't set RX Done <%u><%X>\n", strHif.u8Gid, strHif.u8Opcode);
- return hif_set_rx_done();
- }
-
- return M2M_SUCCESS;
- }
- else
- {
- ret = M2M_ERR_RCV;
- M2M_ERR("(hif) Wrong Size\r\n");
- goto ERR1;
- }
- }
- else
- {
- M2M_ERR("(hif) False interrupt %lx\r\n",reg);
- ret = M2M_ERR_FAIL;
- }
- }
- else
- {
- M2M_ERR("(hif) Failed to read interrupt reg\r\n");
- }
-
- ERR1:
- // OSAL_SEM_Post(&hifSemaphore);
- return ret;
- }
-
- /**
- * @fn hif_handle_isr(void)
- * @brief Handle interrupt received from WINC3400 firmware.
- * @return The function SHALL return 0 for success and a negative value otherwise.
- */
- int8_t hif_handle_isr(void)
- {
- int8_t ret = M2M_SUCCESS;
-
- ret = hif_isr();
- if (M2M_SUCCESS != ret)
- {
- M2M_ERR("(hif) Failed to handle interrupt %d try Again..\r\n",ret);
- }
-
- return ret;
- }
-
- /**
- * @fn hif_receive
- * @brief Host interface interrupt service routine
- * @param[in] u32Addr
- * Receive start address
- * @param[out] pu8Buf
- * Pointer to receive buffer. Allocated by the caller
- * @param[in] u16Sz
- * Receive buffer size
- * @param[in] isDone
- * If you don't need any more packets send True otherwise send false
- * @return The function shall return ZERO for successful operation and a negative value otherwise.
- */
- int8_t hif_receive(uint32_t u32Addr, uint8_t *pu8Buf, uint16_t u16Sz, uint8_t isDone)
- {
- int8_t ret = M2M_SUCCESS;
-
- if((u32Addr == 0) || (pu8Buf == NULL) || (u16Sz == 0))
- {
- if(isDone)
- {
- ret = hif_set_rx_done();
- }
- else
- {
- ret = M2M_ERR_FAIL;
- M2M_ERR(" hif_receive: Invalid argument\r\n");
- }
- goto ERR1;
- }
-
- if(u16Sz > gstrHifCxt.u32RxSize)
- {
- ret = M2M_ERR_FAIL;
- M2M_ERR("APP Requested Size is larger than the received buffer size <%d><%" PRId32 ">\r\n", u16Sz, gstrHifCxt.u32RxSize);
- goto ERR1;
- }
- if((u32Addr < gstrHifCxt.u32RxAddr)||((u32Addr + u16Sz)>(gstrHifCxt.u32RxAddr+gstrHifCxt.u32RxSize)))
- {
- ret = M2M_ERR_FAIL;
- M2M_ERR("APP Requested Address beyond the received buffer address and length\r\n");
- goto ERR1;
- }
-
- /* Receive the payload */
- ret = nm_read_block(u32Addr, pu8Buf, u16Sz);
- if(ret != M2M_SUCCESS)goto ERR1;
-
- /* check if this is the last packet */
- if(
- isDone
- || (((gstrHifCxt.u32RxAddr+gstrHifCxt.u32RxSize) - (u32Addr+u16Sz)) <= 3)
- /* Length in the RCV CTRL 0 register is rounded off to 4 by the firmware,
- but length inside the HIF header is not, hence consider done if fewer than
- 4 bytes left to read */
- )
- {
- /* set RX done */
- ret = hif_set_rx_done();
- }
- ERR1:
- return ret;
- }
-
- /**
- * @fn hif_register_cb
- * @brief To set Callback function for every component
- * @param[in] u8Grp
- * Group to which the Callback function should be set.
- * @param[in] fn
- * function to be set
- * @return The function shall return ZERO for successful operation and a negative value otherwise.
- */
-
- int8_t hif_register_cb(uint8_t u8Grp, tpfHifCallBack fn)
- {
- int8_t ret = M2M_SUCCESS;
- switch(u8Grp)
- {
- case M2M_REQ_GROUP_IP:
- gstrHifCxt.pfIpCb = fn;
- break;
- case M2M_REQ_GROUP_WIFI:
- gstrHifCxt.pfWifiCb = fn;
- break;
- case M2M_REQ_GROUP_OTA:
- gstrHifCxt.pfOtaCb = fn;
- break;
- case M2M_REQ_GROUP_HIF:
- gstrHifCxt.pfHifCb = fn;
- break;
- case M2M_REQ_GROUP_SIGMA:
- gstrHifCxt.pfSigmaCb = fn;
- break;
- case M2M_REQ_GROUP_SSL:
- gstrHifCxt.pfSslCb = fn;
- break;
- default:
- M2M_ERR("GRp ? %d\r\n", u8Grp);
- ret = M2M_ERR_FAIL;
- break;
- }
- return ret;
- }
-
- //DOM-IGNORE-END
|