Ejemplo n.º 1
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
 *	@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);
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
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)
{
	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);
}
Ejemplo n.º 4
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)
{
	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);
}
Ejemplo n.º 5
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)
{
    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);
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
/**
 * \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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
/**
*	@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;
}
Ejemplo n.º 10
0
/*
*	@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;
}
Ejemplo n.º 11
0
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, &reg);
	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, &reg);
	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;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
/**
 * \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 *)&param, 0, sizeof(tstrWifiInitParam));

	/* Initialize Wi-Fi driver with data and status callbacks. */
	ret = m2m_wifi_init(&param);
	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;
}
Ejemplo n.º 14
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);
}
Ejemplo n.º 15
0
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);

}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
0
/*
*	@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;
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
0
/**
 * \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;
}
Ejemplo n.º 21
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;
	/* wait 1ms, spi data read */
	nm_bsp_sleep(1);
	ret = nm_read_reg_with_ret(0x1, &reg);
	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;
}
Ejemplo n.º 23
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, &reg);
	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;
}
Ejemplo n.º 24
0
/*
*	@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;
}
Ejemplo n.º 25
0
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 *)&reg);
			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;
}
Ejemplo n.º 26
0
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;
}
Ejemplo n.º 27
0
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 *)&reg);
			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;
}
Ejemplo n.º 28
0
/*
*	@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;
}