/** * @fn nm_bsp_reset * @brief Reset NMC1500 SoC by setting CHIP_EN and RESET_N signals low, * CHIP_EN high then RESET_N high * @author M. Abdelmawla * @date 11 July 2012 * @version 1.0 */ void nm_bsp_reset(void) { digitalWrite(gi8Winc1501ResetPin, LOW); nm_bsp_sleep(100); digitalWrite(gi8Winc1501ResetPin, HIGH); nm_bsp_sleep(100); }
sint8 wait_for_bootrom(uint8 arg) { sint8 ret = M2M_SUCCESS; uint32 reg = 0, cnt = 0; reg = 0; while(1) { reg = nm_read_reg(0x1014); /* wait for efuse loading done */ if (reg & 0x80000000) { break; } nm_bsp_sleep(1); /* TODO: Why bus error if this delay is not here. */ } reg = nm_read_reg(M2M_WAIT_FOR_HOST_REG); reg &= 0x1; /* check if waiting for the host will be skipped or not */ if(reg == 0) { reg = 0; while(reg != M2M_FINISH_BOOT_ROM) { nm_bsp_sleep(1); reg = nm_read_reg(BOOTROM_REG); if(++cnt > TIMEOUT) { M2M_DBG("failed to load firmware from flash.\n"); ret = M2M_ERR_INIT; goto ERR2; } } } if(2 == arg) { nm_write_reg(NMI_REV_REG, M2M_ATE_FW_START_VALUE); } else { /*bypass this step*/ } if(REV(nmi_get_chipid()) == REV_3A0) { chip_apply_conf(rHAVE_USE_PMU_BIT); } else { chip_apply_conf(0); } nm_write_reg(BOOTROM_REG,M2M_START_FIRMWARE); #ifdef __ROM_TEST__ rom_test(); #endif /* __ROM_TEST__ */ ERR2: return ret; }
/** * @fn nm_bsp_reset * @brief Reset NMC1500 SoC by setting CHIP_EN and RESET_N signals low, * CHIP_EN high then RESET_N high */ void nm_bsp_reset(void) { port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false); port_pin_set_output_level(CONF_WINC_PIN_RESET, false); nm_bsp_sleep(100); port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, true); nm_bsp_sleep(100); port_pin_set_output_level(CONF_WINC_PIN_RESET, true); nm_bsp_sleep(100); }
/** * @fn nm_bsp_reset * @brief Reset NMC1500 SoC by setting CHIP_EN and RESET_N signals low, * CHIP_EN high then RESET_N high */ void nm_bsp_reset(void) { gpioPinSetOutput(confWINC_CHIP_ENABLE_PORT, confWINC_CHIP_ENABLE_PIN, gpioLOW); gpioPinSetOutput(confWINC_RESET_PORT, confWINC_RESET_PIN, gpioLOW); nm_bsp_sleep(100); gpioPinSetOutput(confWINC_CHIP_ENABLE_PORT, confWINC_CHIP_ENABLE_PIN, gpioHIGH); nm_bsp_sleep(10); gpioPinSetOutput(confWINC_RESET_PORT, confWINC_RESET_PIN, gpioHIGH); nm_bsp_sleep(100); }
/** * @fn nm_bsp_reset * @brief Reset NMC1500 SoC by setting CHIP_EN and RESET_N signals low, * CHIP_EN high then RESET_N high */ void nm_bsp_reset(void) { pio_set_pin_low(CONF_WINC_PIN_CHIP_ENABLE); pio_set_pin_low(CONF_WINC_PIN_RESET); nm_bsp_sleep(100); pio_set_pin_high(CONF_WINC_PIN_CHIP_ENABLE); nm_bsp_sleep(10); pio_set_pin_high(CONF_WINC_PIN_RESET); nm_bsp_sleep(10); }
void enable_rf_blocks(void) { nm_write_reg(0x6, 0xdb); nm_write_reg(0x7, 0x6); nm_bsp_sleep(10); nm_write_reg(0x1480, 0); nm_write_reg(0x1484, 0); nm_bsp_sleep(10); nm_write_reg(0x6, 0x0); nm_write_reg(0x7, 0x0); }
/** * \brief P2P mode * * Initializes the P2P mode for a while and terminate. */ static int8_t enable_disable_p2p_mode(void) { int8_t ret; printf("P2P mode, start\r\n"); /* Set device name. */ ret = m2m_wifi_set_device_name((uint8_t *)MAIN_WLAN_DEVICE_NAME, strlen(MAIN_WLAN_DEVICE_NAME)); if (M2M_SUCCESS != ret) { return ret; } /* Start P2P with channel number. */ ret = m2m_wifi_p2p(MAIN_WLAN_P2P_CHANNEL); if (M2M_SUCCESS != ret) { return ret; } /* Keep in P2P mode for a while. */ nm_bsp_sleep(HOLD_TIME_IN_MODE); /* Stop P2P mode. */ ret = m2m_wifi_p2p_disconnect(); if (M2M_SUCCESS != ret) { return ret; } printf("P2P mode, end\r\n"); return ret; }
sint8 nm_bus_init(void *pvinit) { struct hal_spi_settings cfg = { 0 }; /* * Add code to configure spi. */ if (!winc1500_spi_inited) { if (hal_gpio_init_out(WINC1500_SPI_SSN, 1)) { return M2M_ERR_BUS_FAIL; } cfg.data_mode = HAL_SPI_MODE0; cfg.data_order = HAL_SPI_MSB_FIRST; cfg.word_size = HAL_SPI_WORD_SIZE_8BIT; cfg.baudrate = WINC1500_SPI_SPEED; if (hal_spi_config(BSP_WINC1500_SPI_PORT, &cfg)) { return M2M_ERR_BUS_FAIL; } winc1500_spi_inited = 1; if (hal_spi_enable(BSP_WINC1500_SPI_PORT)) { return M2M_ERR_BUS_FAIL; } } nm_bsp_reset(); nm_bsp_sleep(1); return M2M_SUCCESS; }
/** * @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 nm_bus_init * @brief Initialize the bus wrapper * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure */ sint8 nm_bus_init(void *pvinit) { sint8 result = M2M_SUCCESS; #ifdef CONF_WINC_USE_I2C /* Not implemented */ #elif defined CONF_WINC_USE_SPI /* Configure pins */ ioport_configure_pin(CONF_WIFI_M2M_SPI_CS_PIN, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); ioport_configure_pin(CONF_WIFI_M2M_SPI_MOSI_PIN, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); ioport_configure_pin(CONF_WIFI_M2M_SPI_MISO_PIN, IOPORT_DIR_INPUT); ioport_configure_pin(CONF_WIFI_M2M_SPI_SCK_PIN, IOPORT_INIT_LOW | IOPORT_DIR_OUTPUT); struct spi_device spi_device_conf; spi_device_conf.id = CONF_WIFI_M2M_SPI_CS_PIN; /* Configure the SPI master. */ spi_master_init(CONF_WIFI_M2M_SPI_MODULE); spi_master_setup_device(CONF_WIFI_M2M_SPI_MODULE, &spi_device_conf, SPI_MODE_0, CONF_WIFI_M2M_SPI_BAUDRATE, 0); /* Enable the SPI master. */ spi_enable(CONF_WIFI_M2M_SPI_MODULE); nm_bsp_reset(); nm_bsp_sleep(1); #endif return result; }
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 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)); reg = nm_read_reg(regAddress); 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; }
/** * \brief Main application function. * * Application entry point. * * \return program return value. */ int main(void) { tstrWifiInitParam param; int8_t ret; /* Initialize the board. */ system_init(); /* Initialize the UART console. */ configure_console(); printf(STRING_HEADER); /* Initialize the BSP. */ nm_bsp_init(); /* Initialize Wi-Fi parameters structure. */ memset((uint8_t *)¶m, 0, sizeof(tstrWifiInitParam)); /* Initialize Wi-Fi driver with data and status callbacks. */ ret = m2m_wifi_init(¶m); if (M2M_SUCCESS != ret) { printf("main: m2m_wifi_init call error!(%d)\r\n", ret); while (1) { } } /** * Station mode. * Device started as station mode basically. */ if (1) { } /** * AP mode. * On and off AP mode. */ ret = enable_disable_ap_mode(); if (M2M_SUCCESS != ret) { printf("main: enable_disable_ap_mode call error!\r\n"); while (1) { } } nm_bsp_sleep(DELAY_FOR_MODE_CHANGE); /** * P2P mode. * On and off P2P mode. */ ret = enable_disable_p2p_mode(); if (M2M_SUCCESS != ret) { printf("main: enable_disable_p2p_mode call error!\r\n"); while (1) { } } return 0; }
/** * @fn nm_bsp_reset * @brief Reset NMC1500 SoC by setting CHIP_EN and RESET_N signals low, * CHIP_EN high then RESET_N high */ void nm_bsp_reset(void) { HAL_GPIO_WritePin(GPIOA,CONF_WINC_PIN_CHIP_ENABLE,GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOA,CONF_WINC_PIN_RESET,GPIO_PIN_RESET); nm_bsp_sleep(100); HAL_GPIO_WritePin(GPIOA,CONF_WINC_PIN_CHIP_ENABLE,GPIO_PIN_SET); nm_bsp_sleep(10); HAL_GPIO_WritePin(GPIOA,CONF_WINC_PIN_RESET,GPIO_PIN_SET); nm_bsp_sleep(10); // port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false); // port_pin_set_output_level(CONF_WINC_PIN_RESET, false); // nm_bsp_sleep(100); // port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, true); // nm_bsp_sleep(10); // port_pin_set_output_level(CONF_WINC_PIN_RESET, true); // nm_bsp_sleep(10); }
void rom_test() { uint8 *pu8TextSec; FILE *fp; uint32 u32CodeSize = 0; nm_bsp_sleep(1000); /* Read text section. */ fp = fopen(ROM_FIRMWARE_FILE,"rb"); if(fp) { /* Get the code size. */ fseek(fp, 0L, SEEK_END); u32CodeSize = ftell(fp); fseek(fp, 0L, SEEK_SET); pu8TextSec = (uint8*)malloc(u32CodeSize); if(pu8TextSec != NULL) { M2M_INFO("Code Size %f\n",u32CodeSize / 1024.0); fread(pu8TextSec, u32CodeSize, 1, fp); nm_write_block(CODE_BASE, pu8TextSec, (uint16)u32CodeSize); //nm_read_block(CODE_BASE, tmpv, sz); fclose(fp); free(pu8TextSec); } } #if 0 uint8 *pu8DataSec; uint32 u32DataSize = 0; /* Read data section. */ fp = fopen(ROM_DATA_FILE,"rb"); if(fp) { /* Get the data size. */ fseek(fp, 0L, SEEK_END); u32DataSize = ftell(fp); fseek(fp, 0L, SEEK_SET); pu8DataSec = (uint8*)malloc(u32DataSize); if(pu8DataSec != NULL) { M2M_INFO("Data Size %f\n",u32DataSize / 1024.0); fread(pu8DataSec, u32DataSize, 1, fp); nm_write_block(DATA_BASE, pu8DataSec, (uint16)u32DataSize); fclose(fp); } free(pu8DataSec); } #endif nm_write_reg(0x108c, 0xdddd); }
sint8 chip_reset(void) { sint8 ret = M2M_SUCCESS; #ifndef CONF_WINC_USE_UART nmi_set_sys_clk_src_to_xo(); #endif ret += nm_write_reg(NMI_GLB_RESET_0, 0); nm_bsp_sleep(50); #ifndef CONF_WINC_USE_UART restore_pmu_settings_after_global_reset(); #endif return ret; }
/* * @fn nm_bus_init * @brief Initialize the bus wrapper * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure */ sint8 nm_bus_init(void *pvinit) { sint8 result = M2M_SUCCESS; #ifdef CONF_WINC_USE_I2C /* Initialize config structure and software module. */ struct i2c_master_config config_i2c_master; i2c_master_get_config_defaults(&config_i2c_master); /* Change buffer timeout to something longer. */ config_i2c_master.buffer_timeout = 1000; /* Initialize and enable device with config. */ i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master); i2c_master_enable(&i2c_master_instance); #elif defined CONF_WINC_USE_SPI /* Structure for SPI configuration. */ struct spi_config config; struct spi_slave_inst_config slave_config; /* Select SPI slave CS pin. */ /* This step will set the CS high */ spi_slave_inst_get_config_defaults(&slave_config); slave_config.ss_pin = CONF_WINC_SPI_CS_PIN; spi_attach_slave(&slave_inst, &slave_config); /* Configure the SPI master. */ spi_get_config_defaults(&config); config.mux_setting = CONF_WINC_SPI_SERCOM_MUX; config.pinmux_pad0 = CONF_WINC_SPI_PINMUX_PAD0; config.pinmux_pad1 = CONF_WINC_SPI_PINMUX_PAD1; config.pinmux_pad2 = CONF_WINC_SPI_PINMUX_PAD2; config.pinmux_pad3 = CONF_WINC_SPI_PINMUX_PAD3; config.master_slave_select_enable = false; config.mode_specific.master.baudrate = CONF_WINC_SPI_CLOCK; if (spi_init(&master, CONF_WINC_SPI_MODULE, &config) != STATUS_OK) { return M2M_ERR_BUS_FAIL; } /* Enable the SPI master. */ spi_enable(&master); nm_bsp_reset(); nm_bsp_sleep(1); #endif return result; }
NMI_API sint8 m2m_ota_test(void) { uint32 page = 0; uint8 buffer[1500]; uint32 u32Sz = 0; sint8 ret = M2M_SUCCESS; FILE *fp =NULL; fp = fopen(M2M_OTA_FILE,"rb"); if(fp) { fseek(fp, 0L, SEEK_END); u32Sz = ftell(fp); fseek(fp, 0L, SEEK_SET); while(u32Sz > 0) { { page = (rand()%1400); if((page<100)||(page>1400)) page = 1400; } if(u32Sz>page) { u32Sz-=page; } else { page = u32Sz; u32Sz = 0; } printf("page %d\n", (int)page); fread(buffer,page,1,fp); ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_TEST|M2M_REQ_DATA_PKT,NULL,0,(uint8*)&buffer,page,0); if(ret != M2M_SUCCESS) { M2M_ERR("\n"); } nm_bsp_sleep(1); } } else { M2M_ERR("nO err\n"); } return ret; }
sint8 chip_reset(void) { sint8 ret = M2M_SUCCESS; #if 0 // MERGEBUG: TODO: This causes serial trace from the chip to be garbled - investigate #ifndef CONF_WINC_USE_UART nmi_set_sys_clk_src_to_xo(); #endif #endif ret += nm_write_reg(NMI_GLB_RESET_0, 0); nm_bsp_sleep(50); #ifndef CONF_WINC_USE_UART restore_pmu_settings_after_global_reset(); #endif return ret; }
/** * \brief AP mode * * Initializes the AP mode for a while and terminate. */ static int8_t enable_disable_ap_mode(void) { int8_t ret; tstrM2MAPConfig strM2MAPConfig; printf("AP mode, start\r\n"); /* Configure AP. */ memset(&strM2MAPConfig, 0x00, sizeof(tstrM2MAPConfig)); strcpy((char *)&strM2MAPConfig.au8SSID, MAIN_WLAN_SSID); strM2MAPConfig.u8ListenChannel = MAIN_WLAN_AP_CHANNEL; strM2MAPConfig.u8SecType = MAIN_WLAN_AUTH; strM2MAPConfig.au8DHCPServerIP[0] = 0xC0; /* 192 */ strM2MAPConfig.au8DHCPServerIP[1] = 0xA8; /* 168 */ strM2MAPConfig.au8DHCPServerIP[2] = 0x01; /* 1 */ strM2MAPConfig.au8DHCPServerIP[3] = 0x01; /* 1 */ /* Start AP mode. */ ret = m2m_wifi_enable_ap(&strM2MAPConfig); if (M2M_SUCCESS != ret) { return ret; } /* Keep in AP mode for a while. */ nm_bsp_sleep(HOLD_TIME_IN_MODE); /* Stop AP mode. */ ret = m2m_wifi_disable_ap(); if (M2M_SUCCESS != ret) { return ret; } printf("AP mode, end\r\n"); return ret; }
/** * @fn nm_clkless_wake * @brief Wakeup the chip using clockless registers * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure * @author Samer Sarhan * @date 06 June 2014 * @version 1.0 */ sint8 nm_clkless_wake(void) { sint8 ret = M2M_SUCCESS; uint32 reg, clk_status_reg,trials = 0; /* wait 1ms, spi data read */ nm_bsp_sleep(1); ret = nm_read_reg_with_ret(0x1, ®); if(ret != M2M_SUCCESS) { M2M_ERR("Bus error (1). Wake up failed\n"); return ret; } /* * At this point, I am not sure whether it is B0 or A0 * If B0, then clks_enabled bit exists in register 0xf * If A0, then clks_enabled bit exists in register 0xe */ do { /* Set bit 1 */ nm_write_reg(0x1, reg | (1 << 1)); // Search for the correct (clock status) register address do { /* wait 1ms, spi data read */ nm_bsp_sleep(1); ret = nm_read_reg_with_ret(clk_status_reg_adr, &clk_status_reg); if (ret != M2M_SUCCESS || (ret == M2M_SUCCESS && clk_status_reg == 0)) { switch (clk_status_reg_adr) { case 0x13: clk_status_reg_adr = 0x0F; break; case 0x0F: clk_status_reg_adr = 0x0E; break; default: clk_status_reg_adr = 0x00; break; } } else break; // we have found the correct register, break out of the search } while (clk_status_reg_adr); if (0 == clk_status_reg_adr) { M2M_ERR("Bus error (2). Wake up failed\n"); return ret; } // in case of clocks off, wait 2ms, and check it again. // if still off, wait for another 2ms, for a total wait of 6ms. // If still off, redo the wake up sequence while( ((clk_status_reg & 0x4) == 0) && (((++trials) %3) == 0)) { /* Wait for the chip to stabilize*/ nm_bsp_sleep(2); // Make sure chip is awake. This is an extra step that can be removed // later to avoid the bus access overhead nm_read_reg_with_ret(clk_status_reg_adr, &clk_status_reg); if ((clk_status_reg & 0x4) == 0) { M2M_ERR("clocks still OFF. Wake up failed\n"); } } // in case of failure, Reset the wakeup bit to introduce a new edge on the next loop if((clk_status_reg & 0x4) == 0) { // Reset bit 0 nm_write_reg(0x1, reg | (1 << 1)); } } while((clk_status_reg & 0x4) == 0); return ret; }
static s8_t spi_rw(u8_t *mosi, u8_t *miso, u16_t size) { const struct spi_buf buf_tx = { .buf = mosi, .len = size }; const struct spi_buf_set tx = { .buffers = &buf_tx, .count = 1 }; const struct spi_buf buf_rx = { .buf = miso, .len = miso ? size : 0 }; const struct spi_buf_set rx = { .buffers = &buf_rx, .count = 1 }; if (spi_transceive(winc1500.spi, &winc1500.spi_cfg, &tx, &rx)) { LOG_ERR("spi_transceive fail"); return M2M_ERR_BUS_FAIL; } return M2M_SUCCESS; } #endif s8_t nm_bus_init(void *pvinit) { /* configure GPIOs */ winc1500.gpios = winc1500_configure_gpios(); #ifdef CONF_WINC_USE_I2C /* Not implemented */ #elif defined CONF_WINC_USE_SPI /* setup SPI device */ winc1500.spi = device_get_binding(DT_ATMEL_WINC1500_0_BUS_NAME); if (!winc1500.spi) { LOG_ERR("spi device binding"); return -1; } winc1500.spi_cfg.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB; winc1500.spi_cfg.frequency = DT_ATMEL_WINC1500_0_SPI_MAX_FREQUENCY; winc1500.spi_cfg.slave = DT_ATMEL_WINC1500_0_BASE_ADDRESS; #ifdef CONFIG_WIFI_WINC1500_GPIO_SPI_CS cs_ctrl.gpio_dev = device_get_binding( DT_ATMEL_WINC1500_0_CS_GPIO_CONTROLLER); if (!cs_ctrl.gpio_dev) { LOG_ERR("Unable to get GPIO SPI CS device"); return -ENODEV; } cs_ctrl.gpio_pin = DT_ATMEL_WINC1500_0_CS_GPIO_PIN; cs_ctrl.delay = 0U; winc1500.spi_cfg.cs = &cs_ctrl; LOG_DBG("SPI GPIO CS configured on %s:%u", DT_ATMEL_WINC1500_0_CS_GPIO_CONTROLLER, DT_ATMEL_WINC1500_0_CS_GPIO_PIN); #endif /* CONFIG_WIFI_WINC1500_GPIO_SPI_CS */ nm_bsp_reset(); nm_bsp_sleep(1); nm_bsp_interrupt_ctrl(1); LOG_DBG("NOTICE:DONE"); #endif return 0; } s8_t nm_bus_ioctl(u8_t cmd, void *parameter) { sint8 ret = 0; switch (cmd) { #ifdef CONF_WINC_USE_I2C case NM_BUS_IOCTL_R: { struct nm_i2c_default *param = (struct nm_i2c_default *)parameter; ret = nm_i2c_read(param->buffer, param->size); } break; case NM_BUS_IOCTL_W: { struct nm_i2c_default *param = (struct nm_i2c_default *)parameter; ret = nm_i2c_write(param->buffer, param->size); } break; case NM_BUS_IOCTL_W_SPECIAL: { struct nm_i2c_special *param = (struct nm_i2c_special *)parameter; ret = nm_i2c_write_special(param->buffer1, param->size1, param->buffer2, param->size2); } break; #elif defined CONF_WINC_USE_SPI case NM_BUS_IOCTL_RW: { tstrNmSpiRw *param = (tstrNmSpiRw *)parameter; ret = spi_rw(param->pu8InBuf, param->pu8OutBuf, param->u16Sz); } break; #endif default: ret = -1; M2M_ERR("ERROR:invalid ioclt cmd\n"); break; } return ret; } s8_t nm_bus_deinit(void) { return M2M_SUCCESS; } s8_t nm_bus_reinit(void *config) { return 0; }
/** * @fn nm_clkless_wake * @brief Wakeup the chip using clockless registers * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure * @author Samer Sarhan * @date 06 June 2014 * @version 1.0 */ sint8 nm_clkless_wake(void) { sint8 ret = M2M_SUCCESS; uint32 reg, clk_status_reg,trials = 0; ret = nm_read_reg_with_ret(0x1, ®); if(ret != M2M_SUCCESS) { M2M_ERR("Bus error (1). Wake up failed\n"); goto _WAKE_EXIT; } /* * At this point, I am not sure whether it is B0 or A0 * If B0, then clks_enabled bit exists in register 0xf * If A0, then clks_enabled bit exists in register 0xe */ do { /* Set bit 1 */ nm_write_reg(0x1, reg | (1 << 1)); // Check the clock status ret = nm_read_reg_with_ret(clk_status_reg_adr, &clk_status_reg); if( (ret != M2M_SUCCESS) || ((ret == M2M_SUCCESS) && (clk_status_reg == 0)) ) { /* Register 0xf did not exist in A0. * If register 0xf fails to read or if it reads 0, * then the chip is A0. */ clk_status_reg_adr = 0xe; ret = nm_read_reg_with_ret(clk_status_reg_adr, &clk_status_reg); if(ret != M2M_SUCCESS) { M2M_ERR("Bus error (2). Wake up failed\n"); goto _WAKE_EXIT; } } // in case of clocks off, wait 2ms, and check it again. // if still off, wait for another 2ms, for a total wait of 6ms. // If still off, redo the wake up sequence while( ((clk_status_reg & 0x4) == 0) && (((++trials) %3) == 0)) { /* Wait for the chip to stabilize*/ nm_bsp_sleep(1); // Make sure chip is awake. This is an extra step that can be removed // later to avoid the bus access overhead nm_read_reg_with_ret(clk_status_reg_adr, &clk_status_reg); if((clk_status_reg & 0x4) == 0) { M2M_ERR("clocks still OFF. Wake up failed\n"); } } // in case of failure, Reset the wakeup bit to introduce a new edge on the next loop if((clk_status_reg & 0x4) == 0) { // Reset bit 0 nm_write_reg(0x1, reg | (1 << 1)); } } while((clk_status_reg & 0x4) == 0); _WAKE_EXIT: return ret; }
/* * @fn nm_bus_init * @brief Initialize the bus wrapper * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure */ sint8 nm_bus_init(void *pvinit) { sint8 result = M2M_SUCCESS; #ifdef CONF_WINC_USE_I2C /* Initialize config structure and software module. */ struct i2c_master_config config_i2c_master; i2c_master_get_config_defaults(&config_i2c_master); /* Change buffer timeout to something longer. */ config_i2c_master.buffer_timeout = 1000; /* Initialize and enable device with config. */ i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master); i2c_master_enable(&i2c_master_instance); #elif defined CONF_WINC_USE_SPI // hspi1.Instance = SPI1; // hspi1.Init.Mode = SPI_MODE_MASTER; // hspi1.Init.Direction = SPI_DIRECTION_2LINES; // hspi1.Init.DataSize = SPI_DATASIZE_8BIT; // hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; // hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; // hspi1.Init.NSS = SPI_NSS_SOFT; // hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; // hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; // hspi1.Init.TIMode = SPI_TIMODE_DISABLED; // hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; // hspi1.Init.CRCPolynomial = 10; /* Structure for SPI configuration. */ // struct spi_config config; // struct spi_slave_inst_config slave_config; // /* Select SPI slave CS pin. */ // /* This step will set the CS high */ // spi_slave_inst_get_config_defaults(&slave_config); // slave_config.ss_pin = CONF_WINC_SPI_CS_PIN; // spi_attach_slave(&slave_inst, &slave_config); // /* Configure the SPI master. */ // spi_get_config_defaults(&config); // config.mux_setting = CONF_WINC_SPI_SERCOM_MUX; // config.pinmux_pad0 = CONF_WINC_SPI_PINMUX_PAD0; // config.pinmux_pad1 = CONF_WINC_SPI_PINMUX_PAD1; // config.pinmux_pad2 = CONF_WINC_SPI_PINMUX_PAD2; // config.pinmux_pad3 = CONF_WINC_SPI_PINMUX_PAD3; // config.master_slave_select_enable = false; // config.mode_specific.master.baudrate = CONF_WINC_SPI_CLOCK; // if (spi_init(&master, CONF_WINC_SPI_MODULE, &config) != STATUS_OK) { // return M2M_ERR_BUS_FAIL; // } // /* Enable the SPI master. */ // spi_enable(&master); nm_bsp_reset(); nm_bsp_sleep(1); #endif return result; }
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; }
tenuWifiMode localParseEventLoop(ParseClientInternal *parseClient) { tenuWifiMode wifiStatus = M2M_WIFI_MODE_UNKNOWN; while (m2m_wifi_handle_events(NULL) != M2M_SUCCESS) { } #ifdef ENABLE_MDNS if(gTimerCbMdns == 1) { gTimerCbMdns = 0; printf("Send mDNS====\r\n"); mdnsd_send_response(); } #endif switch (gParseMode) { case M2M_WIFI_MODE_UNKNOWN: break; case M2M_WIFI_MODE_AP_ENABLE: { uint8 macAddr[6] = {0,}; uint8_t macInfo[2] = {0,}; m2m_wifi_get_mac_address(macAddr); macInfo[0] = macAddr[4]; macInfo[1] = macAddr[5]; deviceConfigAddKey( 0, "applicationId", "App ID", NULL ); deviceConfigAddKey( 0, "clientKey", "Client Key", NULL ); deviceConfigAddKey( 0, "installationId", "Installation ID", NULL ); deviceConfigAddKey( 0, "sessionToken", "Session Token", NULL ); deviceConfigAddKey( 0, "deviceName", "Device Name", NULL ); /* AP Mode : Enable*/ fluffy_wifi_ap_mode(1, macInfo); gParseMode = M2M_WIFI_MODE_AP_PROV; wifiStatus = M2M_WIFI_MODE_AP_PROV; break; } case M2M_WIFI_MODE_AP_PROV: { /* Provision AP or HTTP */ fluffy_trans_ap_provision(); gParseMode = M2M_WIFI_MODE_AP; wifiStatus = M2M_WIFI_MODE_AP; break; } case M2M_WIFI_MODE_AP: { if (fluffy_get_ap_mode_completed()) { printf("WIFI : Complete AP Provision\r\n"); nm_bsp_sleep(DELAY_FOR_MODE_CHANGE); /* AP Mode : Disable*/ fluffy_trans_socket_close(); fluffy_wifi_ap_mode(0, NULL); nm_bsp_sleep(DELAY_FOR_MODE_CHANGE); gParseMode = M2M_WIFI_MODE_STA_ENABLE; wifiStatus = M2M_WIFI_MODE_STA_ENABLE; } break; } // AP mode for provisioning //////////////////////////////////////////////////////// // Station mode for connecting parse server (request & push) case M2M_WIFI_MODE_STA_ENABLE: { /* printf( "applicationId = %s\r\n", deviceConfigGetValue( 0, "applicationId" ) ); printf( "clientKey = %s\r\n", deviceConfigGetValue( 0, "clientKey" ) ); printf( "installationId = %s\r\n", deviceConfigGetValue( 0, "installationId" ) ); printf( "deviceId = %s\r\n", deviceConfigGetValue( 0, "sessionToken" ) ); printf( "name = %s\r\n", deviceConfigGetValue( 0, "deviceName" ) ); */ /* Station Mode : Enable */ fluffy_wifi_stat_mode(1); gParseMode = M2M_WIFI_MODE_STA_CON; wifiStatus = M2M_WIFI_MODE_STA_CON; break; } case M2M_WIFI_MODE_STA_CON: { if (fluffy_get_wifi_connected()) { #ifdef ENABLE_MDNS if ( !mdnsd_start( deviceConfigGetValue( 0, "deviceName" ) ) ) { printf("Error, mDNS Start\r\n"); } tcc_enable_callback(&tempTccModule, TCC_CALLBACK_CHANNEL_3); #endif gParseMode = M2M_WIFI_MODE_STA; wifiStatus = M2M_WIFI_MODE_STA; } break; } case M2M_WIFI_MODE_STA: { if( parseClient && parseClient->isStartPushService ) { parseClient->isStartPushService = 0; fluffy_trans_sta_socket(); } wifiStatus = M2M_WIFI_MODE_STA; break; } default: { printf("Unknown WIFI Mode : %d\r\n", gParseMode); wifiStatus = gParseMode; break; } } return wifiStatus; }
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 nm_drv_init * @brief Initialize NMC1000 driver * @return M2M_SUCCESS in case of success and Negative error code in case of failure * @param [in] arg * Generic argument * @author M. Abdelmawla * @date 15 July 2012 * @version 1.0 */ sint8 nm_drv_init(void * arg) { tstrM2mRev strtmp; sint8 ret = M2M_SUCCESS; uint8 u8Mode = M2M_WIFI_MODE_NORMAL; if(NULL != arg) { if(M2M_WIFI_MODE_CONFIG == *((uint8 *)arg)) { u8Mode = M2M_WIFI_MODE_CONFIG; } else { /*continue running*/ } } else { /*continue running*/ } ret = nm_bus_iface_init(NULL); if (M2M_SUCCESS != ret) { M2M_ERR("[nmi start]: fail init bus\n"); goto ERR1; } #ifdef BUS_ONLY return; #endif #ifdef NO_HW_CHIP_EN ret = chip_wake(); nm_bsp_sleep(10); if (M2M_SUCCESS != ret) { M2M_ERR("[nmi start]: fail chip_wakeup\n"); goto ERR2; } /** Go... **/ ret = chip_reset(); if (M2M_SUCCESS != ret) { goto ERR2; } #endif M2M_INFO("Chip ID %lx\n", nmi_get_chipid()); #ifdef CONF_WINC_USE_SPI /* Must do this after global reset to set SPI data packet size. */ nm_spi_init(); #endif #ifdef NO_HW_CHIP_EN /*return power save to default value*/ chip_idle(); ret = cpu_start(); if (M2M_SUCCESS != ret) { goto ERR2; } #endif ret = wait_for_bootrom(u8Mode); if (M2M_SUCCESS != ret) { goto ERR2; } ret = wait_for_firmware_start(u8Mode); if (M2M_SUCCESS != ret) { goto ERR2; } if(M2M_WIFI_MODE_CONFIG == u8Mode) { goto ERR1; } else { /*continue running*/ } ret = enable_interrupts(); if (M2M_SUCCESS != ret) { M2M_ERR("failed to enable interrupts..\n"); goto ERR2; } ret = nm_get_firmware_info(&strtmp); M2M_INFO("Firmware ver : %u.%u.%u\n", strtmp.u8FirmwareMajor, strtmp.u8FirmwareMinor, strtmp.u8FirmwarePatch); M2M_INFO("Min driver ver : %u.%u.%u\n", strtmp.u8DriverMajor, strtmp.u8DriverMinor, strtmp.u8DriverPatch); M2M_INFO("Curr driver ver: %u.%u.%u\n", M2M_DRIVER_VERSION_MAJOR_NO, M2M_DRIVER_VERSION_MINOR_NO, M2M_DRIVER_VERSION_PATCH_NO); if(strtmp.u8FirmwareMajor != M2M_DRIVER_VERSION_MAJOR_NO || strtmp.u8FirmwareMinor != M2M_DRIVER_VERSION_MINOR_NO) { ret = M2M_ERR_FW_VER_MISMATCH; M2M_ERR("Firmware version mismatch!\n"); } return ret; ERR2: nm_bus_iface_deinit(); ERR1: return ret; }