sint8 cpu_start(void) { uint32 reg; sint8 ret; /** reset regs */ nm_write_reg(BOOTROM_REG,0); nm_write_reg(NMI_STATE_REG,0); nm_write_reg(NMI_REV_REG,0); /** Go... **/ ret = nm_read_reg_with_ret(0x1118, ®); if (M2M_SUCCESS != ret) { ret = M2M_ERR_BUS_FAIL; M2M_ERR("[nmi start]: fail read reg 0x1118 ...\n"); } reg |= (1 << 0); ret = nm_write_reg(0x1118, reg); ret = nm_write_reg(0x150014, 0x1); ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, ®); if ((reg & (1ul << 10)) == (1ul << 10)) { reg &= ~(1ul << 10); ret += nm_write_reg(NMI_GLB_RESET_0, reg); } reg |= (1ul << 10); ret += nm_write_reg(NMI_GLB_RESET_0, reg); nm_bsp_sleep(1); /* TODO: Why bus error if this delay is not here. */ return ret; }
sint8 nmi_get_mac_address(uint8 *pu8MacAddr) { sint8 ret; uint32 u32RegValue; uint8 mac[6]; tstrGpRegs strgp = {0}; ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &u32RegValue); if(ret != M2M_SUCCESS) goto _EXIT_ERR; #ifdef ARDUINO if (u32RegValue) { ret = nm_read_block(u32RegValue|0x30000,(uint8*)&strgp,sizeof(tstrGpRegs)); if(ret != M2M_SUCCESS) goto _EXIT_ERR; u32RegValue = strgp.u32Mac_efuse_mib; } else { // firmware version 19.3.0 ret = nm_read_reg_with_ret(rNMI_GP_REG_0, &u32RegValue); if(ret != M2M_SUCCESS) goto _EXIT_ERR; } #else ret = nm_read_block(u32RegValue|0x30000,(uint8*)&strgp,sizeof(tstrGpRegs)); if(ret != M2M_SUCCESS) goto _EXIT_ERR; u32RegValue = strgp.u32Mac_efuse_mib; #endif u32RegValue &=0x0000ffff; ret = nm_read_block(u32RegValue|0x30000, mac, 6); m2m_memcpy(pu8MacAddr, mac, 6); return ret; _EXIT_ERR: return ret; }
sint8 enable_interrupts(void) { uint32 reg; sint8 ret; /** interrupt pin mux select **/ ret = nm_read_reg_with_ret(NMI_PIN_MUX_0, ®); if (M2M_SUCCESS != ret) { return M2M_ERR_BUS_FAIL; } reg |= ((uint32) 1 << 8); ret = nm_write_reg(NMI_PIN_MUX_0, reg); if (M2M_SUCCESS != ret) { return M2M_ERR_BUS_FAIL; } /** interrupt enable **/ ret = nm_read_reg_with_ret(NMI_INTR_ENABLE, ®); if (M2M_SUCCESS != ret) { return M2M_ERR_BUS_FAIL; } reg |= ((uint32) 1 << 16); ret = nm_write_reg(NMI_INTR_ENABLE, reg); if (M2M_SUCCESS != ret) { return M2M_ERR_BUS_FAIL; } return M2M_SUCCESS; }
sint8 chip_reset_and_cpu_halt(void) { sint8 ret = M2M_SUCCESS; uint32 reg = 0; ret = chip_wake(); if(ret != M2M_SUCCESS) { return ret; } chip_reset(); ret = nm_read_reg_with_ret(0x1118, ®); if (M2M_SUCCESS != ret) { ret = M2M_ERR_BUS_FAIL; M2M_ERR("[nmi start]: fail read reg 0x1118 ...\n"); } reg |= (1 << 0); ret = nm_write_reg(0x1118, reg); ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, ®); if ((reg & (1ul << 10)) == (1ul << 10)) { reg &= ~(1ul << 10); ret += nm_write_reg(NMI_GLB_RESET_0, reg); ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, ®); } #if 0 reg |= (1ul << 10); ret += nm_write_reg(NMI_GLB_RESET_0, reg); ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, ®); #endif nm_write_reg(BOOTROM_REG,0); nm_write_reg(NMI_STATE_REG,0); nm_write_reg(NMI_REV_REG,0); nm_write_reg(NMI_PIN_MUX_0, 0x11111000); return ret; }
uint32 nmi_get_chipid(void) { static uint32 chipid = 0; if (chipid == 0) { //uint32 revid; uint32 rfrevid; if((nm_read_reg_with_ret(0x1000, &chipid)) != M2M_SUCCESS) { chipid = 0; return 0; } //if((ret = nm_read_reg_with_ret(0x11fc, &revid)) != M2M_SUCCESS) { // return 0; //} if((nm_read_reg_with_ret(0x13f4, &rfrevid)) != M2M_SUCCESS) { chipid = 0; return 0; } if (chipid == 0x1002a0) { if (rfrevid == 0x1) { /* 1002A0 */ } else { /* if (rfrevid == 0x2) */ /* 1002A1 */ chipid = 0x1002a1; } } else if(chipid == 0x1002b0) { if(rfrevid == 3) { /* 1002B0 */ } else if(rfrevid == 4) { /* 1002B1 */ chipid = 0x1002b1; } else { /* if(rfrevid == 5) */ /* 1002B2 */ chipid = 0x1002b2; } } else { } //#define PROBE_FLASH #ifdef PROBE_FLASH if(chipid) { UWORD32 flashid; flashid = probe_spi_flash(); if(flashid == 0x1230ef) { chipid &= ~(0x0f0000); chipid |= 0x050000; } if(flashid == 0xc21320c2) { chipid &= ~(0x0f0000); chipid |= 0x050000; } } #else /*M2M is by default have SPI flash*/ chipid &= ~(0x0f0000); chipid |= 0x050000; #endif /* PROBE_FLASH */ } return chipid; }
sint8 hif_chip_sleep(void) { sint8 ret = M2M_SUCCESS; if(gu8ChipSleep >= 1) { gu8ChipSleep--; } if(gu8ChipSleep == 0) { if((gu8ChipMode == M2M_PS_DEEP_AUTOMATIC)||(gu8ChipMode == M2M_PS_MANUAL)) { uint32 reg = 0; ret = nm_write_reg(WAKE_REG, SLEEP_VALUE); if(ret != M2M_SUCCESS)goto ERR1; /* Clear bit 1 */ ret = nm_read_reg_with_ret(0x1, ®); if(ret != M2M_SUCCESS)goto ERR1; if(reg&0x2) { reg &=~(1 << 1); ret = nm_write_reg(0x1, reg); } } else { } } ERR1: return ret; }
/** * @fn nm_get_firmware_info(tstrM2mRev* M2mRev) * @brief Get Firmware version info * @param [out] M2mRev * pointer holds address of structure "tstrM2mRev" that contains the firmware version parameters * @author Ahmad.Mohammad.Yahya * @date 27 MARCH 2013 * @version 1.0 */ sint8 nm_get_firmware_info(tstrM2mRev* M2mRev) { uint16 curr_drv_ver, min_req_drv_ver,curr_firm_ver; uint32 reg = 0; sint8 ret = M2M_SUCCESS; ret = nm_read_reg_with_ret(NMI_REV_REG, ®); M2mRev->u8DriverMajor = M2M_GET_DRV_MAJOR(reg); M2mRev->u8DriverMinor = M2M_GET_DRV_MINOR(reg); M2mRev->u8DriverPatch = M2M_GET_DRV_PATCH(reg); M2mRev->u8FirmwareMajor = M2M_GET_FW_MAJOR(reg); M2mRev->u8FirmwareMinor = M2M_GET_FW_MINOR(reg); M2mRev->u8FirmwarePatch = M2M_GET_FW_PATCH(reg); M2mRev->u32Chipid = nmi_get_chipid(); curr_firm_ver = M2M_MAKE_VERSION(M2mRev->u8FirmwareMajor, M2mRev->u8FirmwareMinor,M2mRev->u8FirmwarePatch); curr_drv_ver = M2M_MAKE_VERSION(M2M_DRIVER_VERSION_MAJOR_NO, M2M_DRIVER_VERSION_MINOR_NO, M2M_DRIVER_VERSION_PATCH_NO); min_req_drv_ver = M2M_MAKE_VERSION(M2mRev->u8DriverMajor, M2mRev->u8DriverMinor,M2mRev->u8DriverPatch); if(curr_drv_ver < min_req_drv_ver) { /*The current driver version should be larger or equal than the min driver that the current firmware support */ ret = M2M_ERR_FW_VER_MISMATCH; } if(curr_drv_ver > curr_firm_ver) { /*The current driver should be equal or less than the firmware version*/ ret = M2M_ERR_FW_VER_MISMATCH; } return ret; }
static void chip_apply_conf(void) { sint8 ret = M2M_SUCCESS; uint32 val32; val32 = 0; #ifdef __ENABLE_PMU__ val32 |= rHAVE_USE_PMU_BIT; #endif #ifdef __ENABLE_SLEEP_CLK_SRC_RTC__ val32 |= rHAVE_SLEEP_CLK_SRC_RTC; #elif defined __ENABLE_SLEEP_CLK_SRC_XO__ val32 |= rHAVE_SLEEP_CLK_SRC_XO; #endif #ifdef __ENABLE_EXT_PA_INV_TX_RX__ val32 |= rHAVE_EXT_PA_INV_TX_RX; #endif #ifdef __ENABLE_LEGACY_RF_SETTINGS__ val32 |= rHAVE_LEGACY_RF_SETTINGS; #endif do { nm_write_reg(rNMI_GP_REG_1, val32); if(val32 != 0) { uint32 reg = 0; ret = nm_read_reg_with_ret(rNMI_GP_REG_1, ®); if(ret == M2M_SUCCESS) { if(reg == val32) break; } } else { break; } } while(1); }
/** * @fn spi_flash_page_program * @brief Write data (less than page size) from cortus memory to SPI flash * @param[IN] u32MemAdr * Cortus data address. It must be set to its AHB access address * @param[IN] u32FlashAdr * Address to write to at the SPI flash * @param[IN] u32Sz * Data size */ static sint8 spi_flash_page_program(uint32 u32MemAdr, uint32 u32FlashAdr, uint32 u32Sz) { uint8 cmd[4]; uint32 val = 0; sint8 ret = M2M_SUCCESS; cmd[0] = 0x02; cmd[1] = (uint8)(u32FlashAdr >> 16); cmd[2] = (uint8)(u32FlashAdr >> 8); cmd[3] = (uint8)(u32FlashAdr); ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0); ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]|(cmd[1]<<8)|(cmd[2]<<16)|(cmd[3]<<24)); ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x0f); ret += nm_write_reg(SPI_FLASH_DMA_ADDR, u32MemAdr); ret += nm_write_reg(SPI_FLASH_CMD_CNT, 4 | (1<<7) | ((u32Sz & 0xfffff) << 8)); do { ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val); if(M2M_SUCCESS != ret) break; } while(val != 1); return ret; }
/** * @fn spi_flash_rdid * @brief Read SPI Flash ID * @return SPI FLash ID */ static uint32 spi_flash_rdid(void) { unsigned char cmd[1]; uint32 reg = 0; uint32 cnt = 0; sint8 ret = M2M_SUCCESS; cmd[0] = 0x9f; ret += nm_write_reg(SPI_FLASH_DATA_CNT, 4); ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]); ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x1); ret += nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER); ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7)); do { ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)®); if(M2M_SUCCESS != ret) break; if(++cnt > 500) { ret = M2M_ERR_INIT; break; } } while(reg != 1); reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0); M2M_PRINT("Flash ID %x \n",(unsigned int)reg); return reg; }
/** * @fn spi_flash_enable * @brief Enable spi flash operations */ sint8 spi_flash_enable(uint8 enable) { sint8 s8Ret = M2M_SUCCESS; if(REV(nmi_get_chipid()) >= REV_3A0) { uint32 u32Val; /* Enable pinmux to SPI flash. */ s8Ret = nm_read_reg_with_ret(0x1410, &u32Val); if(s8Ret != M2M_SUCCESS) { goto ERR1; } /* GPIO15/16/17/18 */ u32Val &= ~((0x7777ul) << 12); u32Val |= ((0x1111ul) << 12); nm_write_reg(0x1410, u32Val); if(enable) { spi_flash_leave_low_power_mode(); } else { spi_flash_enter_low_power_mode(); } /* Disable pinmux to SPI flash to minimize leakage. */ u32Val &= ~((0x7777ul) << 12); u32Val |= ((0x0010ul) << 12); nm_write_reg(0x1410, u32Val); } ERR1: return s8Ret; }
sint8 nmi_get_otp_mac_address(uint8 *pu8MacAddr, uint8 * pu8IsValid) { sint8 ret; uint32 u32RegValue; uint8 mac[6]; ret = nm_read_reg_with_ret(rNMI_GP_REG_0, &u32RegValue); if(ret != M2M_SUCCESS) goto _EXIT_ERR; if(!EFUSED_MAC(u32RegValue)) { M2M_DBG("Default MAC\n"); m2m_memset(pu8MacAddr, 0, 6); goto _EXIT_ERR; } M2M_DBG("OTP MAC\n"); u32RegValue >>=16; nm_read_block(u32RegValue|0x30000, mac, 6); m2m_memcpy(pu8MacAddr,mac,6); if(pu8IsValid) *pu8IsValid = 1; return ret; _EXIT_ERR: if(pu8IsValid) *pu8IsValid = 0; return ret; }
sint8 nmi_get_otp_mac_address(uint8 *pu8MacAddr, uint8 * pu8IsValid) { sint8 ret; uint32 u32RegValue; uint8 mac[6]; tstrGpRegs strgp = {0}; ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &u32RegValue); if(ret != M2M_SUCCESS) goto _EXIT_ERR; ret = nm_read_block(u32RegValue|0x30000,(uint8*)&strgp,sizeof(tstrGpRegs)); if(ret != M2M_SUCCESS) goto _EXIT_ERR; u32RegValue = strgp.u32Mac_efuse_mib; if(!EFUSED_MAC(u32RegValue)) { M2M_DBG("Default MAC\n"); m2m_memset(pu8MacAddr, 0, 6); goto _EXIT_ERR; } M2M_DBG("OTP MAC\n"); u32RegValue >>=16; ret = nm_read_block(u32RegValue|0x30000, mac, 6); m2m_memcpy(pu8MacAddr,mac,6); if(pu8IsValid) *pu8IsValid = 1; return ret; _EXIT_ERR: if(pu8IsValid) *pu8IsValid = 0; return ret; }
/** * @fn spi_flash_load_to_cortus_mem * @brief Load data from SPI flash into cortus memory * @param[IN] u32MemAdr * Cortus load address. It must be set to its AHB access address * @param[IN] u32FlashAdr * Address to read from at the SPI flash * @param[IN] u32Sz * Data size * @return Status of execution */ static sint8 spi_flash_load_to_cortus_mem(uint32 u32MemAdr, uint32 u32FlashAdr, uint32 u32Sz) { uint8 cmd[5]; uint32 val = 0; sint8 ret = M2M_SUCCESS; cmd[0] = 0x0b; cmd[1] = (uint8)(u32FlashAdr >> 16); cmd[2] = (uint8)(u32FlashAdr >> 8); cmd[3] = (uint8)(u32FlashAdr); cmd[4] = 0xA5; ret += nm_write_reg(SPI_FLASH_DATA_CNT, u32Sz); ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]|(cmd[1]<<8)|(cmd[2]<<16)|(cmd[3]<<24)); ret += nm_write_reg(SPI_FLASH_BUF2, cmd[4]); ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x1f); ret += nm_write_reg(SPI_FLASH_DMA_ADDR, u32MemAdr); ret += nm_write_reg(SPI_FLASH_CMD_CNT, 5 | (1<<7)); do { ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val); if(M2M_SUCCESS != ret) break; } while(val != 1); return ret; }
uint32 nmi_get_rfrevid(void) { uint32 rfrevid; if((nm_read_reg_with_ret(0x13f4, &rfrevid)) != M2M_SUCCESS) { rfrevid = 0; return 0; } return rfrevid; }
void chip_idle(void) { uint32 reg =0; nm_read_reg_with_ret(0x1, ®); if(reg&0x2) { reg &=~(1 << 1); nm_write_reg(0x1, reg); } }
sint8 chip_deinit(void) { uint32 reg = 0; sint8 ret; uint8 timeout = 10; /** stop the firmware, need a re-download **/ ret = nm_read_reg_with_ret(NMI_GLB_RESET_0, ®); if (ret != M2M_SUCCESS) { M2M_ERR("failed to de-initialize\n"); } reg &= ~(1 << 10); ret = nm_write_reg(NMI_GLB_RESET_0, reg); if (ret != M2M_SUCCESS) { M2M_ERR("Error while writing reg\n"); return ret; } do { ret = nm_read_reg_with_ret(NMI_GLB_RESET_0, ®); if (ret != M2M_SUCCESS) { M2M_ERR("Error while reading reg\n"); return ret; } /*Workaround to ensure that the chip is actually reset*/ if ((reg & (1 << 10))) { M2M_DBG("Bit 10 not reset retry %d\n", timeout); reg &= ~(1 << 10); ret = nm_write_reg(NMI_GLB_RESET_0, reg); timeout--; } else { break; } } while (timeout); return ret; }
sint8 get_gpio_val(uint8 gpio, uint8* val) { uint32 val32; sint8 ret; ret = nm_read_reg_with_ret(0x20104, &val32); if(ret != M2M_SUCCESS) goto _EXIT; *val = (uint8)((val32 >> gpio) & 0x01); _EXIT: return ret; }
sint8 nmi_get_mac_address(uint8 *pu8MacAddr) { sint8 ret; uint32 u32RegValue; uint8 mac[6]; ret = nm_read_reg_with_ret(rNMI_GP_REG_0, &u32RegValue); if(ret != M2M_SUCCESS) goto _EXIT_ERR; u32RegValue &=0x0000ffff; nm_read_block(u32RegValue|0x30000, mac, 6); m2m_memcpy(pu8MacAddr, mac, 6); return ret; _EXIT_ERR: return ret; }
sint8 set_gpio_val(uint8 gpio, uint8 val) { uint32 val32; sint8 ret; ret = nm_read_reg_with_ret(0x20100, &val32); if(ret != M2M_SUCCESS) goto _EXIT; if(val) { val32 |= (1ul << gpio); } else { val32 &= ~(1ul << gpio); } ret = nm_write_reg(0x20100, val32); _EXIT: return ret; }
/** * @fn spi_flash_write_disable * @brief Send write disable command to SPI flash */ static sint8 spi_flash_write_disable(void) { uint8 cmd[1]; uint32 val = 0; sint8 ret = M2M_SUCCESS; cmd[0] = 0x04; ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0); ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]); ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01); ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0); ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7)); do { ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val); if(M2M_SUCCESS != ret) break; } while(val != 1); return ret; }
static sint8 hif_set_rx_done(void) { uint32 reg; sint8 ret = M2M_SUCCESS; gstrHifCxt.u8HifRXDone = 0; #ifdef NM_EDGE_INTERRUPT nm_bsp_interrupt_ctrl(1); #endif 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; #ifdef NM_LEVEL_INTERRUPT nm_bsp_interrupt_ctrl(1); #endif ERR1: return ret; }
sint8 pullup_ctrl(uint32 pinmask, uint8 enable) { sint8 s8Ret; uint32 val32; s8Ret = nm_read_reg_with_ret(0x142c, &val32); if(s8Ret != M2M_SUCCESS) { M2M_ERR("[pullup_ctrl]: failed to read\n"); goto _EXIT; } if(enable) { val32 &= ~pinmask; } else { val32 |= pinmask; } s8Ret = nm_write_reg(0x142c, val32); if(s8Ret != M2M_SUCCESS) { M2M_ERR("[pullup_ctrl]: failed to write\n"); goto _EXIT; } _EXIT: return s8Ret; }
sint8 chip_apply_conf(uint32 u32Conf) { sint8 ret = M2M_SUCCESS; uint32 val32 = u32Conf; #ifdef __ENABLE_PMU__ val32 |= rHAVE_USE_PMU_BIT; #endif #ifdef __ENABLE_SLEEP_CLK_SRC_RTC__ val32 |= rHAVE_SLEEP_CLK_SRC_RTC_BIT; #elif defined __ENABLE_SLEEP_CLK_SRC_XO__ val32 |= rHAVE_SLEEP_CLK_SRC_XO_BIT; #endif #ifdef __ENABLE_EXT_PA_INV_TX_RX__ val32 |= rHAVE_EXT_PA_INV_TX_RX; #endif #ifdef __ENABLE_LEGACY_RF_SETTINGS__ val32 |= rHAVE_LEGACY_RF_SETTINGS; #endif #ifdef __DISABLE_FIRMWARE_LOGS__ val32 |= rHAVE_LOGS_DISABLED_BIT; #endif do { nm_write_reg(rNMI_GP_REG_1, val32); if(val32 != 0) { uint32 reg = 0; ret = nm_read_reg_with_ret(rNMI_GP_REG_1, ®); if(ret == M2M_SUCCESS) { if(reg == val32) break; } } else { break; } } while(1); return M2M_SUCCESS; }
sint8 nmi_get_mac_address(uint8 *pu8MacAddr) { sint8 ret; uint32 u32RegValue; uint8 mac[6]; tstrGpRegs strgp = {0}; ret = nm_read_reg_with_ret(rNMI_GP_REG_0, &u32RegValue); if(ret != M2M_SUCCESS) goto _EXIT_ERR; ret = nm_read_block(u32RegValue|0x30000,(uint8*)&strgp,sizeof(tstrGpRegs)); if(ret != M2M_SUCCESS) goto _EXIT_ERR; u32RegValue = strgp.u32Mac_efuse_mib; u32RegValue &=0x0000ffff; ret = nm_read_block(u32RegValue|0x30000, mac, 6); m2m_memcpy(pu8MacAddr, mac, 6); return ret; _EXIT_ERR: return ret; }
/** * @fn spi_flash_read_security_reg * @brief Read security register * @return Security register value */ static uint8 spi_flash_read_security_reg(void) { uint8 cmd[1]; uint32 reg; sint8 ret = M2M_SUCCESS; cmd[0] = 0x2b; ret += nm_write_reg(SPI_FLASH_DATA_CNT, 1); ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]); ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01); ret += nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER); ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7)); do { ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)®); if(M2M_SUCCESS != ret) break; } while(reg != 1); reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0); return (sint8)reg & 0xff; }
sint8 wait_for_firmware_start(uint8 arg) { sint8 ret = M2M_SUCCESS; uint32 reg = 0, cnt = 0; volatile uint32 regAddress = NMI_STATE_REG; volatile uint32 checkValue = M2M_FINISH_INIT_STATE; if(2 == arg) { regAddress = NMI_REV_REG; checkValue = M2M_ATE_FW_IS_UP_VALUE; } else { /*bypass this step*/ } while (checkValue != reg) { nm_bsp_sleep(2); /* TODO: Why bus error if this delay is not here. */ M2M_DBG("%x %x %x\n",(unsigned int)nm_read_reg(0x108c),(unsigned int)nm_read_reg(0x108c),(unsigned int)nm_read_reg(0x14A0)); if (nm_read_reg_with_ret(regAddress, ®) != M2M_SUCCESS) { // ensure reg != checkValue reg = !checkValue; } if(++cnt > TIMEOUT) { M2M_DBG("Time out for wait firmware Run\n"); ret = M2M_ERR_INIT; goto ERR; } } if(M2M_FINISH_INIT_STATE == checkValue) { nm_write_reg(NMI_STATE_REG, 0); } ERR: return ret; }
/** * @fn spi_flash_read_status_reg * @brief Read status register * @param[OUT] val value of status reg * @return Status of execution */ static sint8 spi_flash_read_status_reg(uint8 * val) { sint8 ret = M2M_SUCCESS; uint8 cmd[1]; uint32 reg; cmd[0] = 0x05; ret += nm_write_reg(SPI_FLASH_DATA_CNT, 4); ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]); ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01); ret += nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER); ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7)); do { ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)®); if(M2M_SUCCESS != ret) break; } while(reg != 1); reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0); *val = (uint8)(reg & 0xff); 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_SUCCESS; uint32 reg; volatile tstrHifHdr strHif; 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 &= ~NBIT0; ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0,reg); if(ret != M2M_SUCCESS)goto ERR1; gstrHifCxt.u8HifRXDone = 1; 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; } gstrHifCxt.u32RxAddr = address; gstrHifCxt.u32RxSize = size; 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(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\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("Scoket callback is not registered\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\n"); } else if(M2M_REQ_GROUP_CRYPTO == strHif.u8Gid) { if(gstrHifCxt.pfCryptoCb) gstrHifCxt.pfCryptoCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET); else M2M_ERR("Crypto callback is not registered\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\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("(hif) invalid group ID\n"); ret = M2M_ERR_BUS_FAIL; goto ERR1; } if(gstrHifCxt.u8HifRXDone) { M2M_ERR("(hif) host app didn't set RX Done <%u><%X>\n", strHif.u8Gid, strHif.u8Opcode); ret = hif_set_rx_done(); if(ret != M2M_SUCCESS) goto ERR1; } } else { M2M_ERR("(hif) Wrong Size\n"); ret = M2M_ERR_RCV; 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; //#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; }