/**
*	@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;
}
Example #2
0
/**
*	@fn		NMI_API sint8 hif_deinit(void * arg);
*	@brief	To De-initialize HIF layer.
*    @param [in]	arg
*				Pointer to the arguments.
*    @return		The function shall return ZERO for successful operation and a negative value otherwise.
*/
sint8 hif_deinit(void * arg)
{
	sint8 ret = M2M_SUCCESS;
	ret = hif_chip_wake();
	m2m_memset((uint8*)&gstrHifCxt,0,sizeof(tstrHifContext));
	return ret;
}
Example #3
0
/*!
@fn	\
	NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev);

@brief
	Get the OTA Firmware version.

@return
	The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev)
{
	sint8 ret = M2M_SUCCESS;
	ret = hif_chip_wake();
	if(ret == M2M_SUCCESS)
	{
    	ret = nm_get_ota_firmware_info(pstrRev);
		hif_chip_sleep();
	}
	return ret;
}
Example #4
0
sint8 m2m_wifi_get_otp_mac_address(uint8 *pu8MacAddr, uint8* pu8IsValid)
{
	sint8 ret = M2M_SUCCESS;
	ret = hif_chip_wake();
	if(ret == M2M_SUCCESS)
	{
		ret = nmi_get_otp_mac_address(pu8MacAddr, pu8IsValid);
		if(ret == M2M_SUCCESS)
		{
			ret = hif_chip_sleep();
		}
	}
	return ret;
}
Example #5
0
/**
 * \brief GPIO read/write skeleton with wakeup/sleep capability. 
 */
static sint8 gpio_ioctl(uint8 op, uint8 u8GpioNum, uint8 u8InVal, uint8 * pu8OutVal)
{
	sint8 ret, gpio;

	ret = hif_chip_wake();
	if(ret != M2M_SUCCESS) goto _EXIT;

	gpio = get_gpio_idx(u8GpioNum);
	if(gpio < 0) goto _EXIT1;

	if(op == GPIO_OP_DIR) {
		ret = set_gpio_dir((uint8)gpio, u8InVal);
	} else if(op == GPIO_OP_SET) {	
		ret = set_gpio_val((uint8)gpio, u8InVal);
	} else if(op == GPIO_OP_GET) {
		ret = get_gpio_val((uint8)gpio, pu8OutVal);
	}
	if(ret != M2M_SUCCESS) goto _EXIT1;

_EXIT1:
	ret = hif_chip_sleep();
_EXIT:
	return ret;
}
Example #6
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;
}
/**
*	@fn		hif_isr
*	@brief	Host interface interrupt service routine
*	@author	M. Abdelmawla
*	@date	15 July 2012
*	@return	1 in case of interrupt received else 0 will be returned
*	@version	1.0
*/
static sint8 hif_isr(void)
{
	sint8 ret = M2M_ERR_BUS_FAIL;
	uint32 reg;
	volatile tstrHifHdr strHif;

	ret = hif_chip_wake();
	if(ret == M2M_SUCCESS)
	{
		ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, &reg);
		if(M2M_SUCCESS == ret)
		{
			if(reg & 0x1)	/* New interrupt has been received */
			{
				uint16 size;

				nm_bsp_interrupt_ctrl(0);
				/*Clearing RX interrupt*/
				reg &= ~(1<<0);
				ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0,reg);
				if(ret != M2M_SUCCESS)goto ERR1;
				gu8HifSizeDone = 0;
				size = (uint16)((reg >> 2) & 0xfff);
				if (size > 0) {
					uint32 address = 0;
					/**
					start bus transfer
					**/
					ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_1, &address);
					if(M2M_SUCCESS != ret)
					{
						M2M_ERR("(hif) WIFI_HOST_RCV_CTRL_1 bus fail\n");
						nm_bsp_interrupt_ctrl(1);
						goto ERR1;
					}
					ret = nm_read_block(address, (uint8*)&strHif, sizeof(tstrHifHdr));
					strHif.u16Length = NM_BSP_B_L_16(strHif.u16Length);
					if(M2M_SUCCESS != ret)
					{
						M2M_ERR("(hif) address bus fail\n");
						nm_bsp_interrupt_ctrl(1);
						goto ERR1;
					}
					if(strHif.u16Length != size)
					{
						if((size - strHif.u16Length) > 4)
						{
							M2M_ERR("(hif) Corrupted packet Size = %u <L = %u, G = %u, OP = %02X>\n",
								size, strHif.u16Length, strHif.u8Gid, strHif.u8Opcode);
							nm_bsp_interrupt_ctrl(1);
							ret = M2M_ERR_BUS_FAIL;
							goto ERR1;
						}
					}

					if(M2M_REQ_GROUP_WIFI == strHif.u8Gid)
					{
						if(pfWifiCb)
							pfWifiCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);

					}
					else if(M2M_REQ_GROUP_IP == strHif.u8Gid)
					{
						if(pfIpCb)
							pfIpCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
					}
					else if(M2M_REQ_GROUP_OTA == strHif.u8Gid)
					{
						if(pfOtaCb)
							pfOtaCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
					}
					else if(M2M_REQ_GROUP_CRYPTO == strHif.u8Gid)
					{
						if(pfCryptoCb)
							pfCryptoCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
					}
					else if(M2M_REQ_GROUP_SIGMA == strHif.u8Gid)
					{
						if(pfSigmaCb)
							pfSigmaCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
					}
					else
					{
						M2M_ERR("(hif) invalid group ID\n");
						ret = M2M_ERR_BUS_FAIL;
						goto ERR1;
					}
					#ifndef ENABLE_UNO_BOARD
					if(!gu8HifSizeDone)
					{
						M2M_ERR("(hif) host app didn't set RX Done\n");
						ret = hif_set_rx_done();
					}
					#endif
				}
				else
				{
					ret = M2M_ERR_RCV;
					M2M_ERR("(hif) Wrong Size\n");
					goto ERR1;
				}
			}
			else
			{
sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize,
			   uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset)
{
	sint8		ret = M2M_ERR_SEND;
	volatile tstrHifHdr	strHif;

	strHif.u8Opcode		= u8Opcode&(~NBIT7);
	strHif.u8Gid		= u8Gid;
	strHif.u16Length	= M2M_HIF_HDR_OFFSET;
	if(pu8DataBuf != NULL)
	{
		strHif.u16Length += u16DataOffset + u16DataSize;
	}
	else
	{
		strHif.u16Length += u16CtrlBufSize;
	}
	ret = hif_chip_wake();
	if(ret == M2M_SUCCESS)
	{
		volatile uint32 reg, dma_addr = 0;
		volatile uint16 cnt = 0;

		reg = 0UL;
		reg |= (uint32)u8Gid;
		reg |= ((uint32)u8Opcode<<8);
		reg |= ((uint32)strHif.u16Length<<16);
		ret = nm_write_reg(NMI_STATE_REG,reg);
		if(M2M_SUCCESS != ret) goto ERR1;


		reg = 0;
		reg |= (1<<1);
		ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg);
		if(M2M_SUCCESS != ret) goto ERR1;
		dma_addr = 0;

		//nm_bsp_interrupt_ctrl(0);

		for(cnt = 0; cnt < 1000; cnt ++)
		{
			ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_2,(uint32 *)&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;
}