/** * @fn NMI_API sint8 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. */ sint8 hif_deinit(void * arg) { sint8 ret = M2M_SUCCESS; #if 0 uint32 reg = 0, cnt=0; while (reg != M2M_DISABLE_PS) { nm_bsp_sleep(1); reg = nm_read_reg(STATE_REG); if(++cnt > 1000) { M2M_DBG("failed to stop power save\n"); break; } } #endif ret = hif_chip_wake(); gu8ChipMode = 0; gu8ChipSleep = 0; gu8HifSizeDone = 0; gu8Interrupt = 0; pfWifiCb = NULL; pfIpCb = NULL; pfOtaCb = NULL; pfHifCb = NULL; return ret; }
/** * @fn NMI_API sint8 hif_deinit(void * arg); * @brief To De-initialize HIF layer. * @param [in] arg * Pointer to the arguments. * @return The function shall return ZERO for successful operation and a negative value otherwise. */ sint8 hif_deinit(void * arg) { sint8 ret = M2M_SUCCESS; ret = hif_chip_wake(); m2m_memset((uint8*)&gstrHifCxt,0,sizeof(tstrHifContext)); return ret; }
/*! @fn \ NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev); @brief Get the OTA Firmware version. @return The function SHALL return 0 for success and a negative value otherwise. */ NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev) { sint8 ret = M2M_SUCCESS; ret = hif_chip_wake(); if(ret == M2M_SUCCESS) { ret = nm_get_ota_firmware_info(pstrRev); hif_chip_sleep(); } return ret; }
sint8 m2m_wifi_get_otp_mac_address(uint8 *pu8MacAddr, uint8* pu8IsValid) { sint8 ret = M2M_SUCCESS; ret = hif_chip_wake(); if(ret == M2M_SUCCESS) { ret = nmi_get_otp_mac_address(pu8MacAddr, pu8IsValid); if(ret == M2M_SUCCESS) { ret = hif_chip_sleep(); } } return ret; }
/** * \brief GPIO read/write skeleton with wakeup/sleep capability. */ static sint8 gpio_ioctl(uint8 op, uint8 u8GpioNum, uint8 u8InVal, uint8 * pu8OutVal) { sint8 ret, gpio; ret = hif_chip_wake(); if(ret != M2M_SUCCESS) goto _EXIT; gpio = get_gpio_idx(u8GpioNum); if(gpio < 0) goto _EXIT1; if(op == GPIO_OP_DIR) { ret = set_gpio_dir((uint8)gpio, u8InVal); } else if(op == GPIO_OP_SET) { ret = set_gpio_val((uint8)gpio, u8InVal); } else if(op == GPIO_OP_GET) { ret = get_gpio_val((uint8)gpio, pu8OutVal); } if(ret != M2M_SUCCESS) goto _EXIT1; _EXIT1: ret = hif_chip_sleep(); _EXIT: return ret; }
sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize, uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset) { sint8 ret = M2M_ERR_SEND; volatile tstrHifHdr strHif; strHif.u8Opcode = u8Opcode&(~NBIT7); strHif.u8Gid = u8Gid; strHif.u16Length = M2M_HIF_HDR_OFFSET; if(pu8DataBuf != NULL) { strHif.u16Length += u16DataOffset + u16DataSize; } else { strHif.u16Length += u16CtrlBufSize; } ret = hif_chip_wake(); if(ret == M2M_SUCCESS) { volatile uint32 reg, dma_addr = 0; volatile uint16 cnt = 0; //#define OPTIMIZE_BUS /*please define in firmware also*/ #ifndef OPTIMIZE_BUS reg = 0UL; reg |= (uint32)u8Gid; reg |= ((uint32)u8Opcode<<8); reg |= ((uint32)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; #else reg = 0UL; reg |= NBIT1; reg |= ((u8Opcode & NBIT7) ? (NBIT2):(0)); /*Data = 1 or config*/ reg |= (u8Gid == M2M_REQ_GROUP_IP) ? (NBIT3):(0); /*IP = 1 or non IP*/ reg |= ((uint32)strHif.u16Length << 4); /*length of pkt max = 4096*/ ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg); if(M2M_SUCCESS != ret) goto ERR1; #endif dma_addr = 0; for(cnt = 0; cnt < 1000; cnt ++) { ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_2,(uint32 *)®); 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 >= 500) { if(cnt < 501) { M2M_INFO("Slowing down...\n"); } nm_bsp_sleep(1); } if (!(reg & NBIT1)) { ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_4,(uint32 *)&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 u32CurrAddr; u32CurrAddr = dma_addr; strHif.u16Length=NM_BSP_B_L_16(strHif.u16Length); ret = nm_write_block(u32CurrAddr, (uint8*)&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 += (u16DataOffset - u16CtrlBufSize); ret = nm_write_block(u32CurrAddr, pu8DataBuf, u16DataSize); if(M2M_SUCCESS != ret) goto ERR1; u32CurrAddr += u16DataSize; } reg = dma_addr << 2; reg |= NBIT1; ret = nm_write_reg(WIFI_HOST_RCV_CTRL_3, reg); if(M2M_SUCCESS != ret) goto ERR1; } else { ret = hif_chip_sleep(); M2M_DBG("Failed to alloc rx size %d\r",ret); ret = M2M_ERR_MEM_ALLOC; goto ERR2; } } else { M2M_ERR("(HIF)Fail to wakup the chip\n"); goto ERR2; } /*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*/ return ret; }
/** * @fn hif_isr * @brief Host interface interrupt service routine * @author M. Abdelmawla * @date 15 July 2012 * @return 1 in case of interrupt received else 0 will be returned * @version 1.0 */ static sint8 hif_isr(void) { sint8 ret = M2M_ERR_BUS_FAIL; uint32 reg; volatile tstrHifHdr strHif; ret = hif_chip_wake(); if(ret == M2M_SUCCESS) { ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, ®); if(M2M_SUCCESS == ret) { if(reg & 0x1) /* New interrupt has been received */ { uint16 size; nm_bsp_interrupt_ctrl(0); /*Clearing RX interrupt*/ reg &= ~(1<<0); ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0,reg); if(ret != M2M_SUCCESS)goto ERR1; gu8HifSizeDone = 0; size = (uint16)((reg >> 2) & 0xfff); if (size > 0) { uint32 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\n"); nm_bsp_interrupt_ctrl(1); goto ERR1; } ret = nm_read_block(address, (uint8*)&strHif, sizeof(tstrHifHdr)); strHif.u16Length = NM_BSP_B_L_16(strHif.u16Length); if(M2M_SUCCESS != ret) { M2M_ERR("(hif) address bus fail\n"); nm_bsp_interrupt_ctrl(1); goto ERR1; } if(strHif.u16Length != size) { if((size - strHif.u16Length) > 4) { M2M_ERR("(hif) Corrupted packet Size = %u <L = %u, G = %u, OP = %02X>\n", size, strHif.u16Length, strHif.u8Gid, strHif.u8Opcode); nm_bsp_interrupt_ctrl(1); ret = M2M_ERR_BUS_FAIL; goto ERR1; } } if(M2M_REQ_GROUP_WIFI == strHif.u8Gid) { if(pfWifiCb) pfWifiCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET); } else if(M2M_REQ_GROUP_IP == strHif.u8Gid) { if(pfIpCb) pfIpCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET); } else if(M2M_REQ_GROUP_OTA == strHif.u8Gid) { if(pfOtaCb) pfOtaCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET); } else if(M2M_REQ_GROUP_CRYPTO == strHif.u8Gid) { if(pfCryptoCb) pfCryptoCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET); } else if(M2M_REQ_GROUP_SIGMA == strHif.u8Gid) { if(pfSigmaCb) pfSigmaCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET); } else { M2M_ERR("(hif) invalid group ID\n"); ret = M2M_ERR_BUS_FAIL; goto ERR1; } #ifndef ENABLE_UNO_BOARD if(!gu8HifSizeDone) { M2M_ERR("(hif) host app didn't set RX Done\n"); ret = hif_set_rx_done(); } #endif } else { ret = M2M_ERR_RCV; M2M_ERR("(hif) Wrong Size\n"); goto ERR1; } } else {
sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize, uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset) { sint8 ret = M2M_ERR_SEND; volatile tstrHifHdr strHif; strHif.u8Opcode = u8Opcode&(~NBIT7); strHif.u8Gid = u8Gid; strHif.u16Length = M2M_HIF_HDR_OFFSET; if(pu8DataBuf != NULL) { strHif.u16Length += u16DataOffset + u16DataSize; } else { strHif.u16Length += u16CtrlBufSize; } ret = hif_chip_wake(); if(ret == M2M_SUCCESS) { volatile uint32 reg, dma_addr = 0; volatile uint16 cnt = 0; reg = 0UL; reg |= (uint32)u8Gid; reg |= ((uint32)u8Opcode<<8); reg |= ((uint32)strHif.u16Length<<16); ret = nm_write_reg(NMI_STATE_REG,reg); if(M2M_SUCCESS != ret) goto ERR1; reg = 0; reg |= (1<<1); ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg); if(M2M_SUCCESS != ret) goto ERR1; dma_addr = 0; //nm_bsp_interrupt_ctrl(0); for(cnt = 0; cnt < 1000; cnt ++) { ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_2,(uint32 *)®); if(ret != M2M_SUCCESS) break; if (!(reg & 0x2)) { ret = nm_read_reg_with_ret(0x150400,(uint32 *)&dma_addr); if(ret != M2M_SUCCESS) { /*in case of read error clear the dma address and return error*/ dma_addr = 0; } /*in case of success break */ break; } } //nm_bsp_interrupt_ctrl(1); if (dma_addr != 0) { volatile uint32 u32CurrAddr; u32CurrAddr = dma_addr; strHif.u16Length=NM_BSP_B_L_16(strHif.u16Length); ret = nm_write_block(u32CurrAddr, (uint8*)&strHif, M2M_HIF_HDR_OFFSET); #ifdef CONF_WINC_USE_I2C nm_bsp_sleep(1); #endif if(M2M_SUCCESS != ret) goto ERR1; u32CurrAddr += M2M_HIF_HDR_OFFSET; if(pu8CtrlBuf != NULL) { ret = nm_write_block(u32CurrAddr, pu8CtrlBuf, u16CtrlBufSize); #ifdef CONF_WINC_USE_I2C nm_bsp_sleep(1); #endif if(M2M_SUCCESS != ret) goto ERR1; u32CurrAddr += u16CtrlBufSize; } if(pu8DataBuf != NULL) { u32CurrAddr += (u16DataOffset - u16CtrlBufSize); ret = nm_write_block(u32CurrAddr, pu8DataBuf, u16DataSize); #ifdef CONF_WINC_USE_I2C nm_bsp_sleep(1); #endif if(M2M_SUCCESS != ret) goto ERR1; u32CurrAddr += u16DataSize; } reg = dma_addr << 2; reg |= (1 << 1); ret = nm_write_reg(WIFI_HOST_RCV_CTRL_3, reg); if(M2M_SUCCESS != ret) goto ERR1; } else { M2M_DBG("Failed to alloc rx size\r"); ret = M2M_ERR_MEM_ALLOC; goto ERR1; } } else { M2M_ERR("(HIF)Fail to wakup the chip\n"); goto ERR1; } ret = hif_chip_sleep(); ERR1: return ret; }