Add ATWINC1500 driver

This commit is contained in:
iabdalkader 2015-09-15 02:41:36 +02:00
parent c25804d8cf
commit 47ae5a7669
40 changed files with 18181 additions and 0 deletions

View File

@ -23,6 +23,7 @@ STUSB_DIR=stusb
FATFS_DIR=fatfs FATFS_DIR=fatfs
MICROPY_DIR=micropython MICROPY_DIR=micropython
OMV_DIR=omv OMV_DIR=omv
WINC1500_DIR=winc1500
# Target # Target
TARGET ?= OPENMV2 TARGET ?= OPENMV2
@ -70,6 +71,7 @@ CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/stmhal/boards/$(TARGET)/
CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/ CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/
CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/py/ CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/py/
CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/img/ CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/img/
CFLAGS += -I$(TOP_DIR)/$(WINC1500_DIR)/include/
# Linker Flags # Linker Flags
@ -90,6 +92,7 @@ OBJ += $(wildcard $(BUILD)/$(CMSIS_DIR)/src/dsp/MatrixFunctions/*.o)
OBJ += $(wildcard $(BUILD)/$(STHAL_DIR)/src/*.o) OBJ += $(wildcard $(BUILD)/$(STHAL_DIR)/src/*.o)
OBJ += $(wildcard $(BUILD)/$(FATFS_DIR)/src/*.o) OBJ += $(wildcard $(BUILD)/$(FATFS_DIR)/src/*.o)
OBJ += $(wildcard $(BUILD)/$(FATFS_DIR)/src/option/*.o) OBJ += $(wildcard $(BUILD)/$(FATFS_DIR)/src/option/*.o)
OBJ += $(wildcard $(BUILD)/$(WINC1500_DIR)/src/*.o)
#------------- OpenMV Objects ----------------# #------------- OpenMV Objects ----------------#
OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/, \ OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/, \
@ -291,6 +294,7 @@ objs: | $(BUILD)
$(MAKE) -C $(FATFS_DIR) BUILD=$(BUILD)/$(FATFS_DIR) $(MAKE) -C $(FATFS_DIR) BUILD=$(BUILD)/$(FATFS_DIR)
$(MAKE) -C $(MICROPY_DIR)/stmhal BUILD=$(BUILD)/$(MICROPY_DIR) BOARD=$(TARGET) $(MAKE) -C $(MICROPY_DIR)/stmhal BUILD=$(BUILD)/$(MICROPY_DIR) BOARD=$(TARGET)
$(MAKE) -C $(OMV_DIR) BUILD=$(BUILD)/$(OMV_DIR) $(MAKE) -C $(OMV_DIR) BUILD=$(BUILD)/$(OMV_DIR)
$(MAKE) -C $(WINC1500_DIR) BUILD=$(BUILD)/$(WINC1500_DIR)
$(BUILD)/$(BIN).elf: objs $(BUILD)/$(BIN).elf: objs
$(CCP) -P -E -D$(TARGET) $(OMV_DIR)/stm32f4xx.ld.S > $(BUILD)/stm32f4xx.lds $(CCP) -P -E -D$(TARGET) $(OMV_DIR)/stm32f4xx.ld.S > $(BUILD)/stm32f4xx.lds

16
src/winc1500/Makefile Normal file
View File

@ -0,0 +1,16 @@
# Sources
SRCS = $(wildcard src/*.c)
OBJS = $(addprefix $(BUILD)/, $(SRCS:.c=.o))
OBJ_DIRS = $(sort $(dir $(OBJS)))
all: | $(OBJ_DIRS) $(OBJS)
$(OBJ_DIRS):
$(MKDIR) -p $@
$(BUILD)/%.o : %.c
$(ECHO) "CC $<"
$(CC) $(CFLAGS) -c -o $@ $<
$(BUILD)/%.o : %.s
$(ECHO) "AS $<"
$(AS) $(AFLAGS) $< -o $@

View File

@ -0,0 +1,279 @@
/**
*
* \file
*
* \brief This module contains NMC1500 BSP APIs declarations.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/**@defgroup BSPDefine Defines
* @ingroup nm_bsp
* @{
*/
#ifndef _NM_BSP_H_
#define _NM_BSP_H_
#define NMI_API
/*!<
* Attribute used to define memory section to map Functions in host memory.
*/
#define CONST const
/*!<
* Used for code portability.
*/
/*!
* @typedef void (*tpfNmBspIsr) (void);
* @brief Pointer to function.\n
* Used as a data type of ISR function registered by \ref nm_bsp_register_isr
* @return None
*/
typedef void (*tpfNmBspIsr)(void);
#ifndef NULL
#define NULL ((void*)0)
#endif
/*!<
* Void Pointer to '0' in case of NULL is not defined.
*/
#define BSP_MIN(x,y) ((x)>(y)?(y):(x))
/*!<
* Computes the minimum of \b x and \b y.
*/
//@}
/**@defgroup DataT DataTypes
* @ingroup nm_bsp
* @{
*/
/*!
* @ingroup DataTypes
* @typedef unsigned char uint8;
* @brief Range of values between 0 to 255
*/
typedef unsigned char uint8;
/*!
* @ingroup DataTypes
* @typedef unsigned short uint16;
* @brief Range of values between 0 to 65535
*/
typedef unsigned short uint16;
/*!
* @ingroup Data Types
* @typedef unsigned long uint32;
* @brief Range of values between 0 to 4294967295
*/
typedef unsigned long uint32;
/*!
* @ingroup Data Types
* @typedef signed char sint8;
* @brief Range of values between -128 to 127
*/
typedef signed char sint8;
/*!
* @ingroup DataTypes
* @typedef signed short sint16;
* @brief Range of values between -32768 to 32767
*/
typedef signed short sint16;
/*!
* @ingroup DataTypes
* @typedef signed long sint32;
* @brief Range of values between -2147483648 to 2147483647
*/
typedef signed long sint32;
//@}
#ifndef CORTUS_APP
#ifdef __cplusplus
extern "C"{
#endif
/** \defgroup BSPAPI Function
* @ingroup nm_bsp
*/
/** @defgroup NmBspInitFn nm_bsp_init
* @ingroup BSPAPI
* Initialization for BSP such as Reset and Chip Enable Pins for WINC, delays, register ISR, enable/disable IRQ for WINC, ...etc. You must use this function in the head of your application to
* enable WINC and Host Driver communicate each other.
*/
/**@{*/
/*!
* @fn sint8 nm_bsp_init(void);
* @note Implementation of this function is host dependent.
* @warning Missing use will lead to unavailability of host communication.\n
*
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
sint8 nm_bsp_init(void);
/**@}*/
/** @defgroup NmBspDeinitFn nm_bsp_deinit
* @ingroup BSPAPI
* De-initialization for BSP (\e Board \e Support \e Package)
*/
/**@{*/
/*!
* @fn sint8 nm_bsp_deinit(void);
* @pre Initialize \ref nm_bsp_init first
* @note Implementation of this function is host dependent.
* @warning Missing use may lead to unknown behavior in case of soft reset.\n
* @see nm_bsp_init
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
sint8 nm_bsp_deinit(void);
/**@}*/
/** @defgroup NmBspResetFn nm_bsp_reset
* @ingroup BSPAPI
* Resetting NMC1500 SoC by setting CHIP_EN and RESET_N signals low, then after specific delay the function will put CHIP_EN high then RESET_N high,
* for the timing between signals please review the WINC data-sheet
*/
/**@{*/
/*!
* @fn void nm_bsp_reset(void);
* @param [in] None
* @pre Initialize \ref nm_bsp_init first
* @note Implementation of this function is host dependent and called by HIF layer.
* @see nm_bsp_init
* @return None
*/
void nm_bsp_reset(void);
/**@}*/
/** @defgroup NmBspSleepFn nm_bsp_sleep
* @ingroup BSPAPI
* Sleep in units of milliseconds.\n
* This function used by HIF Layer according to different situations.
*/
/**@{*/
/*!
* @fn void nm_bsp_sleep(uint32);
* @brief
* @param [in] u32TimeMsec
* Time unit in milliseconds
* @pre Initialize \ref nm_bsp_init first
* @warning Maximum value must nor exceed 4294967295 milliseconds which is equal to 4294967.295 seconds.\n
* @note Implementation of this function is host dependent.
* @see nm_bsp_init
* @return None
*/
void nm_bsp_sleep(uint32 u32TimeMsec);
/**@}*/
/** @defgroup NmBspRegisterFn nm_bsp_register_isr
* @ingroup BSPAPI
* Register ISR (Interrupt Service Routine) in the initialization of HIF (Host Interface) Layer.
* When the interrupt trigger the BSP layer should call the pfisr function once inside the interrupt.
*/
/**@{*/
/*!
* @fn void nm_bsp_register_isr(tpfNmBspIsr);
* @param [in] tpfNmBspIsr pfIsr
* Pointer to ISR handler in HIF
* @warning Make sure that ISR for IRQ pin for WINC is disabled by default in your implementation.
* @note Implementation of this function is host dependent and called by HIF layer.
* @see tpfNmBspIsr
* @return None
*/
void nm_bsp_register_isr(tpfNmBspIsr pfIsr);
/**@}*/
/** @defgroup NmBspInterruptCtrl nm_bsp_interrupt_ctrl
* @ingroup BSPAPI
* Synchronous enable/disable interrupts function
*/
/**@{*/
/*!
* @fn void nm_bsp_interrupt_ctrl(uint8);
* @brief Enable/Disable interrupts
* @param [in] u8Enable
* '0' disable interrupts. '1' enable interrupts
* @see tpfNmBspIsr
* @note Implementation of this function is host dependent and called by HIF layer.
* @return None
*/
void nm_bsp_interrupt_ctrl(uint8 u8Enable);
/**@}*/
#ifdef __cplusplus
}
#endif
#endif
#ifdef _NM_BSP_BIG_END
#define NM_BSP_B_L_32(x) \
((((x) & 0x000000FF) << 24) + \
(((x) & 0x0000FF00) << 8) + \
(((x) & 0x00FF0000) >> 8) + \
(((x) & 0xFF000000) >> 24))
#define NM_BSP_B_L_16(x) \
((((x) & 0x00FF) << 8) + \
(((x) & 0xFF00) >> 8))
#else
#define NM_BSP_B_L_32(x) (x)
#define NM_BSP_B_L_16(x) (x)
#endif
#endif /*_NM_BSP_H_*/

View File

@ -0,0 +1,110 @@
/**
*
* \file
*
* \brief This module contains NMC1500 BSP APIs declarations.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/**@defgroup BSPDefine Defines
* @ingroup nm_bsp
* @{
*/
#ifndef _NM_BSP_INTERNAL_H_
#define _NM_BSP_INTERNAL_H_
#ifdef WIN32
#include "nm_bsp_win32.h"
#endif
#ifdef __K20D50M__
#include "nm_bsp_k20d50m.h"
#endif
#ifdef __MSP430FR5739__
#include "bsp_msp430fr5739.h"
#endif
#ifdef _FREESCALE_MCF51CN128_
#include "bsp/include/nm_bsp_mcf51cn128.h"
#endif
#ifdef __MCF964548__
#include "bsp/include/nm_bsp_mc96f4548.h"
#endif
#ifdef __APP_APS3_CORTUS__
#include "nm_bsp_aps3_cortus.h"
#endif
#if (defined __SAML21J18A__) || (defined __SAML21J18B__)
#include "bsp/include/nm_bsp_saml21.h"
#endif
#if (defined __SAMD21J18A__) || (defined __SAMD21G18A__)
#include "bsp/include/nm_bsp_samd21.h"
#endif
#if (defined __SAM4S16C__) || (defined __SAM4SD32C__)
#include "bsp/include/nm_bsp_sam4s.h"
#endif
#ifdef __SAMG53N19__
#include "bsp/include/nm_bsp_samg53.h"
#endif
#ifdef __SAMG55J19__
#include "bsp/include/nm_bsp_samg55.h"
#endif
#ifdef CORTUS_APP
#include "crt_iface.h"
#endif
#ifdef NRF51
#include "nm_bsp_nrf51822.h"
#endif
#ifdef _ARDUINO_UNO_
#include "bsp/include/nm_bsp_arduino_uno.h"
#endif
#ifdef OPENMV2
#include "nm_bsp_openmv2.h"
#endif
#endif //_NM_BSP_INTERNAL_H_

View File

@ -0,0 +1,11 @@
#ifndef _NM_BSP_OPENMV2_H_
#define _NM_BSP_OPENMV2_H_
#include "conf_winc.h"
#define NM_EDGE_INTERRUPT (1)
#define NM_DEBUG CONF_WINC_DEBUG
#define NM_BSP_PRINTF CONF_WINC_PRINTF
#endif /* _NM_BSP_OPENMV2_H_ */

View File

@ -0,0 +1,177 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus wrapper APIs declarations.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _NM_BUS_WRAPPER_H_
#define _NM_BUS_WRAPPER_H_
#include "common/include/nm_common.h"
/**
BUS Type
**/
#define NM_BUS_TYPE_I2C ((uint8)0)
#define NM_BUS_TYPE_SPI ((uint8)1)
#define NM_BUS_TYPE_UART ((uint8)2)
/**
IOCTL commands
**/
#define NM_BUS_IOCTL_R ((uint8)0) /*!< Read only ==> I2C/UART. Parameter:tstrNmI2cDefault/tstrNmUartDefault */
#define NM_BUS_IOCTL_W ((uint8)1) /*!< Write only ==> I2C/UART. Parameter type tstrNmI2cDefault/tstrNmUartDefault*/
#define NM_BUS_IOCTL_W_SPECIAL ((uint8)2) /*!< Write two buffers within the same transaction
(same start/stop conditions) ==> I2C only. Parameter:tstrNmI2cSpecial */
#define NM_BUS_IOCTL_RW ((uint8)3) /*!< Read/Write at the same time ==> SPI only. Parameter:tstrNmSpiRw */
#define NM_BUS_IOCTL_WR_RESTART ((uint8)4) /*!< Write buffer then made restart condition then read ==> I2C only. parameter:tstrNmI2cSpecial */
/**
* @struct tstrNmBusCapabilities
* @brief Structure holding bus capabilities information
* @sa NM_BUS_TYPE_I2C, NM_BUS_TYPE_SPI
*/
typedef struct
{
uint16 u16MaxTrxSz; /*!< Maximum transfer size. Must be >= 16 bytes*/
} tstrNmBusCapabilities;
/**
* @struct tstrNmI2cDefault
* @brief Structure holding I2C default operation parameters
* @sa NM_BUS_IOCTL_R, NM_BUS_IOCTL_W
*/
typedef struct
{
uint8 u8SlaveAdr;
uint8 *pu8Buf; /*!< Operation buffer */
uint16 u16Sz; /*!< Operation size */
} tstrNmI2cDefault;
/**
* @struct tstrNmI2cSpecial
* @brief Structure holding I2C special operation parameters
* @sa NM_BUS_IOCTL_W_SPECIAL
*/
typedef struct
{
uint8 u8SlaveAdr;
uint8 *pu8Buf1; /*!< pointer to the 1st buffer */
uint8 *pu8Buf2; /*!< pointer to the 2nd buffer */
uint16 u16Sz1; /*!< 1st buffer size */
uint16 u16Sz2; /*!< 2nd buffer size */
} tstrNmI2cSpecial;
/**
* @struct tstrNmSpiRw
* @brief Structure holding SPI R/W parameters
* @sa NM_BUS_IOCTL_RW
*/
typedef struct
{
uint8 *pu8InBuf; /*!< pointer to input buffer.
Can be set to null and in this case zeros should be sent at MOSI */
uint8 *pu8OutBuf; /*!< pointer to output buffer.
Can be set to null and in this case data from MISO can be ignored */
uint16 u16Sz; /*!< Transfere size */
} tstrNmSpiRw;
/**
* @struct tstrNmUartDefault
* @brief Structure holding UART default operation parameters
* @sa NM_BUS_IOCTL_R, NM_BUS_IOCTL_W
*/
typedef struct
{
uint8 *pu8Buf; /*!< Operation buffer */
uint16 u16Sz; /*!< Operation size */
} tstrNmUartDefault;
/*!< Bus capabilities. This structure must be declared at platform specific bus wrapper */
extern tstrNmBusCapabilities egstrNmBusCapabilities;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @fn nm_bus_init
* @brief Initialize the bus wrapper
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_bus_init(void *);
/**
* @fn nm_bus_ioctl
* @brief send/receive from the bus
* @param [in] u8Cmd
* IOCTL command for the operation
* @param [in] pvParameter
* Arbitrary parameter depending on IOCTL
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
* @note For SPI only, it's important to be able to send/receive at the same time
*/
sint8 nm_bus_ioctl(uint8 u8Cmd, void* pvParameter);
/**
* @fn nm_bus_deinit
* @brief De-initialize the bus wrapper
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_bus_deinit(void);
/*
* @fn nm_bus_reinit
* @brief re-initialize the bus wrapper
* @param [in] void *config
* re-init configuration data
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_bus_reinit(void *);
/*
* @fn nm_bus_get_chip_type
* @brief get chip type
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
#ifdef CONF_WINC_USE_UART
uint8 nm_bus_get_chip_type(void);
#endif
#ifdef __cplusplus
}
#endif
#endif /*_NM_BUS_WRAPPER_H_*/

View File

@ -0,0 +1,165 @@
/**
*
* \file
*
* \brief This module contains common APIs declarations.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _NM_COMMON_H_
#define _NM_COMMON_H_
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_debug.h"
/**@defgroup CommonDefines CommonDefines
* @ingroup WlanDefines
*/
/**@{*/
#define M2M_TIME_OUT_DELAY 10000
/*states*/
#define M2M_SUCCESS ((sint8)0)
#define M2M_ERR_SEND ((sint8)-1)
#define M2M_ERR_RCV ((sint8)-2)
#define M2M_ERR_MEM_ALLOC ((sint8)-3)
#define M2M_ERR_TIME_OUT ((sint8)-4)
#define M2M_ERR_INIT ((sint8)-5)
#define M2M_ERR_BUS_FAIL ((sint8)-6)
#define M2M_NOT_YET ((sint8)-7)
#define M2M_ERR_FIRMWARE ((sint8)-8)
#define M2M_SPI_FAIL ((sint8)-9)
#define M2M_ERR_FIRMWARE_bURN ((sint8)-10)
#define M2M_ACK ((sint8)-11)
#define M2M_ERR_FAIL ((sint8)-12)
#define M2M_ERR_FW_VER_MISMATCH ((sint8)-13)
#define M2M_ERR_SCAN_IN_PROGRESS ((sint8)-14)
/*
Invalid argument
*/
#define M2M_ERR_INVALID_ARG ((sint8)-15)
/*i2c MAASTER ERR*/
#define I2C_ERR_LARGE_ADDRESS 0xE1UL /*the address exceed the max addressing mode in i2c flash*/
#define I2C_ERR_TX_ABRT 0xE2UL /*NO ACK from slave*/
#define I2C_ERR_OVER_SIZE 0xE3UL /**/
#define ERR_PREFIX_NMIS 0xE4UL /*wrong first four byte in flash NMIS*/
#define ERR_FIRMEWARE_EXCEED_SIZE 0xE5UL /*Total size of firmware exceed the max size 256k*/
/**/
#define PROGRAM_START 0x26961735UL
#define BOOT_SUCCESS 0x10add09eUL
#define BOOT_START 0x12345678UL
#define NBIT31 (0x80000000)
#define NBIT30 (0x40000000)
#define NBIT29 (0x20000000)
#define NBIT28 (0x10000000)
#define NBIT27 (0x08000000)
#define NBIT26 (0x04000000)
#define NBIT25 (0x02000000)
#define NBIT24 (0x01000000)
#define NBIT23 (0x00800000)
#define NBIT22 (0x00400000)
#define NBIT21 (0x00200000)
#define NBIT20 (0x00100000)
#define NBIT19 (0x00080000)
#define NBIT18 (0x00040000)
#define NBIT17 (0x00020000)
#define NBIT16 (0x00010000)
#define NBIT15 (0x00008000)
#define NBIT14 (0x00004000)
#define NBIT13 (0x00002000)
#define NBIT12 (0x00001000)
#define NBIT11 (0x00000800)
#define NBIT10 (0x00000400)
#define NBIT9 (0x00000200)
#define NBIT8 (0x00000100)
#define NBIT7 (0x00000080)
#define NBIT6 (0x00000040)
#define NBIT5 (0x00000020)
#define NBIT4 (0x00000010)
#define NBIT3 (0x00000008)
#define NBIT2 (0x00000004)
#define NBIT1 (0x00000002)
#define NBIT0 (0x00000001)
#define M2M_MAX(A,B) ((A) > (B) ? (A) : (B))
#define M2M_SEL(x,m1,m2,m3) ((x>1)?((x>2)?(m3):(m2)):(m1))
#define WORD_ALIGN(val) (((val) & 0x03) ? ((val) + 4 - ((val) & 0x03)) : (val))
#define DATA_PKT_OFFSET 4
#ifndef BIG_ENDIAN
#define BYTE_0(word) ((uint8)(((word) >> 0 ) & 0x000000FFUL))
#define BYTE_1(word) ((uint8)(((word) >> 8 ) & 0x000000FFUL))
#define BYTE_2(word) ((uint8)(((word) >> 16) & 0x000000FFUL))
#define BYTE_3(word) ((uint8)(((word) >> 24) & 0x000000FFUL))
#else
#define BYTE_0(word) ((uint8)(((word) >> 24) & 0x000000FFUL))
#define BYTE_1(word) ((uint8)(((word) >> 16) & 0x000000FFUL))
#define BYTE_2(word) ((uint8)(((word) >> 8 ) & 0x000000FFUL))
#define BYTE_3(word) ((uint8)(((word) >> 0 ) & 0x000000FFUL))
#endif
typedef enum{
M2M_REQ_GRP_MAIN = 0, M2M_REQ_GRP_WIFI, M2M_REQ_GRP_IP, M2M_REQ_GRP_HIF, M2M_REQ_GRP_OTA
}tenuM2mReqGrp;
typedef enum{
M2M_REQ_CONFIG_PKT,
M2M_REQ_DATA_PKT = NBIT7
}tenuM2mReqPkt;
/**@}*/
#ifdef __cplusplus
extern "C" {
#endif
NMI_API void m2m_memcpy(uint8* pDst,uint8* pSrc,uint32 sz);
NMI_API void m2m_memset(uint8* pBuf,uint8 val,uint32 sz);
NMI_API uint16 m2m_strlen(uint8 * pcStr);
NMI_API sint8 m2m_memcmp(uint8 *pu8Buff1,uint8 *pu8Buff2 ,uint32 u32Size);
NMI_API uint8 m2m_strncmp(uint8 *pcS1, uint8 *pcS2, uint16 u16Len);
NMI_API uint8 * m2m_strstr(uint8 *pcIn, uint8 *pcStr);
NMI_API uint8 m2m_checksum(uint8* buf, int sz);
#ifdef __cplusplus
}
#endif
#endif /*_NM_COMMON_H_*/

View File

@ -0,0 +1,125 @@
/**
*
* \file
*
* \brief This module contains debug APIs declarations.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _NM_DEBUG_H_
#define _NM_DEBUG_H_
#include "bsp/include/nm_bsp.h"
#include "bsp/include/nm_bsp_internal.h"
/**@defgroup DebugDefines DebugDefines
* @ingroup WlanDefines
*/
/**@{*/
#define M2M_LOG_NONE 0
#define M2M_LOG_ERROR 1
#define M2M_LOG_INFO 2
#define M2M_LOG_REQ 3
#define M2M_LOG_DBG 4
#if (defined __APP_APS3_CORTUS__)
#define M2M_LOG_LEVEL M2M_LOG_ERROR
#else
#define M2M_LOG_LEVEL M2M_LOG_REQ
#endif
/**/
#if !((defined __MSP430FR5739)||(defined __MCF964548__))
#define M2M_ERR(...)
#define M2M_INFO(...)
#define M2M_REQ(...)
#define M2M_DBG(...)
#if (CONF_WINC_DEBUG == 1)
#define M2M_PRINT(...) do{CONF_WINC_PRINTF(__VA_ARGS__);CONF_WINC_PRINTF("\r");}while(0)
#if (M2M_LOG_LEVEL >= M2M_LOG_ERROR)
#undef M2M_ERR
#define M2M_ERR(...) do{CONF_WINC_PRINTF("(APP)(ERR)[%s][%d]",__FUNCTION__,__LINE__); CONF_WINC_PRINTF(__VA_ARGS__);CONF_WINC_PRINTF("\r");}while(0)
#if (M2M_LOG_LEVEL >= M2M_LOG_INFO)
#undef M2M_INFO
#define M2M_INFO(...) do{CONF_WINC_PRINTF("(APP)(INFO)"); CONF_WINC_PRINTF(__VA_ARGS__);CONF_WINC_PRINTF("\r");}while(0)
#if (M2M_LOG_LEVEL >= M2M_LOG_REQ)
#undef M2M_REQ
#define M2M_REQ(...) do{CONF_WINC_PRINTF("(APP)(R)"); CONF_WINC_PRINTF(__VA_ARGS__);CONF_WINC_PRINTF("\r");}while(0)
#if (M2M_LOG_LEVEL >= M2M_LOG_DBG)
#undef M2M_DBG
#define M2M_DBG(...) do{CONF_WINC_PRINTF("(APP)(DBG)[%s][%d]",__FUNCTION__,__LINE__); CONF_WINC_PRINTF(__VA_ARGS__);CONF_WINC_PRINTF("\r");}while(0)
#endif
#endif
#endif
#endif
#else
#define M2M_ERR(...)
#define M2M_DBG(...)
#define M2M_REQ(...)
#define M2M_INFO(...)
#define M2M_PRINT(...)
#endif
#else
#if (!defined __MCF964548__)||(!defined __SAMD21J18A__)
static void M2M_ERR(const char *_format, ...) //__attribute__ ((__format__ (M2M_ERR, 1, 2)))
{
}
static void M2M_DBG(const char *_format, ...) //__attribute__ ((__format__ (M2M_DBG, 1, 2)))
{
}
static void M2M_REQ(const char *_format, ...) //__attribute__ ((__format__ (M2M_DBG, 1, 2)))
{
}
static void M2M_INFO(const char *_format, ...) // __attribute__ ((__format__ (M2M_INFO, 1, 2)))
{
}
static void M2M_PRINT(const char *_format, ...) // __attribute__ ((__format__ (M2M_INFO, 1, 2)))
{
}
static void CONF_WINC_PRINTF(const char *_format, ...)
{
}
#endif
#endif
/**@}*/
#endif /* _NM_DEBUG_H_ */

View File

@ -0,0 +1,113 @@
/**
*
* \file
*
* \brief WINC1500 configuration.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef CONF_WINC_H_INCLUDED
#define CONF_WINC_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#include "stdio.h"
/*
---------------------------------
---------- PIN settings ---------
---------------------------------
*/
#define CONF_WINC_PIN_RESET IOPORT_CREATE_PIN(PIOA, 24)
#define CONF_WINC_PIN_CHIP_ENABLE IOPORT_CREATE_PIN(PIOA, 6)
#define CONF_WINC_PIN_WAKE IOPORT_CREATE_PIN(PIOA, 25)
/*
---------------------------------
---------- SPI settings ---------
---------------------------------
*/
#define CONF_WINC_USE_SPI (1)
/** SPI pin and instance settings. */
#define CONF_WINC_SPI SPI
#define CONF_WINC_SPI_ID ID_SPI
#define CONF_WINC_SPI_MISO_GPIO SPI_MISO_GPIO
#define CONF_WINC_SPI_MISO_FLAGS SPI_MISO_FLAGS
#define CONF_WINC_SPI_MOSI_GPIO SPI_MOSI_GPIO
#define CONF_WINC_SPI_MOSI_FLAGS SPI_MOSI_FLAGS
#define CONF_WINC_SPI_CLK_GPIO SPI_SPCK_GPIO
#define CONF_WINC_SPI_CLK_FLAGS SPI_SPCK_FLAGS
#define CONF_WINC_SPI_CS_GPIO SPI_NPCS0_GPIO
#define CONF_WINC_SPI_CS_FLAGS PIO_OUTPUT_1
#define CONF_WINC_SPI_NPCS (0)
/** SPI delay before SPCK and between consecutive transfer. */
#define CONF_WINC_SPI_DLYBS (0)
#define CONF_WINC_SPI_DLYBCT (0)
/** SPI interrupt pin. */
#define CONF_WINC_SPI_INT_PIN IOPORT_CREATE_PIN(PIOA, 1)
#define CONF_WINC_SPI_INT_PIO PIOA
#define CONF_WINC_SPI_INT_PIO_ID ID_PIOA
#define CONF_WINC_SPI_INT_MASK (1 << 1)
#define CONF_WINC_SPI_INT_PRIORITY (0)
/** Clock polarity & phase. */
#define CONF_WINC_SPI_POL (0)
#define CONF_WINC_SPI_PHA (1)
/** SPI clock. */
#define CONF_WINC_SPI_CLOCK (12000000)
/*
---------------------------------
--------- Debug Options ---------
---------------------------------
*/
#define CONF_WINC_DEBUG (1)
#define CONF_WINC_PRINTF printf
#ifdef __cplusplus
}
#endif
#endif /* CONF_WINC_H_INCLUDED */

View File

@ -0,0 +1,587 @@
/**
*
* \file
*
* \brief NMC1500 Peripherals Application Interface.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifdef _M2M_ATE_FW_
#ifndef _M2M_ATE_MODE_H_
#define _M2M_ATE_MODE_H_
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "common/include/nm_common.h"
#include "driver/include/m2m_types.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#define M2M_ATE_MAX_NUM_OF_RATES (20)
/*!< Maximum number of all rates (b,g and n)
*/
#define M2M_ATE_MAX_FRAME_LENGTH (1024)
/*!< Maximum number of length for each frame
*/
#define M2M_ATE_MIN_FRAME_LENGTH (1)
/*!< Minimum number of length for each frame
*/
#define M2M_ATE_SUCCESS (M2M_SUCCESS)
/*!< No Error and operation has been completed successfully.
*/
#define M2M_ATE_ERR_VALIDATE (M2M_ERR_FAIL)
/*!< Error in parameters passed to functions.
*/
#define M2M_ATE_ERR_TX_ALREADY_RUNNING (-1)
/*!< This means that TX case is already running and RX or even TX can't start without stopping it first.
*/
#define M2M_ATE_ERR_RX_ALREADY_RUNNING (-2)
/*!< This means that RX case is already running and TX or even RX can't start without stopping it first.
*/
#define M2M_ATE_ERR_UNHANDLED_CASE (-3)
/*!< Invalid case.
*/
#define M2M_ATE_RX_DISABLE_DA 0x0
#define M2M_ATE_RX_ENABLE_DA 0x1
#define M2M_ATE_RX_DISABLE_SA 0x0
#define M2M_ATE_RX_ENABLE_SA 0x1
#define M2M_ATE_DISABLE_SELF_MACADDR 0x0
#define M2M_ATE_SET_SELF_MACADDR 0x1
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
*@enum tenuM2mAteFwState
*@brief Enumeration used for change ATE firmware state
*/
typedef enum {
M2M_ATE_FW_STATE_STOP = 0x00,
/*!< State to stop ATE firmware
*/
M2M_ATE_FW_STATE_RUN = 0x01,
/*!< State to run ATE firmware
*/
}tenuM2mAteFwState;
/*!
*@enum tenuM2mAteTxRates
*@brief Used to get value of rate referenced by this index
*/
typedef enum {
M2M_ATE_TX_RATE_1_Mbps_INDEX = 0x00,
M2M_ATE_TX_RATE_2_Mbps_INDEX = 0x01,
M2M_ATE_TX_RATE_55_Mbps_INDEX = 0x02,
M2M_ATE_TX_RATE_11_Mbps_INDEX = 0x03,
/*!< B-Rates
*/
M2M_ATE_TX_RATE_6_Mbps_INDEX = 0x04,
M2M_ATE_TX_RATE_9_Mbps_INDEX = 0x05,
M2M_ATE_TX_RATE_12_Mbps_INDEX = 0x06,
M2M_ATE_TX_RATE_18_Mbps_INDEX = 0x07,
M2M_ATE_TX_RATE_24_Mbps_INDEX = 0x08,
M2M_ATE_TX_RATE_36_Mbps_INDEX = 0x09,
M2M_ATE_TX_RATE_48_Mbps_INDEX = 0x0A,
M2M_ATE_TX_RATE_54_Mbps_INDEX = 0x0B,
/*!< G-Rates
*/
M2M_ATE_TX_RATE_MCS_0_INDEX = 0x0C,
M2M_ATE_TX_RATE_MCS_1_INDEX = 0x0D,
M2M_ATE_TX_RATE_MCS_2_INDEX = 0x0E,
M2M_ATE_TX_RATE_MCS_3_INDEX = 0x0F,
M2M_ATE_TX_RATE_MCS_4_INDEX = 0x10,
M2M_ATE_TX_RATE_MCS_5_INDEX = 0x11,
M2M_ATE_TX_RATE_MCS_6_INDEX = 0x12,
M2M_ATE_TX_RATE_MCS_7_INDEX = 0x13,
/*!< N-Rates
*/
}tenuM2mAteTxIndexOfRates;
/*!
*@enum tenuM2mAteTxDutyCycle
*@brief Values of duty cycle
*/
typedef enum {
M2M_ATE_TX_DUTY_1 = 0x01,
M2M_ATE_TX_DUTY_2 = 0x02,
M2M_ATE_TX_DUTY_3 = 0x03,
M2M_ATE_TX_DUTY_4 = 0x04,
M2M_ATE_TX_DUTY_5 = 0x05,
M2M_ATE_TX_DUTY_6 = 0x06,
M2M_ATE_TX_DUTY_7 = 0x07,
M2M_ATE_TX_DUTY_8 = 0x08,
M2M_ATE_TX_DUTY_9 = 0x09,
M2M_ATE_TX_DUTY_10 = 0xA0,
}tenuM2mAteTxDutyCycle;
#define M2M_ATE_TX_DUTY_MAX_VALUE M2M_ATE_TX_DUTY_1
/*!< The maximum value of duty cycle
*/
#define M2M_ATE_TX_DUTY_MIN_VALUE M2M_ATE_TX_DUTY_10
/*!< The minimum value of duty cycle
*/
/*!
*@enum tenuM2mAteTxDpdControl
*@brief Allowed values for DPD control
*/
typedef enum {
M2M_ATE_TX_DPD_DYNAMIC = 0x00,
M2M_ATE_TX_DPD_BYPASS = 0x01,
M2M_ATE_TX_DPD_ENABLED = 0x02,
}tenuM2mAteTxDpdControl;
/*!
*@enum tenuM2mAteTxGainSetting
*@brief Options for TX gain selection mode
*/
typedef enum {
M2M_ATE_TX_GAIN_DYNAMIC = 0x00,
M2M_ATE_TX_GAIN_BYPASS = 0x01,
M2M_ATE_TX_GAIN_FCC = 0x02,
M2M_ATE_TX_GAIN_TELEC = 0x03,
}tenuM2mAteTxGainSetting;
/*!
*@enum tenuM2mAtePMUSetting
*@brief Used to Enable PMU or disable it
*/
typedef enum {
M2M_ATE_PMU_DISBLE = 0x00,
M2M_ATE_PMU_ENABLE = 0x01,
}tenuM2mAtePMUSetting;
/*!
*@enum tenuM2mAteTxSource
*@brief Used to define if enable PHY continues mode or MAC
*/
typedef enum {
M2M_ATE_TX_SRC_MAC = 0x00,
M2M_ATE_TX_SRC_PHY = 0x01,
}tenuM2mAteTxSource;
/*!
*@enum tenuM2mAteTxMode
*@brief Used to define type of TX mode either normal or CW(Continuous Wave) TX sequence
*/
typedef enum {
M2M_ATE_TX_MODE_NORM = 0x00,
M2M_ATE_TX_MODE_CW = 0x01,
}tenuM2mAteTxMode;
/*!
*@enum tenuM2mAteChannels
*@brief Available channels for TX and RX
*/
typedef enum {
M2M_ATE_CHANNEL_1 = 0x01,
M2M_ATE_CHANNEL_2 = 0x02,
M2M_ATE_CHANNEL_3 = 0x03,
M2M_ATE_CHANNEL_4 = 0x04,
M2M_ATE_CHANNEL_5 = 0x05,
M2M_ATE_CHANNEL_6 = 0x06,
M2M_ATE_CHANNEL_7 = 0x07,
M2M_ATE_CHANNEL_8 = 0x08,
M2M_ATE_CHANNEL_9 = 0x09,
M2M_ATE_CHANNEL_10 = 0x0A,
M2M_ATE_CHANNEL_11 = 0x0B,
M2M_ATE_CHANNEL_12 = 0x0C,
M2M_ATE_CHANNEL_13 = 0x0D,
M2M_ATE_CHANNEL_14 = 0x0E,
}tenuM2mAteChannels;
/*!
*@struct tstrM2mAteRxStatus
*@brief Used to save statistics of RX case
*/
typedef struct {
uint32 num_rx_pkts;
/*!< Number of total RX packet
*/
uint32 num_err_pkts;
/*!< Number of RX failed packets
*/
uint32 num_good_pkts;
/*!< Number of RX packets actually received
*/
} tstrM2mAteRxStatus;
/*!
*@struct tstrM2mAteTx
*@brief Used as data source in case of enabling TX test case
*/
typedef struct {
uint32 num_frames;
/*!< Number of frames to be sent where maximum number allowed is 4294967295 ul, and ZERO means infinite number of frames
*/
uint32 data_rate;
/*!< Rate to sent packets over to select rate use value of \ref tenuM2mAteTxIndexOfRates and pass it to \ref m2m_ate_get_tx_rate
*/
uint8 channel_num;
/*!< Channel number \ref tenuM2mAteChannels
*/
uint8 duty_cycle;
/*!< Duty cycle value between from 1 to 10, where maximum = 1, minimum = 10 \ref tenuM2mAteTxDutyCycle
*/
uint16 frame_len;
/*!< Use \ref M2M_ATE_MAX_FRAME_LENGTH (1024) as the maximum value while \ref M2M_ATE_MIN_FRAME_LENGTH (1) is the minimum value
*/
uint8 tx_gain_sel;
/*!< TX gain mode selection value \ref tenuM2mAteTxGainSetting
*/
uint8 dpd_ctrl;
/*!< DPD mode value\ref tenuM2mAteTxDpdControl
*/
uint8 use_pmu;
/*!< This is 0 if PMU is not used otherwise it must be be 1 \ref tenuM2mAtePMUSetting
*/
uint8 phy_burst_tx;
/*!< Source of Burst TX either PHY or MAC\ref tenuM2mAteTxSource
*/
uint8 cw_tx;
/*!< Mode of Burst TX either normal TX sequence or CW(Continuous Wave) TX sequence \ref tenuM2mAteTxMode
*/
uint32 xo_offset_x1000;
/*!< Signed XO offset value in PPM (Part Per Million) multiplied by 1000.
*/
uint8 use_efuse_xo_offset;
/*!< Set to 0 to use the XO offset provided in xo_offset_x1000. Set to 1 to use XO offset programmed on WINC efuse.
*/
uint8 peer_mac_addr[6];
/*!< Set peer address to send directed frames to a certain address.
*/
} tstrM2mAteTx;
/*!
*@struct tstrM2mAteRx
*@brief Used as data source in case of enabling RX test case
*/
typedef struct {
uint8 channel_num;
/*!< Channel number \ref tenuM2mAteChannels
*/
uint8 use_pmu;
/*!< This is 0 if PMU is not used otherwise it must be be 1 \ref tenuM2mAtePMUSetting
*/
uint32 xo_offset_x1000;
/*!< Signed XO offset value in PPM (Part Per Million) multiplied by 1000.
*/
uint8 use_efuse_xo_offset;
/*!< Set to 0 to use the XO offset provided in xo_offset_x1000. Set to 1 to use XO offset programmed on WINC efuse.
*/
uint8 self_mac_addr[6];
/*!< Set to the self mac address required to be overriden.
*/
uint8 peer_mac_addr[6];
/*!< Set to the source mac address expected to filter frames from.
*/
uint8 mac_filter_en_da;
/*!< Flag set to enable or disable reception with destination address as a filter.
*/
uint8 mac_filter_en_sa;
/*!< Flag set to enable or disable reception with source address as a filter.
*/
uint8 override_self_mac_addr;
/*!< Flag set to enable or disable self mac address feature.
*/
} tstrM2mAteRx;
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#ifdef __cplusplus
extern "C" {
#endif
/*!
@fn \
sint8 m2m_ate_init(void);
@brief
This function used to download ATE firmware from flash and start it
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_init(void);
/*!
@fn \
sint8 m2m_ate_deinit(void);
@brief
De-Initialization of ATE firmware mode
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_deinit(void);
/*!
@fn \
sint8 m2m_ate_set_fw_state(uint8);
@brief
This function used to change ATE firmware status from running to stopped or vice versa.
@param [in] u8State
Required state of ATE firmware, one of \ref tenuM2mAteFwState enumeration values.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init
*/
sint8 m2m_ate_set_fw_state(uint8);
/*!
@fn \
sint8 m2m_ate_get_fw_state(uint8);
@brief
This function used to return status of ATE firmware.
@return
The function SHALL return status of ATE firmware, one of \ref tenuM2mAteFwState enumeration values.
\sa
m2m_ate_init, m2m_ate_set_fw_state
*/
sint8 m2m_ate_get_fw_state(void);
/*!
@fn \
uint32 m2m_ate_get_tx_rate(uint8);
@brief
This function used to return value of TX rate required by application developer.
@param [in] u8Index
Index of required rate , one of \ref tenuM2mAteTxIndexOfRates enumeration values.
@return
The function SHALL return 0 for in case of failure otherwise selected rate value.
\sa
tenuM2mAteTxIndexOfRates
*/
uint32 m2m_ate_get_tx_rate(uint8);
/*!
@fn \
sint8 m2m_ate_get_tx_status(void);
@brief
This function used to return status of TX test case either running or stopped.
@return
The function SHALL return status of ATE firmware, 1 if TX is running otherwise 0.
\sa
m2m_ate_start_tx, m2m_ate_stop_tx
*/
sint8 m2m_ate_get_tx_status(void);
/*!
@fn \
sint8 m2m_ate_start_tx(tstrM2mAteTx *)
@brief
This function used to start TX test case.
@param [in] strM2mAteTx
Type of \ref tstrM2mAteTx, with the values required to enable TX test case. You must use \ref m2m_ate_init first.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_stop_tx, m2m_ate_get_tx_status
*/
sint8 m2m_ate_start_tx(tstrM2mAteTx *);
/*!
@fn \
sint8 m2m_ate_stop_tx(void)
@brief
This function used to stop TX test case.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_start_tx, m2m_ate_get_tx_status
*/
sint8 m2m_ate_stop_tx(void);
/*!
@fn \
sint8 m2m_ate_get_rx_status(uint8);
@brief
This function used to return status of RX test case either running or stopped.
@return
The function SHALL return status of ATE firmware, 1 if RX is running otherwise 0.
\sa
m2m_ate_start_rx, m2m_ate_stop_rx
*/
sint8 m2m_ate_get_rx_status(void);
/*!
@fn \
sint8 m2m_ate_start_rx(tstrM2mAteRx *)
@brief
This function used to start RX test case.
@param [in] strM2mAteRx
Type of \ref tstrM2mAteRx, with the values required to enable RX test case. You must use \ref m2m_ate_init first.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_stop_rx, m2m_ate_get_rx_status
*/
sint8 m2m_ate_start_rx(tstrM2mAteRx *);
/*!
@fn \
sint8 m2m_ate_stop_rx(void)
@brief
This function used to stop RX test case.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_start_rx, m2m_ate_get_rx_status
*/
sint8 m2m_ate_stop_rx(void);
/*!
@fn \
sint8 m2m_ate_read_rx_status(tstrM2mAteRxStatus *)
@brief
This function used to read RX statistics from ATE firmware.
@param [out] strM2mAteRxStatus
Type of \ref tstrM2mAteRxStatus used to save statistics of RX test case. You must use \ref m2m_ate_start_rx first.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_start_rx
*/
sint8 m2m_ate_read_rx_status(tstrM2mAteRxStatus *);
/*!
@fn \
sint8 m2m_ate_set_dig_gain(double dGaindB)
@brief
This function is used to set the digital gain
@param [in] double dGaindB
The digital gain value required to be set.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_set_dig_gain(double dGaindB);
/*!
@fn \
sint8 m2m_ate_get_dig_gain(double * dGaindB)
@brief
This function is used to get the digital gain
@param [out] double * dGaindB
The retrieved digital gain value obtained from HW registers in dB.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_get_dig_gain(double * dGaindB);
/*!
@fn \
sint8 m2m_ate_get_pa_gain(double *paGaindB)
@brief
This function is used to get the PA gain
@param [out] double *paGaindB
The retrieved PA gain value obtained from HW registers in dB.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_get_pa_gain(double *paGaindB);
/*!
@fn \
sint8 m2m_ate_get_ppa_gain(double * ppaGaindB)
@brief
This function is used to get the PPA gain
@param [out] uint32 * ppaGaindB
The retrieved PPA gain value obtained from HW registers in dB.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_get_ppa_gain(double * ppaGaindB);
/*!
@fn \
sint8 m2m_ate_get_tot_gain(double * totGaindB)
@brief
This function is used to calculate the total gain
@param [out] double * totGaindB
The retrieved total gain value obtained from calculations made based on the digital gain, PA and PPA gain values.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_get_tot_gain(double * totGaindB);
#ifdef __cplusplus
}
#endif
#endif /* _M2M_CONFIG_MODE_H_ */
#endif //_M2M_ATE_FW_

View File

@ -0,0 +1,241 @@
/**
*
* \file
*
* \brief This module contains M2M host interface APIs implementation.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _M2M_HIF_
#define _M2M_HIF_
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "common/include/nm_common.h"
/*!< Include depends on UNO Board is used or not*/
#ifdef ENABLE_UNO_BOARD
#include "m2m_uno_hif.h"
#endif
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#define M2M_HIF_MAX_PACKET_SIZE (1600 - 4)
/*!< Maximum size of the buffer could be transferred between Host and Firmware.
*/
#define M2M_HIF_HDR_OFFSET (sizeof(tstrHifHdr) + 4)
/**
* @struct tstrHifHdr
* @brief Structure to hold HIF header
*/
typedef struct
{
uint8 u8Gid; /*!< Group ID */
uint8 u8Opcode; /*!< OP code */
uint16 u16Length; /*!< Payload length */
}tstrHifHdr;
#ifdef __cplusplus
extern "C" {
#endif
/*!
@typedef typedef void (*tpfHifCallBack)(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr);
@brief used to point to Wi-Fi call back function depend on Arduino project or other projects.
@param [in] u8OpCode
HIF Opcode type.
@param [in] u16DataSize
HIF data length.
@param [in] u32Addr
HIF address.
@param [in] grp
HIF group type.
*/
typedef void (*tpfHifCallBack)(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr);
/**
* @fn NMI_API sint8 hif_init(void * arg);
* @brief
To initialize HIF layer.
* @param [in] arg
* Pointer to the arguments.
* @return
The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_init(void * arg);
/**
* @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.
*/
NMI_API sint8 hif_deinit(void * arg);
/**
* @fn NMI_API sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize,
uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset)
* @brief Send packet using host interface.
* @param [in] u8Gid
* Group ID.
* @param [in] u8Opcode
* Operation ID.
* @param [in] pu8CtrlBuf
* Pointer to the Control buffer.
* @param [in] u16CtrlBufSize
Control buffer size.
* @param [in] u16DataOffset
Packet Data offset.
* @param [in] pu8DataBuf
* Packet buffer Allocated by the caller.
* @param [in] u16DataSize
Packet buffer size (including the HIF header).
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize,
uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset);
/*
* @fn hif_receive
* @brief Host interface interrupt serviece routine
* @param [in] u32Addr
* Receive start address
* @param [out] pu8Buf
* Pointer to receive buffer. Allocated by the caller
* @param [in] u16Sz
* Receive buffer size
* @param [in] isDone
* If you don't need any more packets send True otherwise send false
* @return
The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_receive(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz, uint8 isDone);
/**
* @fn hif_register_cb
* @brief
To set Callback function for every Component.
* @param [in] u8Grp
* Group to which the Callback function should be set.
* @param [in] fn
* function to be set to the specified group.
* @return
The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_register_cb(uint8 u8Grp,tpfHifCallBack fn);
/**
* @fn NMI_API sint8 hif_chip_sleep(void);
* @brief
To make the chip sleep.
* @return
The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_chip_sleep(void);
/**
* @fn NMI_API sint8 hif_chip_wake(void);
* @brief
To Wakeup the chip.
* @return
The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_chip_wake(void);
/*!
@fn \
NMI_API void hif_set_sleep_mode(uint8 u8Pstype);
@brief
Set the sleep mode of the HIF layer.
@param [in] u8Pstype
Sleep mode.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API void hif_set_sleep_mode(uint8 u8Pstype);
/*!
@fn \
NMI_API uint8 hif_get_sleep_mode(void);
@brief
Get the sleep mode of the HIF layer.
@return
The function SHALL return the sleep mode of the HIF layer.
*/
NMI_API uint8 hif_get_sleep_mode(void);
#ifdef CORTUS_APP
/**
* @fn hif_Resp_handler(uint8 *pu8Buffer, uint16 u16BufferSize)
* @brief
Response handler for HIF layer.
* @param [in] pu8Buffer
Pointer to the buffer.
* @param [in] u16BufferSize
Buffer size.
* @return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 hif_Resp_handler(uint8 *pu8Buffer, uint16 u16BufferSize);
#endif
/**
* @fn hif_handle_isr(void)
* @brief
Handle interrupt received from NMC1500 firmware.
* @return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 hif_handle_isr(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,330 @@
/**
*
* \file
*
* \brief NMC1500 IoT OTA Interface.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef __M2M_OTA_H__
#define __M2M_OTA_H__
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "common/include/nm_common.h"
#include "driver/include/m2m_types.h"
/**@defgroup OTATYPEDEF WLANTypedef
* @ingroup WlanEnums
*/
/* @{ */
/*!
@typedef void (*tpfOtaNotifCb) (tstrOtaUpdateInfo *);
@brief A callback to get notification about an potential OTA update.
@param[in] pstrOtaUpdateInfo A structure to provide notification payload.
@sa
tstrOtaUpdateInfo
@warning
The notification is not supported (Not implemented yet)
*/
typedef void (*tpfOtaNotifCb) (tstrOtaUpdateInfo * pstrOtaUpdateInfo);
/*!
@typedef void (*tpfOtaUpdateCb) (uint8 u8OtaUpdateStatusType ,uint8 u8OtaUpdateStatus);
@brief
A callback to get OTA status update, the callback provide the status type and its status the OTA callback provides the download status,
the switch to the downloaded firmware status and roll-back status.
@param[in] u8OtaUpdateStatusType Possible values are listed in tenuOtaUpdateStatusType. Possible types are:
- [DL_STATUS](@ref DL_STATUS)
- [SW_STATUS](@ref SW_STATUS)
- [RB_STATUS](@ref RB_STATUS)
@param[in] u8OtaUpdateStatus Possible values are listed in tenuOtaUpdateStatus.
@see
tenuOtaUpdateStatusType
tenuOtaUpdateStatus
*/
typedef void (*tpfOtaUpdateCb) (uint8 u8OtaUpdateStatusType ,uint8 u8OtaUpdateStatus);
/**@}*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup OtaInitFn m2m_ota_init
* @ingroup WLANAPI
* Synchronous initialization function for the OTA layer by registering the update callback.
* The notification callback is not supported at the current version. Calling this API is a
* MUST for all the OTA API's.
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb,tpfOtaNotifCb pfOtaNotifCb)
@param [in] pfOtaUpdateCb
OTA Update callback function
@param [in] pfOtaNotifCb
OTA notify callback function
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb,tpfOtaNotifCb pfOtaNotifCb);
/**@}*/
/** @defgroup OtaNotifStFn m2m_ota_notif_set_url
* @ingroup WLANAPI
* Set the OTA notification server URL, the functions need to be called before any check for update
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url);
@param [in] u8Url
Set the OTA notification server URL, the functions need to be called before any check for update.
@warning
Calling m2m_ota_init is required
Notification Server is not supported in the current version (function is not implemented)
@see
m2m_ota_init
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url);
/**@}*/
/** @defgroup OtaNotifCheckFn m2m_ota_notif_check_for_update
* @ingroup WLANAPI
* Synchronous function to check for the OTA update using the Notification Server
* URL. Function is not implemented (not supported at the current version)
*
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_notif_check_for_update(void);
@warning
Function is not implemented (not supported at the current version)
@sa
m2m_ota_init
m2m_ota_notif_set_url
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_check_for_update(void);
/**@}*/
/** @defgroup OtaSched m2m_ota_notif_sched
* @ingroup WLANAPI
* Schedule OTA notification Server check for update request after specific number of days
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
@param [in] u32Period
Period in days
@sa
m2m_ota_init
m2m_ota_notif_check_for_update
m2m_ota_notif_set_url
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
/**@}*/
/** @defgroup OtaStartUpdatefn m2m_ota_start_update
* @ingroup WLANAPI
* Request OTA start update using the downloaded URL, the OTA module will download the OTA image and ensure integrity of the image,
* and update the validity of the image in control structure. Switching to that image requires calling @ref m2m_ota_switch_firmware API.
* As a prerequisite @ref m2m_ota_init should be called before using @ref m2m_ota_start().
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_start_update(uint8 * u8DownloadUrl);
@param [in] u8DownloadUrl
The download firmware URL, you get it from device info according to the application server
@warning
Calling this API does not guarantee OTA WINC image update, It depends on the connection with the download server and the validity of the image.
If the API response is failure this may invalidate the roll-back image if it was previously valid, since the WINC does not have any internal memory
except the flash roll-back image location to validate the downloaded image from
@see
m2m_ota_init
tpfOtaUpdateCb
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
\section Example
The example shows an example of how the OTA image update is carried out.
@code
static void OtaUpdateCb(uint8 u8OtaUpdateStatusType ,uint8 u8OtaUpdateStatus)
{
if(u8OtaUpdateStatusType == DL_STATUS) {
if(u8OtaUpdateStatus == OTA_STATUS_SUCSESS) {
//switch to the upgraded firmware
m2m_ota_switch_firmware();
}
}
else if(u8OtaUpdateStatusType == SW_STATUS) {
if(u8OtaUpdateStatus == OTA_STATUS_SUCSESS) {
M2M_INFO("Now OTA successfully done");
//start the host SW upgrade then system reset is required (Reinitialize the driver)
}
}
}
void wifi_event_cb(uint8 u8WiFiEvent, void * pvMsg)
{
case M2M_WIFI_REQ_DHCP_CONF:
{
//after successfully connection, start the over air upgrade
m2m_ota_start_update(OTA_URL);
}
break;
default:
break;
}
int main (void)
{
tstrWifiInitParam param;
tstr1xAuthCredentials gstrCred1x = AUTH_CREDENTIALS;
nm_bsp_init();
m2m_memset((uint8*)&param, 0, sizeof(param));
param.pfAppWifiCb = wifi_event_cb;
//Initialize the WINC Driver
ret = m2m_wifi_init(&param);
if (M2M_SUCCESS != ret)
{
M2M_ERR("Driver Init Failed <%d>\n",ret);
while(1);
}
//Initialize the OTA module
m2m_ota_init(OtaUpdateCb,NULL);
//connect to AP that provide connection to the OTA server
m2m_wifi_default_connect();
while(1)
{
//Handle the app state machine plus the WINC event handler
while(m2m_wifi_handle_events(NULL) != M2M_SUCCESS) {
}
}
}
@endcode
*/
NMI_API sint8 m2m_ota_start_update(uint8 * u8DownloadUrl);
/**@}*/
/** @defgroup OtaRollbackfn m2m_ota_rollback
* @ingroup WLANAPI
Request OTA Roll-back to the old (other) WINC image, the WINC firmware will check the validation of the Roll-back image
and switch to it if it is valid.
If the API response is success, system restart is required (re-initialize the driver with hardware rest) update the host driver version may
be required if it is did not match the minimum version supported by the WINC firmware.
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_rollback(void);
@sa
m2m_ota_init
m2m_ota_start_update
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_rollback(void);
/**@}*/
/**@}*/
/** @defgroup OtaSwitchFirmware m2m_ota_switch_firmware
* @ingroup WLANAPI
* Switch to the upgraded Firmware, that API will update the control structure working image to the upgraded image
take effect will be on the next system restart
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_switch_firmware(void);
@warning
It is important to note that if the API succeeds, system restart is required (re-initializing the driver with hardware reset) updating the host driver version may be required
if it does not match the minimum driver version supported by the WINC's firmware.
@sa
m2m_ota_init
m2m_ota_start_update
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_switch_firmware(void);
/**@}*/
NMI_API sint8 m2m_ota_test(void);
#ifdef __cplusplus
}
#endif
#endif /* __M2M_OTA_H__ */

View File

@ -0,0 +1,407 @@
/**
*
* \file
*
* \brief NMC1500 Peripherals Application Interface.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _M2M_PERIPH_H_
#define _M2M_PERIPH_H_
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "common/include/nm_common.h"
#include "driver/include/m2m_types.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
@struct \
tstrPerphInitParam
@brief
Peripheral module initialization parameters.
*/
typedef struct {
void * arg;
} tstrPerphInitParam;
/*!
@enum \
tenuGpioNum
@brief
A list of GPIO numbers configurable through the m2m_periph module.
*/
typedef enum {
M2M_PERIPH_GPIO15, /*!< GPIO15 pad */
M2M_PERIPH_GPIO16, /*!< GPIO16 pad */
M2M_PERIPH_GPIO18, /*!< GPIO18 pad */
M2M_PERIPH_GPIO_MAX
} tenuGpioNum;
/*!
@enum \
tenuI2cMasterSclMuxOpt
@brief
Allowed pin multiplexing options for I2C master SCL signal.
*/
typedef enum {
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_HOST_WAKEUP, /*!< I2C master SCL is avaiable on HOST_WAKEUP. */
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_SD_DAT3, /*!< I2C master SCL is avaiable on SD_DAT3 (GPIO 7). */
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_GPIO13, /*!< I2C master SCL is avaiable on GPIO 13. */
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_GPIO4, /*!< I2C master SCL is avaiable on GPIO 4.*/
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_I2C_SCL, /*!< I2C master SCL is avaiable on I2C slave SCL. */
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_NUM
} tenuI2cMasterSclMuxOpt;
/*!
@enum \
tenuI2cMasterSdaMuxOpt
@brief
Allowed pin multiplexing options for I2C master SDA signal.
*/
typedef enum {
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_RTC_CLK , /*!< I2C master SDA is avaiable on RTC_CLK. */
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_SD_CLK, /*!< I2C master SDA is avaiable on SD_CLK (GPIO 8). */
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_GPIO14, /*!< I2C master SDA is avaiable on GPIO 14. */
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_GPIO6, /*!< I2C master SDA is avaiable on GPIO 6.*/
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_I2C_SDA, /*!< I2C master SDA is avaiable on I2C slave SDA. */
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_NUM
} tenuI2cMasterSdaMuxOpt;
/*!
@struct \
tstrI2cMasterInitParam
@brief
I2C master configuration parameters.
@sa
tenuI2cMasterSclMuxOpt
tenuI2cMasterSdaMuxOpt
*/
typedef struct {
uint8 enuSclMuxOpt; /*!< SCL multiplexing option. Allowed value are defined in tenuI2cMasterSclMuxOpt */
uint8 enuSdaMuxOpt; /*!< SDA multiplexing option. Allowed value are defined in tenuI2cMasterSdaMuxOpt */
uint8 u8ClkSpeedKHz; /*!< I2C master clock speed in KHz. */
} tstrI2cMasterInitParam;
/*!
@enum \
tenuI2cMasterFlags
@brief
Bitwise-ORed flags for use in m2m_periph_i2c_master_write and m2m_periph_i2c_master_read
@sa
m2m_periph_i2c_master_write
m2m_periph_i2c_master_read
*/
typedef enum {
I2C_MASTER_NO_FLAGS = 0x00,
/*!< No flags. */
I2C_MASTER_NO_STOP = 0x01,
/*!< No stop bit after this transaction. Useful for scattered buffer read/write operations. */
I2C_MASTER_NO_START = 0x02,
/*!< No start bit at the beginning of this transaction. Useful for scattered buffer read/write operations.*/
} tenuI2cMasterFlags;
/*!
@enum \
tenuPullupMask
@brief
Bitwise-ORed flags for use in m2m_perph_pullup_ctrl.
@sa
m2m_periph_pullup_ctrl
*/
typedef enum {
M2M_PERIPH_PULLUP_HOST_WAKEUP = (1ul << 0),
M2M_PERIPH_PULLUP_RTC_CLK = (1ul << 1),
M2M_PERIPH_PULLUP_IRQN = (1ul << 2),
M2M_PERIPH_PULLUP_GPIO_3 = (1ul << 3),
M2M_PERIPH_PULLUP_GPIO_4 = (1ul << 4),
M2M_PERIPH_PULLUP_GPIO_5 = (1ul << 5),
M2M_PERIPH_PULLUP_SD_DAT3 = (1ul << 6),
M2M_PERIPH_PULLUP_SD_DAT2_SPI_RXD = (1ul << 7),
M2M_PERIPH_PULLUP_SD_DAT1_SPI_SSN = (1ul << 8),
M2M_PERIPH_PULLUP_SD_CMD_SPI_SCK = (1ul << 9),
M2M_PERIPH_PULLUP_SD_DAT0_SPI_TXD = (1ul << 10),
M2M_PERIPH_PULLUP_GPIO_6 = (1ul << 11),
M2M_PERIPH_PULLUP_SD_CLK = (1ul << 12),
M2M_PERIPH_PULLUP_I2C_SCL = (1ul << 13),
M2M_PERIPH_PULLUP_I2C_SDA = (1ul << 14),
M2M_PERIPH_PULLUP_GPIO_11 = (1ul << 15),
M2M_PERIPH_PULLUP_GPIO_12 = (1ul << 16),
M2M_PERIPH_PULLUP_GPIO_13 = (1ul << 17),
M2M_PERIPH_PULLUP_GPIO_14 = (1ul << 18),
M2M_PERIPH_PULLUP_GPIO_15 = (1ul << 19),
M2M_PERIPH_PULLUP_GPIO_16 = (1ul << 20),
M2M_PERIPH_PULLUP_GPIO_17 = (1ul << 21),
M2M_PERIPH_PULLUP_GPIO_18 = (1ul << 22),
M2M_PERIPH_PULLUP_GPIO_19 = (1ul << 23),
M2M_PERIPH_PULLUP_GPIO_20 = (1ul << 24),
M2M_PERIPH_PULLUP_GPIO_21 = (1ul << 25),
M2M_PERIPH_PULLUP_GPIO_22 = (1ul << 26),
M2M_PERIPH_PULLUP_GPIO_23 = (1ul << 27),
M2M_PERIPH_PULLUP_GPIO_24 = (1ul << 28),
} tenuPullupMask;
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#ifdef __cplusplus
extern "C" {
#endif
/*!
@fn \
NMI_API sint8 m2m_periph_init(tstrPerphInitParam * param);
@brief
Initialize the NMC1500 peripheral driver module.
@param [in] param
Peripheral module initialization structure. See members of tstrPerphInitParam.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tstrPerphInitParam
*/
NMI_API sint8 m2m_periph_init(tstrPerphInitParam * param);
/*!
@fn \
NMI_API sint8 m2m_periph_gpio_set_dir(uint8 u8GpioNum, uint8 u8GpioDir);
@brief
Configure a specific NMC1500 pad as a GPIO and sets its direction (input or output).
@param [in] u8GpioNum
GPIO number. Allowed values are defined in tenuGpioNum.
@param [in] u8GpioDir
GPIO direction: Zero = input. Non-zero = output.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuGpioNum
*/
NMI_API sint8 m2m_periph_gpio_set_dir(uint8 u8GpioNum, uint8 u8GpioDir);
/*!
@fn \
NMI_API sint8 m2m_periph_gpio_set_val(uint8 u8GpioNum, uint8 u8GpioVal);
@brief
Set an NMC1500 GPIO output level high or low.
@param [in] u8GpioNum
GPIO number. Allowed values are defined in tenuGpioNum.
@param [in] u8GpioVal
GPIO output value. Zero = low, non-zero = high.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuGpioNum
*/
NMI_API sint8 m2m_periph_gpio_set_val(uint8 u8GpioNum, uint8 u8GpioVal);
/*!
@fn \
NMI_API sint8 m2m_periph_gpio_get_val(uint8 u8GpioNum, uint8 * pu8GpioVal);
@brief
Read an NMC1500 GPIO input level.
@param [in] u8GpioNum
GPIO number. Allowed values are defined in tenuGpioNum.
@param [out] pu8GpioVal
GPIO input value. Zero = low, non-zero = high.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuGpioNum
*/
NMI_API sint8 m2m_periph_gpio_get_val(uint8 u8GpioNum, uint8 * pu8GpioVal);
/*!
@fn \
NMI_API sint8 m2m_periph_gpio_pullup_ctrl(uint8 u8GpioNum, uint8 u8PullupEn);
@brief
Set an NMC1500 GPIO pullup resisitor enable or disable.
@param [in] u8GpioNum
GPIO number. Allowed values are defined in tenuGpioNum.
@param [in] u8PullupEn
Zero: pullup disabled. Non-zero: pullup enabled.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuGpioNum
*/
NMI_API sint8 m2m_periph_gpio_pullup_ctrl(uint8 u8GpioNum, uint8 u8PullupEn);
/*!
@fn \
NMI_API sint8 m2m_periph_i2c_master_init(tstrI2cMasterInitParam * param);
@brief
Initialize and configure the NMC1500 I2C master peripheral.
@param [in] param
I2C master initialization structure. See members of tstrI2cMasterInitParam.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tstrI2cMasterInitParam
*/
NMI_API sint8 m2m_periph_i2c_master_init(tstrI2cMasterInitParam * param);
/*!
@fn \
NMI_API sint8 m2m_periph_i2c_master_write(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint8 flags);
@brief
Write a stream of bytes to the I2C slave device.
@param [in] u8SlaveAddr
7-bit I2C slave address.
@param [in] pu8Buf
A pointer to an input buffer which contains a stream of bytes.
@param [in] u16BufLen
Input buffer length in bytes.
@param [in] flags
Write operation bitwise-ORed flags. See tenuI2cMasterFlags.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuI2cMasterFlags
*/
NMI_API sint8 m2m_periph_i2c_master_write(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint8 flags);
/*!
@fn \
NMI_API sint8 m2m_periph_i2c_master_read(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint16 * pu16ReadLen, uint8 flags);
@brief
Write a stream of bytes to the I2C slave device.
@param [in] u8SlaveAddr
7-bit I2C slave address.
@param [out] pu8Buf
A pointer to an output buffer in which a stream of bytes are received.
@param [in] u16BufLen
Max output buffer length in bytes.
@param [out] pu16ReadLen
Actual number of bytes received.
@param [in] flags
Write operation bitwise-ORed flags. See tenuI2cMasterFlags.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuI2cMasterFlags
*/
NMI_API sint8 m2m_periph_i2c_master_read(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint16 * pu16ReadLen, uint8 flags);
/*!
@fn \
NMI_API sint8 m2m_periph_pullup_ctrl(uint32 pinmask, uint8 enable);
@brief
Control the programmable pull-up resistor on the chip pads .
@param [in] pinmask
Write operation bitwise-ORed mask for which pads to control. Allowed values are defined in tenuPullupMask.
@param [in] enable
Set to 0 to disable pull-up resistor. Non-zero will enable the pull-up.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuPullupMask
*/
NMI_API sint8 m2m_periph_pullup_ctrl(uint32 pinmask, uint8 enable);
#ifdef __cplusplus
}
#endif
#endif /* _M2M_PERIPH_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,141 @@
/**
*
* \file
*
* \brief This module contains NMC1500 ASIC specific internal APIs.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _NMASIC_H_
#define _NMASIC_H_
#include "common/include/nm_common.h"
#define NMI_PERIPH_REG_BASE 0x1000
#define NMI_CHIPID (NMI_PERIPH_REG_BASE)
#define rNMI_GP_REG_0 (0x149c)
#define rNMI_GP_REG_1 (0x14A0)
#define rNMI_GLB_RESET (0x1400)
#define rNMI_BOOT_RESET_MUX (0x1118)
#define NMI_STATE_REG (0x108c)
#define BOOTROM_REG (0xc000c)
#define NMI_REV_REG (0x207ac) /*Also, Used to load ATE firmware from SPI Flash and to ensure that it is running too*/
#define M2M_WAIT_FOR_HOST_REG (0x207bc)
#define M2M_FINISH_INIT_STATE 0x02532636UL
#define M2M_FINISH_BOOT_ROM 0x10add09eUL
#define M2M_START_FIRMWARE 0xef522f61UL
#define M2M_START_PS_FIRMWARE 0x94992610UL
#define M2M_ATE_FW_START_VALUE (0x3C1CD57D) /*Also, Change this value in boot_firmware if it will be changed here*/
#define M2M_ATE_FW_IS_UP_VALUE (0xD75DC1C3) /*Also, Change this value in ATE (Burst) firmware if it will be changed here*/
#define REV_2B0 (0x2B0)
#define REV_B0 (0x2B0)
#define REV_3A0 (0x3A0)
#define GET_CHIPID() nmi_get_chipid()
#define ISNMC1000(id) (((id & 0xfffff000) == 0x100000) ? 1 : 0)
#define ISNMC1500(id) (((id & 0xfffff000) == 0x150000) ? 1 : 0)
#define REV(id) ( ((id) & 0x00000fff ) )
#define EFUSED_MAC(value) (value & 0xffff0000)
#define rHAVE_SDIO_IRQ_GPIO_BIT (NBIT0)
#define rHAVE_USE_PMU_BIT (NBIT1)
#define rHAVE_SLEEP_CLK_SRC_RTC_BIT (NBIT2)
#define rHAVE_SLEEP_CLK_SRC_XO_BIT (NBIT3)
#define rHAVE_EXT_PA_INV_TX_RX (NBIT4)
#define rHAVE_LEGACY_RF_SETTINGS (NBIT5)
#define rHAVE_LOGS_DISABLED_BIT (NBIT6)
#ifdef __cplusplus
extern "C" {
#endif
/**
* @fn nm_clkless_wake
* @brief Wakeup the chip using clockless registers
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Samer Sarhan
*/
sint8 nm_clkless_wake(void);
sint8 chip_wake(void);
void chip_idle(void);
void enable_rf_blocks(void);
sint8 enable_interrupts(void);
sint8 cpu_start(void);
uint32 nmi_get_chipid(void);
uint32 nmi_get_rfrevid(void);
void restore_pmu_settings_after_global_reset(void);
void nmi_update_pll(void);
void nmi_set_sys_clk_src_to_xo(void);
sint8 chip_reset(void);
sint8 wait_for_bootrom(uint8);
sint8 wait_for_firmware_start(uint8);
sint8 chip_deinit(void);
sint8 chip_reset_and_cpu_halt(void);
sint8 set_gpio_dir(uint8 gpio, uint8 dir);
sint8 set_gpio_val(uint8 gpio, uint8 val);
sint8 get_gpio_val(uint8 gpio, uint8* val);
sint8 pullup_ctrl(uint32 pinmask, uint8 enable);
sint8 nmi_get_otp_mac_address(uint8 *pu8MacAddr, uint8 * pu8IsValid);
sint8 nmi_get_mac_address(uint8 *pu8MacAddr);
sint8 chip_apply_conf(uint32 u32conf);
#ifdef __cplusplus
}
#endif
#endif /*_NMASIC_H_*/

View File

@ -0,0 +1,139 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus APIs implementation.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _NMBUS_H_
#define _NMBUS_H_
#include "common/include/nm_common.h"
#include "bus_wrapper/include/nm_bus_wrapper.h"
#ifdef __cplusplus
extern "C"{
#endif
/**
* @fn nm_bus_iface_init
* @brief Initialize bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_bus_iface_init(void *);
/**
* @fn nm_bus_iface_deinit
* @brief Deinitialize bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_bus_iface_deinit(void);
/**
* @fn nm_bus_iface_reconfigure
* @brief reconfigure bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_bus_iface_reconfigure(void *ptr);
/**
* @fn nm_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
*/
uint32 nm_read_reg(uint32 u32Addr);
/**
* @fn nm_read_reg_with_ret
* @brief Read register with error code return
* @param [in] u32Addr
* Register address
* @param [out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_read_reg_with_ret(uint32 u32Addr, uint32* pu32RetVal);
/**
* @fn nm_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_write_reg(uint32 u32Addr, uint32 u32Val);
/**
* @fn nm_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u32Sz
* Number of bytes to read. The buffer size must be >= u32Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_read_block(uint32 u32Addr, uint8 *puBuf, uint32 u32Sz);
/**
* @fn nm_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u32Sz
* Number of bytes to write. The buffer size must be >= u32Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_write_block(uint32 u32Addr, uint8 *puBuf, uint32 u32Sz);
#ifdef __cplusplus
}
#endif
#endif /* _NMBUS_H_ */

View File

@ -0,0 +1,109 @@
/**
*
* \file
*
* \brief This module contains NMC1500 M2M driver APIs declarations.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _NMDRV_H_
#define _NMDRV_H_
#include "common/include/nm_common.h"
/**
* @struct tstrM2mWifiGetRevision
* @brief Structure holding firmware version parameters
* @sa M2M_WIFI_AUTH_WEB, M2M_WIFI_AUTH_WPA, M2M_WIFI_AUTH_WPA2
*/
typedef struct {
uint8 u8FirmwareMajor; /* Version Major Number which represents the official release base */
uint8 u8FirmwareMinor; /* Version Minor Number which represents the engineering release base */
uint8 u8FirmwarePatch; /* Version pathc Number which represents the pathces release base */
uint8 u8DriverMajor; /* Version Major Number which represents the official release base */
uint8 u8DriverMinor; /* Version Minor Number which represents the engineering release base */
uint8 u8DriverPatch; /* Version Patch Number which represents the pathces release base */
uint8 BuildDate[sizeof(__DATE__)];
uint8 BuildTime[sizeof(__TIME__)];
uint32 u32Chipid; /* HW revision which will be basically the chip ID */
} tstrM2mRev;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @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
* @version 1.0
*/
sint8 nm_get_firmware_info(tstrM2mRev* M2mRev);
/*
* @fn nm_drv_init
* @brief Initialize NMC1000 driver
* @return ZERO in case of success and Negative error code in case of failure
*/
sint8 nm_drv_init_download_mode(void);
/*
* @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 TBD
* @return ZERO in case of success and Negative error code in case of failure
*/
sint8 nm_drv_init(void * arg);
/**
* @fn nm_drv_deinit
* @brief Deinitialize NMC1000 driver
* @author M. Abdelmawla
* @param [in] arg
* Generic argument TBD
* @return ZERO in case of success and Negative error code in case of failure
*/
sint8 nm_drv_deinit(void * arg);
#ifdef __cplusplus
}
#endif
#endif /*_NMDRV_H_*/

View File

@ -0,0 +1,104 @@
/**
*
* \file
*
* \brief This module contains NMC1000 I2C protocol bus APIs implementation.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _NMI2C_H_
#define _NMI2C_H_
#include "common/include/nm_common.h"
/**
* @fn nm_i2c_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
*/
uint32 nm_i2c_read_reg(uint32 u32Addr);
/**
* @fn nm_i2c_read_reg_with_ret
* @brief Read register with error code return
* @param [in] u32Addr
* Register address
* @param [out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_i2c_read_reg_with_ret(uint32 u32Addr, uint32* pu32RetVal);
/**
* @fn nm_i2c_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_i2c_write_reg(uint32 u32Addr, uint32 u32Val);
/**
* @fn nm_i2c_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u16Sz
* Number of bytes to read. The buffer size must be >= u16Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_i2c_read_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz);
/**
* @fn nm_i2c_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u16Sz
* Number of bytes to write. The buffer size must be >= u16Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_i2c_write_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz);
#endif /* _NMI2C_H_ */

View File

@ -0,0 +1,126 @@
/**
*
* \file
*
* \brief This module contains NMC1000 SPI protocol bus APIs implementation.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _NMSPI_H_
#define _NMSPI_H_
#include "common/include/nm_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @fn nm_spi_init
* @brief Initialize the SPI
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_init(void);
/**
* @fn nm_spi_deinit
* @brief DeInitialize the SPI
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_deinit(void);
/**
* @fn nm_spi_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
*/
uint32 nm_spi_read_reg(uint32 u32Addr);
/**
* @fn nm_spi_read_reg_with_ret
* @brief Read register with error code return
* @param [in] u32Addr
* Register address
* @param [out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_read_reg_with_ret(uint32 u32Addr, uint32* pu32RetVal);
/**
* @fn nm_spi_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_write_reg(uint32 u32Addr, uint32 u32Val);
/**
* @fn nm_spi_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u16Sz
* Number of bytes to read. The buffer size must be >= u16Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_read_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz);
/**
* @fn nm_spi_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u16Sz
* Number of bytes to write. The buffer size must be >= u16Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_write_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz);
#ifdef __cplusplus
}
#endif
#endif /* _NMSPI_H_ */

View File

@ -0,0 +1,118 @@
/**
*
* \file
*
* \brief This module contains NMC1000 UART protocol bus APIs implementation.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _NMUART_H_
#define _NMUART_H_
#include "common/include/nm_common.h"
/*
* @fn nm_uart_sync_cmd
* @brief Check COM Port
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_uart_sync_cmd(void);
/**
* @fn nm_uart_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
*/
uint32 nm_uart_read_reg(uint32 u32Addr);
/**
* @fn nm_uart_read_reg_with_ret
* @brief Read register with error code return
* @param [in] u32Addr
* Register address
* @param [out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_uart_read_reg_with_ret(uint32 u32Addr, uint32* pu32RetVal);
/**
* @fn nm_uart_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_uart_write_reg(uint32 u32Addr, uint32 u32Val);
/**
* @fn nm_uart_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u16Sz
* Number of bytes to read. The buffer size must be >= u16Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_uart_read_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz);
/**
* @fn nm_uart_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u16Sz
* Number of bytes to write. The buffer size must be >= u16Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_uart_write_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz);
/**
* @fn nm_uart_reconfigure
* @brief Reconfigures the UART interface
* @param [in] ptr
* Pointer to a DWORD containing baudrate at this moment.
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_uart_reconfigure(void *ptr);
#endif /* _NMI2C_H_ */

View File

@ -0,0 +1,412 @@
/**
*
* \file
*
* \brief BSD alike socket interface internal types.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef __M2M_SOCKET_HOST_IF_H__
#define __M2M_SOCKET_HOST_IF_H__
#ifdef __cplusplus
extern "C" {
#endif
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#ifndef _BOOT_
#ifndef _FIRMWARE_
#include "socket/include/socket.h"
#else
#include "m2m_types.h"
#endif
#endif
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#ifdef _FIRMWARE_
#define HOSTNAME_MAX_SIZE (64)
#endif
#define SSL_MAX_OPT_LEN HOSTNAME_MAX_SIZE
#define SOCKET_CMD_INVALID 0x00
/*!<
Invlaid Socket command value.
*/
#define SOCKET_CMD_BIND 0x41
/*!<
Socket Binding command value.
*/
#define SOCKET_CMD_LISTEN 0x42
/*!<
Socket Listening command value.
*/
#define SOCKET_CMD_ACCEPT 0x43
/*!<
Socket Accepting command value.
*/
#define SOCKET_CMD_CONNECT 0x44
/*!<
Socket Connecting command value.
*/
#define SOCKET_CMD_SEND 0x45
/*!<
Socket send command value.
*/
#define SOCKET_CMD_RECV 0x46
/*!<
Socket Recieve command value.
*/
#define SOCKET_CMD_SENDTO 0x47
/*!<
Socket sendTo command value.
*/
#define SOCKET_CMD_RECVFROM 0x48
/*!<
Socket RecieveFrom command value.
*/
#define SOCKET_CMD_CLOSE 0x49
/*!<
Socket Close command value.
*/
#define SOCKET_CMD_DNS_RESOLVE 0x4A
/*!<
Socket DNS Resolve command value.
*/
#define SOCKET_CMD_SSL_CONNECT 0x4B
/*!<
SSL-Socket Connect command value.
*/
#define SOCKET_CMD_SSL_SEND 0x4C
/*!<
SSL-Socket Send command value.
*/
#define SOCKET_CMD_SSL_RECV 0x4D
/*!<
SSL-Socket Recieve command value.
*/
#define SOCKET_CMD_SSL_CLOSE 0x4E
/*!<
SSL-Socket Close command value.
*/
#define SOCKET_CMD_SET_SOCKET_OPTION 0x4F
/*!<
Set Socket Option command value.
*/
#define SOCKET_CMD_SSL_CREATE 0x50
/*!<
*/
#define SOCKET_CMD_SSL_SET_SOCK_OPT 0x51
#define SOCKET_CMD_PING 0x52
#define PING_ERR_SUCCESS 0
#define PING_ERR_DEST_UNREACH 1
#define PING_ERR_TIMEOUT 2
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
* @brief
*/
typedef struct{
uint16 u16Family;
uint16 u16Port;
uint32 u32IPAddr;
}tstrSockAddr;
typedef sint8 SOCKET;
typedef tstrSockAddr tstrUIPSockAddr;
/*!
@struct \
tstrDnsReply
@brief
DNS Reply, contains hostName and HostIP.
*/
typedef struct{
char acHostName[HOSTNAME_MAX_SIZE];
uint32 u32HostIP;
}tstrDnsReply;
/*!
@brief
*/
typedef struct{
tstrSockAddr strAddr;
SOCKET sock;
uint8 u8Void;
uint16 u16SessionID;
}tstrBindCmd;
/*!
@brief
*/
typedef struct{
SOCKET sock;
sint8 s8Status;
uint16 u16SessionID;
}tstrBindReply;
/*!
* @brief
*/
typedef struct{
SOCKET sock;
uint8 u8BackLog;
uint16 u16SessionID;
}tstrListenCmd;
/*!
@struct \
tstrSocketRecvMsg
@brief Socket recv status.
It is passed to the APPSocketEventHandler with SOCKET_MSG_RECV or SOCKET_MSG_RECVFROM message type
in a response to a user call to the recv or recvfrom.
If the received data from the remote peer is larger than the USER Buffer size (given at recv call), the data is
delivered to the user in a number of consecutive chunks according to the USER Buffer size.
*/
typedef struct{
SOCKET sock;
sint8 s8Status;
uint16 u16SessionID;
}tstrListenReply;
/*!
* @brief
*/
typedef struct{
tstrSockAddr strAddr;
SOCKET sListenSock;
SOCKET sConnectedSock;
uint16 u16Void;
}tstrAcceptReply;
/*!
* @brief
*/
typedef struct{
tstrSockAddr strAddr;
SOCKET sock;
uint8 u8SslFlags;
uint16 u16SessionID;
}tstrConnectCmd;
/*!
@struct \
tstrConnectReply
@brief
Connect Reply, contains sock number and error value
*/
typedef struct{
SOCKET sock;
sint8 s8Error;
uint16 u16SessionID;
}tstrConnectReply;
/*!
@brief
*/
typedef struct{
SOCKET sock;
uint8 u8Void;
uint16 u16DataSize;
tstrSockAddr strAddr;
uint16 u16SessionID;
uint16 u16Void;
}tstrSendCmd;
/*!
@struct \
tstrSendReply
@brief
Send Reply, contains socket number and number of sent bytes.
*/
typedef struct{
SOCKET sock;
uint8 u8Void;
sint16 s16SentBytes;
uint16 u16SessionID;
uint16 u16Void;
}tstrSendReply;
/*!
* @brief
*/
typedef struct{
uint32 u32Timeoutmsec;
SOCKET sock;
uint8 u8Void;
uint16 u16SessionID;
}tstrRecvCmd;
/*!
@struct
@brief
*/
typedef struct{
tstrSockAddr strRemoteAddr;
sint16 s16RecvStatus;
uint16 u16DataOffset;
SOCKET sock;
uint8 u8Void;
uint16 u16SessionID;
}tstrRecvReply;
/*!
* @brief
*/
typedef struct{
uint32 u32OptionValue;
SOCKET sock;
uint8 u8Option;
uint16 u16SessionID;
}tstrSetSocketOptCmd;
typedef struct{
SOCKET sslSock;
uint8 __PAD24__[3];
}tstrSSLSocketCreateCmd;
/*!
* @brief
*/
typedef struct{
SOCKET sock;
uint8 u8Option;
uint16 u16SessionID;
uint32 u32OptLen;
uint8 au8OptVal[SSL_MAX_OPT_LEN];
}tstrSSLSetSockOptCmd;
/*!
*/
typedef struct{
uint32 u32DestIPAddr;
uint32 u32CmdPrivate;
uint16 u16PingCount;
uint8 u8TTL;
uint8 __PAD8__;
}tstrPingCmd;
typedef struct{
uint32 u32IPAddr;
uint32 u32CmdPrivate;
uint32 u32RTT;
uint16 u16Success;
uint16 u16Fail;
uint8 u8ErrorCode;
uint8 __PAD24__[3];
}tstrPingReply;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __M2M_SOCKET_HOST_IF_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
/**
*
* \file
*
* \brief BSD alike socket interface internal types.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef __SOCKET_INTERNAL_H__
#define __SOCKET_INTERNAL_H__
#ifdef __cplusplus
extern "C" {
#endif
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "socket/include/socket.h"
#include "socket/include/m2m_socket_host_if.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
NMI_API void Socket_ReadSocketData(SOCKET sock, tstrSocketRecvMsg *pstrRecv,uint8 u8SocketMsg,
uint32 u32StartAddress,uint16 u16ReadCount);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __SOCKET_H__ */

320
src/winc1500/m2m_ota.c Normal file
View File

@ -0,0 +1,320 @@
/**
*
* \file
*
* \brief NMC1500 IoT OTA Interface.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "common/include/nm_common.h"
#include "driver/include/m2m_types.h"
#include "driver/include/m2m_ota.h"
#include "driver/source/m2m_hif.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
static tpfOtaUpdateCb gpfOtaUpdateCb = NULL;
static tpfOtaNotifCb gpfOtaNotifCb = NULL;
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/**
* @fn m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr, uint8 grp)
* @brief WiFi call back function
* @param [in] u8OpCode
* HIF Opcode type.
* @param [in] u16DataSize
* HIF data length.
* @param [in] u32Addr
* HIF address.
* @param [in] grp
* HIF group type.
* @author
* @date
* @version 1.0
*/
static void m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
{
sint8 ret = M2M_SUCCESS;
if(u8OpCode == M2M_OTA_RESP_NOTIF_UPDATE_INFO)
{
tstrOtaUpdateInfo strOtaUpdateInfo;
m2m_memset((uint8*)&strOtaUpdateInfo,0,sizeof(tstrOtaUpdateInfo));
ret = hif_receive(u32Addr,(uint8*)&strOtaUpdateInfo,sizeof(tstrOtaUpdateInfo),0);
if(ret == M2M_SUCCESS)
{
if(gpfOtaNotifCb)
gpfOtaNotifCb(&strOtaUpdateInfo);
}
}
else if (u8OpCode == M2M_OTA_RESP_UPDATE_STATUS)
{
tstrOtaUpdateStatusResp strOtaUpdateStatusResp;
m2m_memset((uint8*)&strOtaUpdateStatusResp,0,sizeof(tstrOtaUpdateStatusResp));
ret = hif_receive(u32Addr, (uint8*) &strOtaUpdateStatusResp,sizeof(tstrOtaUpdateStatusResp), 0);
if(ret == M2M_SUCCESS)
{
if(gpfOtaUpdateCb)
gpfOtaUpdateCb(strOtaUpdateStatusResp.u8OtaUpdateStatusType,strOtaUpdateStatusResp.u8OtaUpdateStatus);
}
}
else
{
M2M_ERR("Invaild OTA resp %d ?\n",u8OpCode);
}
}
/*!
@fn \
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb);
@brief
Initialize the OTA layer.
@param [in] pfOtaUpdateCb
OTA Update callback function
@param [in] pfOtaNotifCb
OTA notify callback function
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb)
{
sint8 ret = M2M_SUCCESS;
if(pfOtaUpdateCb){
gpfOtaUpdateCb = pfOtaUpdateCb;
}else{
M2M_ERR("Invaild Ota update cb\n");
}
if(pfOtaNotifCb){
gpfOtaNotifCb = pfOtaNotifCb;
}else{
M2M_ERR("Invaild Ota notify cb\n");
}
hif_register_cb(M2M_REQ_GRP_OTA,m2m_ota_cb);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url);
@brief
Set the OTA url
@param [in] u8Url
The url server address
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url)
{
sint8 ret = M2M_SUCCESS;
uint16 u16UrlSize = m2m_strlen(u8Url) + 1;
/*Todo: we may change it to data pkt but we need to give it higer priority
but the priorty is not implemnted yet in data pkt
*/
ret = hif_send(M2M_REQ_GRP_OTA,M2M_OTA_REQ_START_UPDATE,u8Url,u16UrlSize,NULL,0,0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_notif_check_for_update(void);
@brief
check for ota update
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_check_for_update(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GRP_OTA,M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE,NULL,0,NULL,0,0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
@brief
Schedule OTA update
@param [in] u32Period
Period in days
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GRP_OTA,M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE,NULL,0,NULL,0,0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_start_update(uint8 * u8DownloadUrl);
@brief
Request OTA start update using the downloaded url
@param [in] u8DownloadUrl
The download firmware url, you get it from device info
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_start_update(uint8 * u8DownloadUrl)
{
sint8 ret = M2M_SUCCESS;
uint16 u16DurlSize = m2m_strlen(u8DownloadUrl) + 1;
/*Todo: we may change it to data pkt but we need to give it higer priority
but the priorty is not implemnted yet in data pkt
*/
ret = hif_send(M2M_REQ_GRP_OTA,M2M_OTA_REQ_START_UPDATE,u8DownloadUrl,u16DurlSize,NULL,0,0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_rollback(void);
@brief
Request OTA Rollback image
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_rollback(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GRP_OTA,M2M_OTA_REQ_ROLLBACK,NULL,0,NULL,0,0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_switch_firmware(void);
@brief
Switch to the upgraded Firmware
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_switch_firmware(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GRP_OTA,M2M_OTA_REQ_SWITCH_FIRMWARE,NULL,0,NULL,0,0);
return ret;
}
#if 0
#define M2M_OTA_FILE "../../../m2m_ota.dat"
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_GRP_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;
}
#endif

View File

@ -0,0 +1,778 @@
/**
*
* \file
*
* \brief NMC1500 Peripherials Application Interface.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifdef _M2M_ATE_FW_
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "driver/include/m2m_ate_mode.h"
#include "driver/include/nmasic.h"
#include "driver/include/nmdrv.h"
#include "driver/include/m2m_hif.h"
#include "driver/include/nmbus.h"
#include "bsp/include/nm_bsp.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#define rInterrupt_CORTUS_0 (0x10a8)
#define rInterrupt_CORTUS_1 (0x10ac)
#define rInterrupt_CORTUS_2 (0x10b0)
#define rBurstTx_NMI_TX_RATE (0x161d00)
#define rBurstTx_NMI_NUM_TX_FRAMES (0x161d04)
#define rBurstTx_NMI_TX_FRAME_LEN (0x161d08)
#define rBurstTx_NMI_TX_CW_PARAM (0x161d0c)
#define rBurstTx_NMI_TX_GAIN (0x161d10)
#define rBurstTx_NMI_TX_DPD_CTRL (0x161d14)
#define rBurstTx_NMI_USE_PMU (0x161d18)
#define rBurstTx_NMI_TEST_CH (0x161d1c)
#define rBurstTx_NMI_TX_PHY_CONT (0x161d20)
#define rBurstTx_NMI_TX_CW_MODE (0x161d24)
#define rBurstTx_NMI_TEST_XO_OFF (0x161d28)
#define rBurstTx_NMI_USE_EFUSE_XO_OFF (0x161d2c)
#define rBurstTx_NMI_MAC_FILTER_ENABLE_DA (0x161d30)
#define rBurstTx_NMI_MAC_ADDR_LO_PEER (0x161d34)
#define rBurstTx_NMI_MAC_ADDR_LO_SELF (0x161d38)
#define rBurstTx_NMI_MAC_ADDR_HI_PEER (0x161d3c)
#define rBurstTx_NMI_MAC_ADDR_HI_SELF (0x161d40)
#define rBurstTx_NMI_RX_PKT_CNT_SUCCESS (0x161d44)
#define rBurstTx_NMI_RX_PKT_CNT_FAIL (0x161d48)
#define rBurstTx_NMI_SET_SELF_MAC_ADDR (0x161d4c)
#define rBurstTx_NMI_MAC_ADDR_LO_SA (0x161d50)
#define rBurstTx_NMI_MAC_ADDR_HI_SA (0x161d54)
#define rBurstTx_NMI_MAC_FILTER_ENABLE_SA (0x161d58)
#define rBurstRx_NMI_RX_ALL_PKTS_CONT (0x9898)
#define rBurstRx_NMI_RX_ERR_PKTS_CONT (0x988c)
#define TX_DGAIN_MAX_NUM_REGS (4)
#define TX_DGAIN_REG_BASE_ADDRESS (0x1240)
#define TX_GAIN_CODE_MAX_NUM_REGS (3)
#define TX_GAIN_CODE_BASE_ADDRESS (0x1250)
#define TX_PA_MAX_NUM_REGS (3)
#define TX_PA_BASE_ADDRESS (0x1e58)
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
VARIABLES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
volatile static uint8 gu8AteIsRunning = 0; /*!< ATE firmware status, 1 means ATE is running otherwise stopped */
volatile static uint8 gu8RxState = 0; /*!< RX status, 1 means Rx is running otherwise stopped */
volatile static uint8 gu8TxState = 0; /*!< TX status, 1 means Tx is running otherwise stopped */
volatile static uint32 gaAteFwTxRates[M2M_ATE_MAX_NUM_OF_RATES] =
{
0x01, 0x02, 0x05, 0x0B, /*B-Rats*/
0x06, 0x09, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x36, /*G-Rats*/
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87 /*N-Rats*/
};
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
STATIC FUNCTIONS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
static void m2m_ate_set_rx_status(uint8 u8Value)
{
gu8RxState = u8Value;
}
static void m2m_ate_set_tx_status(uint8 u8Value)
{
gu8TxState = u8Value;
}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION IMPLEMENTATION
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
@fn \
sint8 m2m_ate_init(void);
@brief
This function used to download ATE firmware from flash and start it
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_init(void)
{
sint8 s8Ret = M2M_SUCCESS;
uint8 u8WifiMode = M2M_WIFI_MODE_CONFIG;
s8Ret = nm_drv_init(&u8WifiMode);
return s8Ret;
}
/*!
@fn \
sint8 m2m_ate_deinit(void);
@brief
De-Initialization of ATE firmware mode
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_deinit(void)
{
return nm_drv_deinit(NULL);
}
/*!
@fn \
sint8 m2m_ate_set_fw_state(uint8);
@brief
This function used to change ATE firmware status from running to stopped or vice versa.
@param [in] u8State
Required state of ATE firmware, one of \ref tenuM2mAteFwState enumeration values.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init
*/
sint8 m2m_ate_set_fw_state(uint8 u8State)
{
sint8 s8Ret = M2M_SUCCESS;
uint32_t u32Val = 0;
if((M2M_ATE_FW_STATE_STOP == u8State) && (M2M_ATE_FW_STATE_STOP != gu8AteIsRunning))
{
u32Val = nm_read_reg(rNMI_GLB_RESET);
u32Val &= ~(1 << 10);
s8Ret = nm_write_reg(rNMI_GLB_RESET, u32Val);
gu8AteIsRunning = M2M_ATE_FW_STATE_STOP;
}
else if((M2M_ATE_FW_STATE_RUN == u8State) && (M2M_ATE_FW_STATE_RUN != gu8AteIsRunning))
{
/* 0x1118[0]=0 at power-on-reset: pad-based control. */
/* Switch cortus reset register to register control. 0x1118[0]=1. */
u32Val = nm_read_reg(rNMI_BOOT_RESET_MUX);
u32Val |= (1 << 0);
s8Ret = nm_write_reg(rNMI_BOOT_RESET_MUX, u32Val);
if(M2M_SUCCESS != s8Ret)
{
goto __EXIT;
}
/**
Write the firmware download complete magic value 0x10ADD09E at
location 0xFFFF000C (Cortus map) or C000C (AHB map).
This will let the boot-rom code execute from RAM.
**/
s8Ret = nm_write_reg(0xc0000, 0x71);
if(M2M_SUCCESS != s8Ret)
{
goto __EXIT;
}
u32Val = nm_read_reg(rNMI_GLB_RESET);
if((u32Val & (1ul << 10)) == (1ul << 10))
{
u32Val &= ~(1ul << 10);
s8Ret = nm_write_reg(rNMI_GLB_RESET, u32Val);
if(M2M_SUCCESS != s8Ret)
{
goto __EXIT;
}
}
u32Val |= (1ul << 10);
s8Ret = nm_write_reg(rNMI_GLB_RESET, u32Val);
if(M2M_SUCCESS != s8Ret)
{
goto __EXIT;
}
gu8AteIsRunning = M2M_ATE_FW_STATE_RUN;
}
else
{
s8Ret = M2M_ATE_ERR_UNHANDLED_CASE;
}
__EXIT:
if((M2M_SUCCESS == s8Ret) && (M2M_ATE_FW_STATE_RUN == gu8AteIsRunning))
{
nm_bsp_sleep(500); /*wait for ATE firmware start up*/
}
return s8Ret;
}
/*!
@fn \
sint8 m2m_ate_get_fw_state(uint8);
@brief
This function used to return status of ATE firmware.
@return
The function SHALL return status of ATE firmware, one of \ref tenuM2mAteFwState enumeration values.
\sa
m2m_ate_init, m2m_ate_set_fw_state
*/
sint8 m2m_ate_get_fw_state(void)
{
return gu8AteIsRunning;
}
/*!
@fn \
uint32 m2m_ate_get_tx_rate(uint8);
@brief
This function used to return value of TX rate required by application developer.
@param [in] u8Index
Index of required rate , one of \ref tenuM2mAteTxIndexOfRates enumeration values.
@return
The function SHALL return 0 for in case of failure otherwise selected rate value.
\sa
tenuM2mAteTxIndexOfRates
*/
uint32 m2m_ate_get_tx_rate(uint8 u8Index)
{
if(M2M_ATE_MAX_NUM_OF_RATES <= u8Index)
{
return 0;
}
return gaAteFwTxRates[u8Index];
}
/*!
@fn \
sint8 m2m_ate_get_tx_status(void);
@brief
This function used to return status of TX test case either running or stopped.
@return
The function SHALL return status of ATE firmware, 1 if TX is running otherwise 0.
\sa
m2m_ate_start_tx, m2m_ate_stop_tx
*/
sint8 m2m_ate_get_tx_status(void)
{
return gu8TxState;
}
/*!
@fn \
sint8 m2m_ate_start_tx(tstrM2mAteTx *)
@brief
This function used to start TX test case.
@param [in] strM2mAteTx
Type of \ref tstrM2mAteTx, with the values required to enable TX test case. You must use \ref m2m_ate_init first.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_stop_tx, m2m_ate_get_tx_status
*/
sint8 m2m_ate_start_tx(tstrM2mAteTx * strM2mAteTx)
{
sint8 s8Ret = M2M_SUCCESS;
uint8 u8LoopCntr = 0;
uint32_t val32;
if(NULL == strM2mAteTx)
{
s8Ret = M2M_ATE_ERR_VALIDATE;
goto __EXIT;
}
if(0 != m2m_ate_get_tx_status())
{
s8Ret = M2M_ATE_ERR_TX_ALREADY_RUNNING;
goto __EXIT;
}
if(0 != m2m_ate_get_rx_status())
{
s8Ret = M2M_ATE_ERR_RX_ALREADY_RUNNING;
goto __EXIT;
}
if( (strM2mAteTx->channel_num < M2M_ATE_CHANNEL_1) ||
(strM2mAteTx->channel_num > M2M_ATE_CHANNEL_14) ||
(strM2mAteTx->tx_gain_sel < M2M_ATE_TX_GAIN_DYNAMIC) ||
(strM2mAteTx->tx_gain_sel > M2M_ATE_TX_GAIN_TELEC) ||
(strM2mAteTx->frame_len > M2M_ATE_MAX_FRAME_LENGTH) ||
(strM2mAteTx->frame_len < M2M_ATE_MIN_FRAME_LENGTH)
)
{
s8Ret = M2M_ATE_ERR_VALIDATE;
goto __EXIT;
}
if( (strM2mAteTx->duty_cycle < M2M_ATE_TX_DUTY_MAX_VALUE /*1*/) ||
(strM2mAteTx->duty_cycle > M2M_ATE_TX_DUTY_MIN_VALUE /*10*/ ) ||
(strM2mAteTx->dpd_ctrl < M2M_ATE_TX_DPD_DYNAMIC) ||
(strM2mAteTx->dpd_ctrl > M2M_ATE_TX_DPD_ENABLED) ||
(strM2mAteTx->use_pmu < M2M_ATE_PMU_DISBLE) ||
(strM2mAteTx->use_pmu > M2M_ATE_PMU_ENABLE) ||
(strM2mAteTx->phy_burst_tx < M2M_ATE_TX_SRC_MAC) ||
(strM2mAteTx->phy_burst_tx > M2M_ATE_TX_SRC_PHY) ||
(strM2mAteTx->cw_tx < M2M_ATE_TX_MODE_NORM) ||
(strM2mAteTx->cw_tx > M2M_ATE_TX_MODE_CW)
)
{
s8Ret = M2M_ATE_ERR_VALIDATE;
goto __EXIT;
}
for(u8LoopCntr=0; u8LoopCntr<M2M_ATE_MAX_NUM_OF_RATES; u8LoopCntr++)
{
if(gaAteFwTxRates[u8LoopCntr] == strM2mAteTx->data_rate)
{
break;
}
}
if(M2M_ATE_MAX_NUM_OF_RATES == u8LoopCntr)
{
s8Ret = M2M_ATE_ERR_VALIDATE;
goto __EXIT;
}
s8Ret += nm_write_reg(rBurstTx_NMI_USE_PMU, strM2mAteTx->use_pmu);
s8Ret += nm_write_reg(rBurstTx_NMI_TX_PHY_CONT, strM2mAteTx->phy_burst_tx);
s8Ret += nm_write_reg(rBurstTx_NMI_NUM_TX_FRAMES, strM2mAteTx->num_frames);
s8Ret += nm_write_reg(rBurstTx_NMI_TX_GAIN, strM2mAteTx->tx_gain_sel);
s8Ret += nm_write_reg(rBurstTx_NMI_TEST_CH, strM2mAteTx->channel_num);
s8Ret += nm_write_reg(rBurstTx_NMI_TX_FRAME_LEN, strM2mAteTx->frame_len);
s8Ret += nm_write_reg(rBurstTx_NMI_TX_CW_PARAM, strM2mAteTx->duty_cycle);
s8Ret += nm_write_reg(rBurstTx_NMI_TX_DPD_CTRL, strM2mAteTx->dpd_ctrl);
s8Ret += nm_write_reg(rBurstTx_NMI_TX_RATE, strM2mAteTx->data_rate);
s8Ret += nm_write_reg(rBurstTx_NMI_TX_CW_MODE, strM2mAteTx->cw_tx);
s8Ret += nm_write_reg(rBurstTx_NMI_TEST_XO_OFF, strM2mAteTx->xo_offset_x1000);
s8Ret += nm_write_reg(rBurstTx_NMI_USE_EFUSE_XO_OFF, strM2mAteTx->use_efuse_xo_offset);
val32 = strM2mAteTx->peer_mac_addr[5] << 0;
val32 |= strM2mAteTx->peer_mac_addr[4] << 8;
val32 |= strM2mAteTx->peer_mac_addr[3] << 16;
nm_write_reg(rBurstTx_NMI_MAC_ADDR_LO_PEER, val32 );
val32 = strM2mAteTx->peer_mac_addr[2] << 0;
val32 |= strM2mAteTx->peer_mac_addr[1] << 8;
val32 |= strM2mAteTx->peer_mac_addr[0] << 16;
nm_write_reg(rBurstTx_NMI_MAC_ADDR_HI_PEER, val32 );
if(M2M_SUCCESS == s8Ret)
{
s8Ret += nm_write_reg(rInterrupt_CORTUS_0, 1); /*Interrupt Cortus*/
m2m_ate_set_tx_status(1);
nm_bsp_sleep(200); /*Recommended*/
}
__EXIT:
return s8Ret;
}
/*!
@fn \
sint8 m2m_ate_stop_tx(void)
@brief
This function used to stop TX test case.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_start_tx, m2m_ate_get_tx_status
*/
sint8 m2m_ate_stop_tx(void)
{
sint8 s8Ret = M2M_SUCCESS;
s8Ret = nm_write_reg(rInterrupt_CORTUS_1, 1);
if(M2M_SUCCESS == s8Ret)
{
m2m_ate_set_tx_status(0);
}
return s8Ret;
}
/*!
@fn \
sint8 m2m_ate_get_rx_status(uint8);
@brief
This function used to return status of RX test case either running or stopped.
@return
The function SHALL return status of ATE firmware, 1 if RX is running otherwise 0.
\sa
m2m_ate_start_rx, m2m_ate_stop_rx
*/
sint8 m2m_ate_get_rx_status(void)
{
return gu8RxState;
}
/*!
@fn \
sint8 m2m_ate_start_rx(tstrM2mAteRx *)
@brief
This function used to start RX test case.
@param [in] strM2mAteRx
Type of \ref tstrM2mAteRx, with the values required to enable RX test case. You must use \ref m2m_ate_init first.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_stop_rx, m2m_ate_get_rx_status
*/
sint8 m2m_ate_start_rx(tstrM2mAteRx * strM2mAteRxStr)
{
sint8 s8Ret = M2M_SUCCESS;
uint32 val32;
if(NULL == strM2mAteRxStr)
{
s8Ret = M2M_ATE_ERR_VALIDATE;
goto __EXIT;
}
if(0 != m2m_ate_get_tx_status())
{
s8Ret = M2M_ATE_ERR_TX_ALREADY_RUNNING;
goto __EXIT;
}
if(0 != m2m_ate_get_rx_status())
{
s8Ret = M2M_ATE_ERR_RX_ALREADY_RUNNING;
goto __EXIT;
}
if( (strM2mAteRxStr->channel_num < M2M_ATE_CHANNEL_1) ||
(strM2mAteRxStr->channel_num > M2M_ATE_CHANNEL_14)||
(strM2mAteRxStr->use_pmu < M2M_ATE_PMU_DISBLE) ||
(strM2mAteRxStr->use_pmu > M2M_ATE_PMU_ENABLE)
)
{
s8Ret = M2M_ATE_ERR_VALIDATE;
goto __EXIT;
}
s8Ret += nm_write_reg(rBurstTx_NMI_TEST_CH, strM2mAteRxStr->channel_num);
s8Ret += nm_write_reg(rBurstTx_NMI_USE_PMU, strM2mAteRxStr->use_pmu);
s8Ret += nm_write_reg(rBurstTx_NMI_TEST_XO_OFF, strM2mAteRxStr->xo_offset_x1000);
s8Ret += nm_write_reg(rBurstTx_NMI_USE_EFUSE_XO_OFF, strM2mAteRxStr->use_efuse_xo_offset);
if(strM2mAteRxStr->override_self_mac_addr)
{
val32 = strM2mAteRxStr->self_mac_addr[5] << 0;
val32 |= strM2mAteRxStr->self_mac_addr[4] << 8;
val32 |= strM2mAteRxStr->self_mac_addr[3] << 16;
nm_write_reg(rBurstTx_NMI_MAC_ADDR_LO_SELF, val32 );
val32 = strM2mAteRxStr->self_mac_addr[2] << 0;
val32 |= strM2mAteRxStr->self_mac_addr[1] << 8;
val32 |= strM2mAteRxStr->self_mac_addr[0] << 16;
nm_write_reg(rBurstTx_NMI_MAC_ADDR_HI_SELF, val32 );
}
if(strM2mAteRxStr->mac_filter_en_sa)
{
val32 = strM2mAteRxStr->peer_mac_addr[5] << 0;
val32 |= strM2mAteRxStr->peer_mac_addr[4] << 8;
val32 |= strM2mAteRxStr->peer_mac_addr[3] << 16;
nm_write_reg(rBurstTx_NMI_MAC_ADDR_LO_SA, val32 );
val32 = strM2mAteRxStr->peer_mac_addr[2] << 0;
val32 |= strM2mAteRxStr->peer_mac_addr[1] << 8;
val32 |= strM2mAteRxStr->peer_mac_addr[0] << 16;
nm_write_reg(rBurstTx_NMI_MAC_ADDR_HI_SA, val32 );
}
nm_write_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_DA, strM2mAteRxStr->mac_filter_en_da);
nm_write_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_SA, strM2mAteRxStr->mac_filter_en_sa);
nm_write_reg(rBurstTx_NMI_SET_SELF_MAC_ADDR, strM2mAteRxStr->override_self_mac_addr);
if(M2M_SUCCESS == s8Ret)
{
s8Ret += nm_write_reg(rInterrupt_CORTUS_2, 1); /*Interrupt Cortus*/
m2m_ate_set_rx_status(1);
nm_bsp_sleep(10); /*Recommended*/
}
__EXIT:
return s8Ret;
}
/*!
@fn \
sint8 m2m_ate_stop_rx(void)
@brief
This function used to stop RX test case.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_start_rx, m2m_ate_get_rx_status
*/
sint8 m2m_ate_stop_rx(void)
{
m2m_ate_set_rx_status(0);
nm_bsp_sleep(200); /*Recommended*/
return M2M_SUCCESS;
}
/*!
@fn \
sint8 m2m_ate_read_rx_status(tstrM2mAteRxStatus *)
@brief
This function used to read RX statistics from ATE firmware.
@param [out] strM2mAteRxStatus
Type of \ref tstrM2mAteRxStatus used to save statistics of RX test case. You must use \ref m2m_ate_start_rx first.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_start_rx
*/
sint8 m2m_ate_read_rx_status(tstrM2mAteRxStatus *strM2mAteRxStatus)
{
sint8 s8Ret = M2M_SUCCESS;
if(NULL == strM2mAteRxStatus)
{
s8Ret = M2M_ATE_ERR_VALIDATE;
goto __EXIT;
}
if(0 != m2m_ate_get_tx_status())
{
s8Ret = M2M_ATE_ERR_TX_ALREADY_RUNNING;
goto __EXIT;
}
if (nm_read_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_DA) || nm_read_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_SA))
{
strM2mAteRxStatus->num_rx_pkts = nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_SUCCESS) + nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_FAIL);
strM2mAteRxStatus->num_good_pkts = nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_SUCCESS);
strM2mAteRxStatus->num_err_pkts = nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_FAIL);
}
else
{
strM2mAteRxStatus->num_rx_pkts = nm_read_reg(rBurstRx_NMI_RX_ALL_PKTS_CONT) + nm_read_reg(0x989c);
strM2mAteRxStatus->num_err_pkts = nm_read_reg(rBurstRx_NMI_RX_ERR_PKTS_CONT);
strM2mAteRxStatus->num_good_pkts = strM2mAteRxStatus->num_rx_pkts - strM2mAteRxStatus->num_err_pkts;
}
__EXIT:
return s8Ret;
}
/*!
@fn \
sint8 m2m_ate_set_dig_gain(double dGaindB)
@brief
This function is used to set the digital gain
@param [in] double dGaindB
The digital gain value required to be set.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_set_dig_gain(double dGaindB)
{
uint32_t dGain, val32;
dGain = (uint32_t)(pow(10, dGaindB/20.0) * 1024.0);
val32 = nm_read_reg(0x160cd0);
val32 &= ~(0x1ffful << 0);
val32 |= (((uint32_t)dGain) << 0);
nm_write_reg(0x160cd0, val32);
return M2M_SUCCESS;
}
/*!
@fn \
sint8 m2m_ate_get_dig_gain(double * dGaindB)
@brief
This function is used to get the digital gain
@param [out] double * dGaindB
The retrieved digital gain value obtained from HW registers in dB.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_get_dig_gain(double * dGaindB)
{
uint32 dGain, val32;
if(!dGaindB) return M2M_ERR_INVALID_ARG;
val32 = nm_read_reg(0x160cd0);
dGain = (val32 >> 0) & 0x1ffful;
*dGaindB = 20.0*log10((double)dGain / 1024.0);
return M2M_SUCCESS;
}
/*!
@fn \
sint8 m2m_ate_get_pa_gain(double *paGaindB)
@brief
This function is used to get the PA gain
@param [out] double *paGaindB
The retrieved PA gain value obtained from HW registers in dB.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_get_pa_gain(double *paGaindB)
{
uint32 val32, paGain;
uint32 m_cmbPAGainStep;
if(!paGaindB)
return M2M_ERR_INVALID_ARG;
val32 = nm_read_reg(0x1e9c);
paGain = (val32 >> 8) & 0x3f;
switch(paGain){
case 0x1:
m_cmbPAGainStep = 5;
break;
case 0x3:
m_cmbPAGainStep = 4;
break;
case 0x7:
m_cmbPAGainStep = 3;
break;
case 0xf:
m_cmbPAGainStep = 2;
break;
case 0x1f:
m_cmbPAGainStep = 1;
break;
case 0x3f:
m_cmbPAGainStep = 0;
break;
default:
m_cmbPAGainStep = 0;
break;
}
*paGaindB = 18 - m_cmbPAGainStep*3;
return M2M_SUCCESS;
}
/*!
@fn \
sint8 m2m_ate_get_ppa_gain(double * ppaGaindB)
@brief
This function is used to get the PPA gain
@param [out] uint32 * ppaGaindB
The retrieved PPA gain value obtained from HW registers in dB.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_get_ppa_gain(double * ppaGaindB)
{
uint32 val32, ppaGain, m_cmbPPAGainStep;
if(!ppaGaindB) return M2M_ERR_INVALID_ARG;
val32 = nm_read_reg(0x1ea0);
ppaGain = (val32 >> 5) & 0x7;
switch(ppaGain){
case 0x1:
m_cmbPPAGainStep = 2;
break;
case 0x3:
m_cmbPPAGainStep = 1;
break;
case 0x7:
m_cmbPPAGainStep = 0;
break;
default:
m_cmbPPAGainStep = 3;
break;
}
*ppaGaindB = 9 - m_cmbPPAGainStep*3;
return M2M_SUCCESS;
}
/*!
@fn \
sint8 m2m_ate_get_tot_gain(double * totGaindB)
@brief
This function is used to calculate the total gain
@param [out] double * totGaindB
The retrieved total gain value obtained from calculations made based on the digital gain, PA and PPA gain values.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_get_tot_gain(double * totGaindB)
{
double dGaindB, paGaindB, ppaGaindB;
if(!totGaindB) return M2M_ERR_INVALID_ARG;
m2m_ate_get_pa_gain(&paGaindB);
m2m_ate_get_ppa_gain(&ppaGaindB);
m2m_ate_get_dig_gain(&dGaindB);
*totGaindB = dGaindB + paGaindB + ppaGaindB;
return M2M_SUCCESS;
}
#endif //_M2M_ATE_FW_

684
src/winc1500/src/m2m_hif.c Normal file
View File

@ -0,0 +1,684 @@
/**
*
* \file
*
* \brief This module contains M2M host interface APIs implementation.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "common/include/nm_common.h"
#include "driver/include/nmbus.h"
#include "bsp/include/nm_bsp.h"
#include "driver/include/m2m_hif.h"
#include "driver/include/m2m_types.h"
#include "driver/include/nmasic.h"
#include "driver/include/m2m_periph.h"
#if (defined NM_EDGE_INTERRUPT)&&(defined NM_LEVEL_INTERRUPT)
#error "only one type of interrupt NM_EDGE_INTERRUPT,NM_LEVEL_INTERRUPT"
#endif
#if !((defined NM_EDGE_INTERRUPT)||(defined NM_LEVEL_INTERRUPT))
#error "define interrupt type NM_EDGE_INTERRUPT,NM_LEVEL_INTERRUPT"
#endif
#ifndef CORTUS_APP
#define NMI_AHB_DATA_MEM_BASE 0x30000
#define NMI_AHB_SHARE_MEM_BASE 0xd0000
#define WIFI_HOST_RCV_CTRL_0 (0x1070)
#define WIFI_HOST_RCV_CTRL_1 (0x1084)
#define WIFI_HOST_RCV_CTRL_2 (0x1078)
#define WIFI_HOST_RCV_CTRL_3 (0x106c)
#define WAKE_VALUE (0x5678)
#define SLEEP_VALUE (0x4321)
#define WAKE_REG (0x1074)
static volatile uint8 gu8ChipMode = 0;
static volatile uint8 gu8ChipSleep = 0;
static volatile uint8 gu8HifSizeDone = 0;
static volatile uint8 gu8Interrupt = 0;
tpfHifCallBack pfWifiCb = NULL; /*!< pointer to Wi-Fi call back function */
tpfHifCallBack pfIpCb = NULL; /*!< pointer to Socket call back function */
tpfHifCallBack pfOtaCb = NULL; /*!< pointer to OTA call back function */
tpfHifCallBack pfHifCb = NULL;
static void isr(void)
{
gu8Interrupt++;
#ifdef NM_LEVEL_INTERRUPT
nm_bsp_interrupt_ctrl(0);
#endif
}
static sint8 hif_set_rx_done(void)
{
uint32 reg;
sint8 ret = M2M_SUCCESS;
#ifdef NM_EDGE_INTERRUPT
nm_bsp_interrupt_ctrl(1);
#endif
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0,&reg);
if(ret != M2M_SUCCESS)goto ERR1;
//reg &= ~(1<<0);
/* Set RX Done */
reg |= (1<<1);
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;
}
/**
* @fn static void m2m_hif_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
* @brief WiFi call back function
* @param [in] u8OpCode
* HIF Opcode type.
* @param [in] u16DataSize
* HIF data length.
* @param [in] u32Addr
* HIF address.
* @param [in] grp
* HIF group type.
* @author
* @date
* @version 1.0
*/
static void m2m_hif_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
{
}
/**
* @fn NMI_API sint8 hif_chip_wake(void);
* @brief To Wakeup the chip.
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
sint8 hif_chip_wake(void)
{
sint8 ret = M2M_SUCCESS;
if(gu8ChipSleep == 0)
{
if((gu8ChipMode == M2M_PS_DEEP_AUTOMATIC)||(gu8ChipMode == M2M_PS_MANUAL))
{
ret = nm_clkless_wake();
if(ret != M2M_SUCCESS)goto ERR1;
ret = nm_write_reg(WAKE_REG, WAKE_VALUE);
if(ret != M2M_SUCCESS)goto ERR1;
}
else
{
}
}
gu8ChipSleep++;
ERR1:
return ret;
}
/*!
@fn \
NMI_API void hif_set_sleep_mode(uint8 u8Pstype);
@brief
Set the sleep mode of the HIF layer.
@param [in] u8Pstype
Sleep mode.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
void hif_set_sleep_mode(uint8 u8Pstype)
{
gu8ChipMode = u8Pstype;
}
/*!
@fn \
NMI_API uint8 hif_get_sleep_mode(void);
@brief
Get the sleep mode of the HIF layer.
@return
The function SHALL return the sleep mode of the HIF layer.
*/
uint8 hif_get_sleep_mode(void)
{
return gu8ChipMode;
}
/**
* @fn NMI_API sint8 hif_chip_sleep(void);
* @brief To make the chip sleep.
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
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, &reg);
if(ret != M2M_SUCCESS)goto ERR1;
if(reg&0x2)
{
reg &=~(1 << 1);
ret = nm_write_reg(0x1, reg);
}
}
else
{
}
}
ERR1:
return ret;
}
/**
* @fn NMI_API sint8 hif_init(void * arg);
* @brief To 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_init(void * arg)
{
pfWifiCb = NULL;
pfIpCb = NULL;
gu8ChipSleep = 0;
gu8ChipMode = M2M_NO_PS;
gu8Interrupt = 0;
nm_bsp_register_isr(isr);
hif_register_cb(M2M_REQ_GRP_HIF,m2m_hif_cb);
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 NMI_API sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize,
uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset)
* @brief Send packet using host interface.
* @param [in] u8Gid
* Group ID.
* @param [in] u8Opcode
* Operation ID.
* @param [in] pu8CtrlBuf
* Pointer to the Control buffer.
* @param [in] u16CtrlBufSize
Control buffer size.
* @param [in] u16DataOffset
Packet Data offset.
* @param [in] pu8DataBuf
* Packet buffer Allocated by the caller.
* @param [in] u16DataSize
Packet buffer size (including the HIF header).
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
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);
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 |= (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;
}
/**
* @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(0x1070, &reg);
if(M2M_SUCCESS == ret)
{
if(reg & 0x1) /* New interrupt has been received */
{
uint16 size;
nm_bsp_interrupt_ctrl(0);
/*Clearing RX interrupt*/
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0,&reg);
if(ret != M2M_SUCCESS)goto ERR1;
reg &= ~(1<<0);
ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0,reg);
if(ret != M2M_SUCCESS)goto ERR1;
/* read the rx size */
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, &reg);
if(M2M_SUCCESS != ret)
{
M2M_ERR("(hif) WIFI_HOST_RCV_CTRL_0 bus fail\n");
nm_bsp_interrupt_ctrl(1);
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_GRP_WIFI == strHif.u8Gid)
{
if(pfWifiCb)
pfWifiCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
}
else if(M2M_REQ_GRP_IP == strHif.u8Gid)
{
if(pfIpCb)
pfIpCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
}
else if(M2M_REQ_GRP_OTA == strHif.u8Gid)
{
if(pfOtaCb)
pfOtaCb(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
{
#ifndef WIN32
M2M_ERR("(hif) False interrupt %lx",reg);
#endif
}
}
else
{
M2M_ERR("(hif) Fail to Read interrupt reg\n");
goto ERR1;
}
}
else
{
M2M_ERR("(hif) FAIL to wakeup the chip\n");
goto ERR1;
}
ret = hif_chip_sleep();
ERR1:
return ret;
}
/**
* @fn hif_handle_isr(void)
* @brief Handle interrupt received from NMC1500 firmware.
* @return The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 hif_handle_isr(void)
{
sint8 ret = M2M_SUCCESS;
while (gu8Interrupt) {
/*must be at that place because of the race of interrupt increment and that decrement*/
/*when the interrupt enabled*/
gu8Interrupt--;
while(1)
{
ret = hif_isr();
if(ret == M2M_SUCCESS) {
/*we will try forever untill we get that interrupt*/
/*Fail return errors here due to bus errors (reading expected values)*/
break;
} else {
M2M_ERR("(HIF) Fail to handle interrupt %d try Again..\n",ret);
}
}
}
return ret;
}
/*
* @fn hif_receive
* @brief Host interface interrupt serviece routine
* @param [in] u32Addr
* Receive start address
* @param [out] pu8Buf
* Pointer to receive buffer. Allocated by the caller
* @param [in] u16Sz
* Receive buffer size
* @param [in] isDone
* If you don't need any more packets send True otherwise send false
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
sint8 hif_receive(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz, uint8 isDone)
{
uint32 address, reg;
uint16 size;
sint8 ret = M2M_SUCCESS;
if(u32Addr == 0 ||pu8Buf == NULL || u16Sz == 0)
{
if(isDone)
{
gu8HifSizeDone = 1;
/* set RX done */
ret = hif_set_rx_done();
}
ret = M2M_ERR_FAIL;
M2M_ERR(" hif_receive: Invalid argument\n");
goto ERR1;
}
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0,&reg);
if(ret != M2M_SUCCESS)goto ERR1;
size = (uint16)((reg >> 2) & 0xfff);
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_1,&address);
if(ret != M2M_SUCCESS)goto ERR1;
/* Receive the payload */
ret = nm_read_block(u32Addr, pu8Buf, u16Sz);
if(ret != M2M_SUCCESS)goto ERR1;
if(u16Sz > size)
{
ret = M2M_ERR_FAIL;
M2M_ERR("APP Requested Size is larger than the recived buffer size <%d><%d>\n",u16Sz, size);
goto ERR1;
}
if((u32Addr < address)||((u32Addr + u16Sz)>(address+size)))
{
ret = M2M_ERR_FAIL;
M2M_ERR("APP Requested Address beyond the recived buffer address and length\n");
goto ERR1;
}
/* check if this is the last packet */
if((((address+size) - (u32Addr+u16Sz)) <= 0) || isDone)
{
gu8HifSizeDone = 1;
/* set RX done */
ret = hif_set_rx_done();
}
ERR1:
return ret;
}
/**
* @fn hif_register_cb
* @brief To set Callback function for every compantent Component
* @param [in] u8Grp
* Group to which the Callback function should be set.
* @param [in] fn
* function to be set
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
sint8 hif_register_cb(uint8 u8Grp,tpfHifCallBack fn)
{
sint8 ret = M2M_SUCCESS;
switch(u8Grp)
{
case M2M_REQ_GRP_IP:
pfIpCb = fn;
break;
case M2M_REQ_GRP_WIFI:
pfWifiCb = fn;
break;
case M2M_REQ_GRP_OTA:
pfOtaCb = fn;
break;
case M2M_REQ_GRP_HIF:
pfHifCb = fn;
break;
default:
M2M_ERR("GRp ? %d\n",u8Grp);
ret = M2M_ERR_FAIL;
break;
}
return ret;
}
#endif

320
src/winc1500/src/m2m_ota.c Normal file
View File

@ -0,0 +1,320 @@
/**
*
* \file
*
* \brief NMC1500 IoT OTA Interface.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "common/include/nm_common.h"
#include "driver/include/m2m_types.h"
#include "driver/include/m2m_ota.h"
#include "driver/include/m2m_hif.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
static tpfOtaUpdateCb gpfOtaUpdateCb = NULL;
static tpfOtaNotifCb gpfOtaNotifCb = NULL;
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/**
* @fn m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr, uint8 grp)
* @brief WiFi call back function
* @param [in] u8OpCode
* HIF Opcode type.
* @param [in] u16DataSize
* HIF data length.
* @param [in] u32Addr
* HIF address.
* @param [in] grp
* HIF group type.
* @author
* @date
* @version 1.0
*/
static void m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
{
sint8 ret = M2M_SUCCESS;
if(u8OpCode == M2M_OTA_RESP_NOTIF_UPDATE_INFO)
{
tstrOtaUpdateInfo strOtaUpdateInfo;
m2m_memset((uint8*)&strOtaUpdateInfo,0,sizeof(tstrOtaUpdateInfo));
ret = hif_receive(u32Addr,(uint8*)&strOtaUpdateInfo,sizeof(tstrOtaUpdateInfo),0);
if(ret == M2M_SUCCESS)
{
if(gpfOtaNotifCb)
gpfOtaNotifCb(&strOtaUpdateInfo);
}
}
else if (u8OpCode == M2M_OTA_RESP_UPDATE_STATUS)
{
tstrOtaUpdateStatusResp strOtaUpdateStatusResp;
m2m_memset((uint8*)&strOtaUpdateStatusResp,0,sizeof(tstrOtaUpdateStatusResp));
ret = hif_receive(u32Addr, (uint8*) &strOtaUpdateStatusResp,sizeof(tstrOtaUpdateStatusResp), 0);
if(ret == M2M_SUCCESS)
{
if(gpfOtaUpdateCb)
gpfOtaUpdateCb(strOtaUpdateStatusResp.u8OtaUpdateStatusType,strOtaUpdateStatusResp.u8OtaUpdateStatus);
}
}
else
{
M2M_ERR("Invaild OTA resp %d ?\n",u8OpCode);
}
}
/*!
@fn \
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb);
@brief
Initialize the OTA layer.
@param [in] pfOtaUpdateCb
OTA Update callback function
@param [in] pfOtaNotifCb
OTA notify callback function
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb)
{
sint8 ret = M2M_SUCCESS;
if(pfOtaUpdateCb){
gpfOtaUpdateCb = pfOtaUpdateCb;
}else{
M2M_ERR("Invaild Ota update cb\n");
}
if(pfOtaNotifCb){
gpfOtaNotifCb = pfOtaNotifCb;
}else{
M2M_ERR("Invaild Ota notify cb\n");
}
hif_register_cb(M2M_REQ_GRP_OTA,m2m_ota_cb);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url);
@brief
Set the OTA url
@param [in] u8Url
The url server address
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url)
{
sint8 ret = M2M_SUCCESS;
uint16 u16UrlSize = m2m_strlen(u8Url) + 1;
/*Todo: we may change it to data pkt but we need to give it higer priority
but the priorty is not implemnted yet in data pkt
*/
ret = hif_send(M2M_REQ_GRP_OTA,M2M_OTA_REQ_START_UPDATE,u8Url,u16UrlSize,NULL,0,0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_notif_check_for_update(void);
@brief
check for ota update
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_check_for_update(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GRP_OTA,M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE,NULL,0,NULL,0,0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
@brief
Schedule OTA update
@param [in] u32Period
Period in days
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GRP_OTA,M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE,NULL,0,NULL,0,0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_start_update(uint8 * u8DownloadUrl);
@brief
Request OTA start update using the downloaded url
@param [in] u8DownloadUrl
The download firmware url, you get it from device info
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_start_update(uint8 * u8DownloadUrl)
{
sint8 ret = M2M_SUCCESS;
uint16 u16DurlSize = m2m_strlen(u8DownloadUrl) + 1;
/*Todo: we may change it to data pkt but we need to give it higer priority
but the priorty is not implemnted yet in data pkt
*/
ret = hif_send(M2M_REQ_GRP_OTA,M2M_OTA_REQ_START_UPDATE,u8DownloadUrl,u16DurlSize,NULL,0,0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_rollback(void);
@brief
Request OTA Rollback image
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_rollback(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GRP_OTA,M2M_OTA_REQ_ROLLBACK,NULL,0,NULL,0,0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_switch_firmware(void);
@brief
Switch to the upgraded Firmware
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_switch_firmware(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GRP_OTA,M2M_OTA_REQ_SWITCH_FIRMWARE,NULL,0,NULL,0,0);
return ret;
}
#if 0
#define M2M_OTA_FILE "../../../m2m_ota.dat"
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_GRP_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;
}
#endif

View File

@ -0,0 +1,154 @@
/**
*
* \file
*
* \brief NMC1500 Peripherials Application Interface.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "driver/include/m2m_periph.h"
#include "driver/include/nmasic.h"
#include "driver/include/m2m_hif.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#define GPIO_OP_DIR 0
#define GPIO_OP_SET 1
#define GPIO_OP_GET 2
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
STATIC FUNCTIONS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
static sint8 get_gpio_idx(uint8 u8GpioNum)
{
if(u8GpioNum >= M2M_PERIPH_GPIO_MAX) return -1;
if(u8GpioNum == M2M_PERIPH_GPIO15) { return 15;
} else if(u8GpioNum == M2M_PERIPH_GPIO16) { return 16;
} else if(u8GpioNum == M2M_PERIPH_GPIO18) { return 18;
} else {
return -2;
}
}
/*
* 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;
}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION IMPLEMENTATION
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
sint8 m2m_periph_init(tstrPerphInitParam * param)
{
return M2M_SUCCESS;
}
sint8 m2m_periph_gpio_set_dir(uint8 u8GpioNum, uint8 u8GpioDir)
{
return gpio_ioctl(GPIO_OP_DIR, u8GpioNum, u8GpioDir, NULL);
}
sint8 m2m_periph_gpio_set_val(uint8 u8GpioNum, uint8 u8GpioVal)
{
return gpio_ioctl(GPIO_OP_SET, u8GpioNum, u8GpioVal, NULL);
}
sint8 m2m_periph_gpio_get_val(uint8 u8GpioNum, uint8 * pu8GpioVal)
{
return gpio_ioctl(GPIO_OP_GET, u8GpioNum, 0, pu8GpioVal);
}
sint8 m2m_periph_gpio_pullup_ctrl(uint8 u8GpioNum, uint8 u8PullupEn)
{
/* TBD */
return M2M_SUCCESS;
}
sint8 m2m_periph_i2c_master_init(tstrI2cMasterInitParam * param)
{
/* TBD */
return M2M_SUCCESS;
}
sint8 m2m_periph_i2c_master_write(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint8 flags)
{
/* TBD */
return M2M_SUCCESS;
}
sint8 m2m_periph_i2c_master_read(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint16 * pu16ReadLen, uint8 flags)
{
/* TBD */
return M2M_SUCCESS;
}
sint8 m2m_periph_pullup_ctrl(uint32 pinmask, uint8 enable)
{
return pullup_ctrl(pinmask, enable);
}

1231
src/winc1500/src/m2m_wifi.c Normal file

File diff suppressed because it is too large Load Diff

118
src/winc1500/src/nm_bsp.c Normal file
View File

@ -0,0 +1,118 @@
#include <stm32f4xx_hal.h>
#include "conf_winc.h"
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_common.h"
#include "py/nlr.h"
#include "py/runtime.h"
#include "pin.h"
#include "genhdr/pins.h"
#include "extint.h"
#include "systick.h"
static tpfNmBspIsr gpfIsr;
static const pin_obj_t *PIN_CS = &pin_B12;
static const pin_obj_t *PIN_EN = &pin_A5;
static const pin_obj_t *PIN_RST = &pin_D12;
static const pin_obj_t *PIN_IRQ = &pin_D13;
static const mp_obj_fun_builtin_t irq_callback_obj;
/*
* @fn nm_bsp_init
* @brief Initialize BSP
* @return 0 in case of success and -1 in case of failure
*/
sint8 nm_bsp_init(void)
{
gpfIsr = NULL;
// configure wlan CS and EN pins
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Alternate = 0;
GPIO_InitStructure.Pin = PIN_CS->pin_mask;
HAL_GPIO_Init(PIN_CS->gpio, &GPIO_InitStructure);
GPIO_InitStructure.Pin = PIN_EN->pin_mask;
HAL_GPIO_Init(PIN_EN->gpio, &GPIO_InitStructure);
GPIO_InitStructure.Pin = PIN_RST->pin_mask;
HAL_GPIO_Init(PIN_RST->gpio, &GPIO_InitStructure);
HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_SET);
HAL_GPIO_WritePin(PIN_EN->gpio, PIN_EN->pin_mask, GPIO_PIN_SET);
HAL_GPIO_WritePin(PIN_RST->gpio, PIN_RST->pin_mask, GPIO_PIN_SET);
/* Perform chip reset. */
nm_bsp_reset();
return M2M_SUCCESS;
}
/**
* @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(PIN_EN->gpio, PIN_EN->pin_mask, GPIO_PIN_RESET);
HAL_GPIO_WritePin(PIN_RST->gpio, PIN_RST->pin_mask, GPIO_PIN_RESET);
nm_bsp_sleep(100);
HAL_GPIO_WritePin(PIN_EN->gpio, PIN_EN->pin_mask, GPIO_PIN_SET);
nm_bsp_sleep(100);
HAL_GPIO_WritePin(PIN_RST->gpio, PIN_RST->pin_mask, GPIO_PIN_SET);
nm_bsp_sleep(100);
}
extern void systick_sleep(uint32_t ms);
/*
* @fn nm_bsp_sleep
* @brief Sleep in units of mSec
* @param[IN] u32TimeMsec
* Time in milliseconds
*/
void nm_bsp_sleep(uint32 u32TimeMsec)
{
systick_sleep(u32TimeMsec);
}
/*
* @fn nm_bsp_register_isr
* @brief Register interrupt service routine
* @param[IN] pfIsr
* Pointer to ISR handler
*/
void nm_bsp_register_isr(tpfNmBspIsr pfIsr)
{
gpfIsr = pfIsr;
// register EXTI
extint_register((mp_obj_t)PIN_IRQ, GPIO_MODE_IT_FALLING, GPIO_PULLUP, (mp_obj_t)&irq_callback_obj, true);
extint_enable(PIN_IRQ->pin);
}
/*
* @fn nm_bsp_interrupt_ctrl
* @brief Enable/Disable interrupts
* @param[IN] u8Enable
* '0' disable interrupts. '1' enable interrupts
*/
void nm_bsp_interrupt_ctrl(uint8 u8Enable)
{
if (u8Enable) {
extint_enable(PIN_IRQ->pin);
} else {
extint_disable(PIN_IRQ->pin);
}
}
static mp_obj_t irq_callback(mp_obj_t line) {
if (gpfIsr) {
gpfIsr();
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(irq_callback_obj, irq_callback);

View File

@ -0,0 +1,214 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus wrapper APIs implementation.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include <stdio.h>
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_common.h"
#include "bus_wrapper/include/nm_bus_wrapper.h"
#include "conf_winc.h"
#include "py/nlr.h"
#include "py/runtime.h"
#include "pin.h"
#include "genhdr/pins.h"
#include "extint.h"
#include <stm32f4xx_hal.h>
#include "spi.h"
static SPI_HandleTypeDef SPI_HANDLE;
#define NM_BUS_MAX_TRX_SZ 4096
tstrNmBusCapabilities egstrNmBusCapabilities =
{
NM_BUS_MAX_TRX_SZ
};
#ifdef CONF_WINC_USE_I2C
#define SLAVE_ADDRESS 0x60
/** Number of times to try to send packet if failed. */
#define I2C_TIMEOUT 100
static sint8 nm_i2c_write(uint8 *b, uint16 sz)
{
sint8 result = M2M_ERR_BUS_FAIL;
return result;
}
static sint8 nm_i2c_read(uint8 *rb, uint16 sz)
{
sint8 result = M2M_ERR_BUS_FAIL;
return result;
}
static sint8 nm_i2c_write_special(uint8 *wb1, uint16 sz1, uint8 *wb2, uint16 sz2)
{
static uint8 tmp[NM_BUS_MAX_TRX_SZ];
m2m_memcpy(tmp, wb1, sz1);
m2m_memcpy(&tmp[sz1], wb2, sz2);
return nm_i2c_write(tmp, sz1+sz2);
}
#endif
#ifdef CONF_WINC_USE_SPI
/** PIO instance used by CS. */
static const pin_obj_t *PIN_CS = &pin_B12;
#define SPI_ASSERT_CS() do {HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_RESET);} while(0)
#define SPI_DEASSERT_CS() do {HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_SET);} while(0)
#define SPI_TIMEOUT (10000) /* in ms */
#include <string.h>
static sint8 spi_rw(uint8 *tx_buf, uint8 *rx_buf, uint16 u16Sz)
{
sint8 result = M2M_SUCCESS;
if (tx_buf == 0) {
memset(rx_buf, 0, u16Sz);
tx_buf = rx_buf;
}
if (rx_buf == 0) {
rx_buf = tx_buf;
}
// Start SPI transfer
// TODO: Use DMA
__disable_irq();
SPI_ASSERT_CS();
if (HAL_SPI_TransmitReceive(&SPI_HANDLE, tx_buf, rx_buf, u16Sz, SPI_TIMEOUT) != HAL_OK) {
result = M2M_ERR_BUS_FAIL;
}
SPI_DEASSERT_CS();
__enable_irq();
return result;
}
#endif
/*
* @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;
SPI_DEASSERT_CS();
// SPI configuration
SPI_HANDLE.Instance = SPI2;
SPI_HANDLE.Init.Mode = SPI_MODE_MASTER;
SPI_HANDLE.Init.Direction = SPI_DIRECTION_2LINES;
SPI_HANDLE.Init.DataSize = SPI_DATASIZE_8BIT;
SPI_HANDLE.Init.CLKPolarity = SPI_POLARITY_LOW;
SPI_HANDLE.Init.CLKPhase = SPI_PHASE_1EDGE;
SPI_HANDLE.Init.NSS = SPI_NSS_SOFT;
SPI_HANDLE.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
SPI_HANDLE.Init.FirstBit = SPI_FIRSTBIT_MSB;
SPI_HANDLE.Init.TIMode = SPI_TIMODE_DISABLED;
SPI_HANDLE.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
SPI_HANDLE.Init.CRCPolynomial = 7;
// Init SPI
spi_init(&SPI_HANDLE, false);
nm_bsp_reset();
SPI_DEASSERT_CS();
return result;
}
/*
* @fn nm_bus_ioctl
* @brief send/receive from the bus
* @param[IN] u8Cmd
* IOCTL command for the operation
* @param[IN] pvParameter
* Arbitrary parameter depenging on IOCTL
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @note For SPI only, it's important to be able to send/receive at the same time
*/
sint8 nm_bus_ioctl(uint8 u8Cmd, void* pvParameter)
{
sint8 s8Ret = 0;
switch(u8Cmd)
{
#ifdef CONF_WINC_USE_I2C
case NM_BUS_IOCTL_R: {
tstrNmI2cDefault *pstrParam = (tstrNmI2cDefault *)pvParameter;
s8Ret = nm_i2c_read(pstrParam->pu8Buf, pstrParam->u16Sz);
}
break;
case NM_BUS_IOCTL_W: {
tstrNmI2cDefault *pstrParam = (tstrNmI2cDefault *)pvParameter;
s8Ret = nm_i2c_write(pstrParam->pu8Buf, pstrParam->u16Sz);
}
break;
case NM_BUS_IOCTL_W_SPECIAL: {
tstrNmI2cSpecial *pstrParam = (tstrNmI2cSpecial *)pvParameter;
s8Ret = nm_i2c_write_special(pstrParam->pu8Buf1, pstrParam->u16Sz1, pstrParam->pu8Buf2, pstrParam->u16Sz2);
}
break;
#elif defined CONF_WINC_USE_SPI
case NM_BUS_IOCTL_RW: {
tstrNmSpiRw *pstrParam = (tstrNmSpiRw *)pvParameter;
s8Ret = spi_rw(pstrParam->pu8InBuf, pstrParam->pu8OutBuf, pstrParam->u16Sz);
}
break;
#endif
default:
s8Ret = -1;
M2M_ERR("invalide ioclt cmd\n");
break;
}
return s8Ret;
}
/*
* @fn nm_bus_deinit
* @brief De-initialize the bus wrapper
*/
sint8 nm_bus_deinit(void)
{
return M2M_SUCCESS;
}

View File

@ -0,0 +1,136 @@
/**
*
* \file
*
* \brief This module contains common APIs declarations.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "common/include/nm_common.h"
void m2m_memcpy(uint8* pDst,uint8* pSrc,uint32 sz)
{
if(sz == 0) return;
do
{
*pDst = *pSrc;
pDst++;
pSrc++;
}while(--sz);
}
uint8 m2m_checksum(uint8* buf, int sz)
{
uint8 cs = 0;
while(--sz)
{
cs ^= *buf;
buf++;
}
return cs;
}
void m2m_memset(uint8* pBuf,uint8 val,uint32 sz)
{
if(sz == 0) return;
do
{
*pBuf = val;
pBuf++;
}while(--sz);
}
uint16 m2m_strlen(uint8 * pcStr)
{
uint16 u16StrLen = 0;
while(*pcStr)
{
u16StrLen ++;
pcStr++;
}
return u16StrLen;
}
uint8 m2m_strncmp(uint8 *pcS1, uint8 *pcS2, uint16 u16Len)
{
for ( ; u16Len > 0; pcS1++, pcS2++, --u16Len)
if (*pcS1 != *pcS2)
return ((*(uint8 *)pcS1 < *(uint8 *)pcS2) ? -1 : +1);
else if (*pcS1 == '\0')
return 0;
return 0;
}
/* Finds the occurance of pcStr in pcIn.
If pcStr is part of pcIn it returns a valid pointer to the start of pcStr within pcIn.
Otherwise a NULL Pointer is returned.
*/
uint8 * m2m_strstr(uint8 *pcIn, uint8 *pcStr)
{
uint8 u8c;
uint16 u16StrLen;
u8c = *pcStr++;
if (!u8c)
return (uint8 *) pcIn; // Trivial empty string case
u16StrLen = m2m_strlen(pcStr);
do {
uint8 u8Sc;
do {
u8Sc = *pcIn++;
if (!u8Sc)
return (uint8 *) 0;
} while (u8Sc != u8c);
} while (m2m_strncmp(pcIn, pcStr, u16StrLen) != 0);
return (uint8 *) (pcIn - 1);
}
sint8 m2m_memcmp(uint8 *pu8Buff1,uint8 *pu8Buff2 ,uint32 u32Size)
{
uint32 i;
sint8 s8Result = 0;
for(i = 0 ; i < u32Size ; i++)
{
if(pu8Buff1[i] != pu8Buff2[i])
{
s8Result = 1;
break;
}
}
return s8Result;
}

678
src/winc1500/src/nmasic.c Normal file
View File

@ -0,0 +1,678 @@
/**
*
* \file
*
* \brief This module contains NMC1500 ASIC specific internal APIs.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "common/include/nm_common.h"
#include "driver/include/nmbus.h"
#include "bsp/include/nm_bsp.h"
#include "driver/include/nmasic.h"
#define NMI_GLB_RESET_0 (NMI_PERIPH_REG_BASE + 0x400)
#define NMI_INTR_REG_BASE (NMI_PERIPH_REG_BASE+0xa00)
#define NMI_PIN_MUX_0 (NMI_PERIPH_REG_BASE + 0x408)
#define NMI_INTR_ENABLE (NMI_INTR_REG_BASE)
#define GET_UINT32(X,Y) (X[0+Y] + ((uint32)X[1+Y]<<8) + ((uint32)X[2+Y]<<16) +((uint32)X[3+Y]<<24))
#define TIMEOUT (2000)
#define M2M_DISABLE_PS 0xD0UL
static uint32 clk_status_reg_adr = 0xf; /* Assume initially it is B0 chip */
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, &reg);
if(ret == M2M_SUCCESS) {
if(reg == val32)
break;
}
} else {
break;
}
} while(1);
return M2M_SUCCESS;
}
/**
* @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");
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));
/* wait 1ms, spi data read */
nm_bsp_sleep(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;
/* 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) {
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(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);
_WAKE_EXIT:
return ret;
}
void chip_idle(void)
{
uint32 reg =0;
nm_read_reg_with_ret(0x1, &reg);
if(reg&0x2)
{
reg &=~(1 << 1);
nm_write_reg(0x1, reg);
}
}
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);
}
sint8 enable_interrupts(void)
{
uint32 reg;
sint8 ret;
/**
interrupt pin mux select
**/
ret = nm_read_reg_with_ret(NMI_PIN_MUX_0, &reg);
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, &reg);
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 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;
}
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;
}
uint32 nmi_get_rfrevid(void)
{
uint32 rfrevid;
if((nm_read_reg_with_ret(0x13f4, &rfrevid)) != M2M_SUCCESS) {
rfrevid = 0;
return 0;
}
return rfrevid;
}
void restore_pmu_settings_after_global_reset(void)
{
/*
* Must restore PMU register value after
* global reset if PMU toggle is done at
* least once since the last hard reset.
*/
if(REV(nmi_get_chipid()) >= REV_2B0) {
nm_write_reg(0x1e48, 0xb78469ce);
}
}
void nmi_update_pll(void)
{
uint32 pll;
pll = nm_read_reg(0x1428);
pll &= ~0x1ul;
nm_write_reg(0x1428, pll);
pll |= 0x1ul;
nm_write_reg(0x1428, pll);
}
void nmi_set_sys_clk_src_to_xo(void)
{
uint32 val32;
/* Switch system clock source to XO. This will take effect after nmi_update_pll(). */
val32 = nm_read_reg(0x141c);
val32 |= (1 << 2);
nm_write_reg(0x141c, val32);
/* Do PLL update */
nmi_update_pll();
}
sint8 chip_wake(void)
{
sint8 ret = M2M_SUCCESS;
ret = nm_clkless_wake();
if(ret != M2M_SUCCESS) return ret;
enable_rf_blocks();
return ret;
}
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, &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_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);
ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
}
#if 0
reg |= (1ul << 10);
ret += nm_write_reg(NMI_GLB_RESET_0, reg);
ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
#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;
}
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;
}
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;
}
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;
}
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, &reg);
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, &reg);
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 set_gpio_dir(uint8 gpio, uint8 dir)
{
uint32 val32;
sint8 ret;
ret = nm_read_reg_with_ret(0x20108, &val32);
if(ret != M2M_SUCCESS) goto _EXIT;
if(dir) {
val32 |= (1ul << gpio);
} else {
val32 &= ~(1ul << gpio);
}
ret = nm_write_reg(0x20108, val32);
_EXIT:
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;
}
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 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 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_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;
}

279
src/winc1500/src/nmbus.c Normal file
View File

@ -0,0 +1,279 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus APIs implementation.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef CORTUS_APP
#include "driver/include/nmbus.h"
#include "driver/include/nmi2c.h"
#include "driver/include/nmspi.h"
#include "driver/include/nmuart.h"
#define MAX_TRX_CFG_SZ 8
/**
* @fn nm_bus_iface_init
* @brief Initialize bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_bus_iface_init(void *pvInitVal)
{
sint8 ret = M2M_SUCCESS;
ret = nm_bus_init(pvInitVal);
return ret;
}
/**
* @fn nm_bus_iface_deinit
* @brief Deinitialize bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Samer Sarhan
* @date 07 April 2014
* @version 1.0
*/
sint8 nm_bus_iface_deinit(void)
{
sint8 ret = M2M_SUCCESS;
ret = nm_bus_deinit();
return ret;
}
/**
* @fn nm_bus_iface_reconfigure
* @brief reconfigure bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Viswanathan Murugesan
* @date 22 Oct 2014
* @version 1.0
*/
sint8 nm_bus_iface_reconfigure(void *ptr)
{
sint8 ret = M2M_SUCCESS;
#ifdef CONF_WINC_USE_UART
ret = nm_uart_reconfigure(ptr);
#endif
return ret;
}
/*
* @fn nm_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
uint32 nm_read_reg(uint32 u32Addr)
{
#ifdef CONF_WINC_USE_UART
return nm_uart_read_reg(u32Addr);
#elif defined (CONF_WINC_USE_SPI)
return nm_spi_read_reg(u32Addr);
#elif defined (CONF_WINC_USE_I2C)
return nm_i2c_read_reg(u32Addr);
#else
#error "Plesae define bus usage"
#endif
}
/*
* @fn nm_read_reg_with_ret
* @brief Read register with error code return
* @param [in] u32Addr
* Register address
* @param [out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_read_reg_with_ret(uint32 u32Addr, uint32* pu32RetVal)
{
#ifdef CONF_WINC_USE_UART
return nm_uart_read_reg_with_ret(u32Addr,pu32RetVal);
#elif defined (CONF_WINC_USE_SPI)
return nm_spi_read_reg_with_ret(u32Addr,pu32RetVal);
#elif defined (CONF_WINC_USE_I2C)
return nm_i2c_read_reg_with_ret(u32Addr,pu32RetVal);
#else
#error "Plesae define bus usage"
#endif
}
/*
* @fn nm_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_write_reg(uint32 u32Addr, uint32 u32Val)
{
#ifdef CONF_WINC_USE_UART
return nm_uart_write_reg(u32Addr,u32Val);
#elif defined (CONF_WINC_USE_SPI)
return nm_spi_write_reg(u32Addr,u32Val);
#elif defined (CONF_WINC_USE_I2C)
return nm_i2c_write_reg(u32Addr,u32Val);
#else
#error "Plesae define bus usage"
#endif
}
static sint8 p_nm_read_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz)
{
#ifdef CONF_WINC_USE_UART
return nm_uart_read_block(u32Addr,puBuf,u16Sz);
#elif defined (CONF_WINC_USE_SPI)
return nm_spi_read_block(u32Addr,puBuf,u16Sz);
#elif defined (CONF_WINC_USE_I2C)
return nm_i2c_read_block(u32Addr,puBuf,u16Sz);
#else
#error "Plesae define bus usage"
#endif
}
/*
* @fn nm_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u32Sz
* Number of bytes to read. The buffer size must be >= u32Sz
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_read_block(uint32 u32Addr, uint8 *puBuf, uint32 u32Sz)
{
uint16 u16MaxTrxSz = egstrNmBusCapabilities.u16MaxTrxSz - MAX_TRX_CFG_SZ;
uint32 off = 0;
sint8 s8Ret = M2M_SUCCESS;
for(;;)
{
if(u32Sz <= u16MaxTrxSz)
{
s8Ret += p_nm_read_block(u32Addr, &puBuf[off], (uint16)u32Sz);
break;
}
else
{
s8Ret += p_nm_read_block(u32Addr, &puBuf[off], u16MaxTrxSz);
if(M2M_SUCCESS != s8Ret) break;
u32Sz -= u16MaxTrxSz;
off += u16MaxTrxSz;
u32Addr += u16MaxTrxSz;
}
}
return s8Ret;
}
static sint8 p_nm_write_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz)
{
#ifdef CONF_WINC_USE_UART
return nm_uart_write_block(u32Addr,puBuf,u16Sz);
#elif defined (CONF_WINC_USE_SPI)
return nm_spi_write_block(u32Addr,puBuf,u16Sz);
#elif defined (CONF_WINC_USE_I2C)
return nm_i2c_write_block(u32Addr,puBuf,u16Sz);
#else
#error "Plesae define bus usage"
#endif
}
/**
* @fn nm_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u32Sz
* Number of bytes to write. The buffer size must be >= u32Sz
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_write_block(uint32 u32Addr, uint8 *puBuf, uint32 u32Sz)
{
uint16 u16MaxTrxSz = egstrNmBusCapabilities.u16MaxTrxSz - MAX_TRX_CFG_SZ;
uint32 off = 0;
sint8 s8Ret = M2M_SUCCESS;
for(;;)
{
if(u32Sz <= u16MaxTrxSz)
{
s8Ret += p_nm_write_block(u32Addr, &puBuf[off], (uint16)u32Sz);
break;
}
else
{
s8Ret += p_nm_write_block(u32Addr, &puBuf[off], u16MaxTrxSz);
if(M2M_SUCCESS != s8Ret) break;
u32Sz -= u16MaxTrxSz;
off += u16MaxTrxSz;
u32Addr += u16MaxTrxSz;
}
}
return s8Ret;
}
#endif

270
src/winc1500/src/nmdrv.c Normal file
View File

@ -0,0 +1,270 @@
/**
*
* \file
*
* \brief This module contains NMC1000 M2M driver APIs implementation.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "common/include/nm_common.h"
#include "driver/include/nmbus.h"
#include "bsp/include/nm_bsp.h"
#include "driver/include/nmdrv.h"
#include "driver/include/nmasic.h"
#include "driver/include/m2m_types.h"
#ifdef CONF_WINC_USE_SPI
#include "driver/include/nmspi.h"
#endif
/**
* @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, &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;
}
/*
* @fn nm_drv_init_download_mode
* @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 Viswanathan Murugesan
* @date 10 Oct 2014
* @version 1.0
*/
sint8 nm_drv_init_download_mode()
{
sint8 ret = M2M_SUCCESS;
ret = nm_bus_iface_init(NULL);
if (M2M_SUCCESS != ret) {
M2M_ERR("[nmi start]: fail init bus\n");
goto ERR1;
}
#ifdef CONF_WINC_USE_SPI
/* Must do this after global reset to set SPI data packet size. */
nm_spi_init();
#endif
M2M_INFO("Chip ID %lx\n", nmi_get_chipid());
/*disable all interrupt in ROM (to disable uart) in 2b0 chip*/
nm_write_reg(0x20300,0);
ERR1:
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;
}
/*
* @fn nm_drv_deinit
* @brief Deinitialize NMC1000 driver
* @author M. Abdelmawla
* @date 17 July 2012
* @version 1.0
*/
sint8 nm_drv_deinit(void * arg)
{
sint8 ret;
ret = chip_deinit();
if (M2M_SUCCESS != ret) {
M2M_ERR("[nmi stop]: chip_deinit fail\n");
goto ERR1;
}
ret = nm_bus_iface_deinit();
if (M2M_SUCCESS != ret) {
M2M_ERR("[nmi stop]: fail init bus\n");
goto ERR1;
}
#ifdef CONF_WINC_USE_SPI
/* Must do this after global reset to set SPI data packet size. */
nm_spi_deinit();
#endif
ERR1:
return ret;
}

269
src/winc1500/src/nmi2c.c Normal file
View File

@ -0,0 +1,269 @@
/**
*
* \file
*
* \brief This module contains NMC1000 I2C protocol bus APIs implementation.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "common/include/nm_common.h"
#ifdef CONF_WINC_USE_I2C
#include "nmi2c.h"
#include "bus_wrapper/include/nm_bus_wrapper.h"
/*
* @fn nm_i2c_read_reg_with_ret
* @brief Read register with error code return
* @param [in] u32Addr
* Register address
* @param [out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_i2c_read_reg_with_ret(uint32 u32Addr, uint32* pu32RetVal)
{
uint8 b[6];
uint8 rsz;
tstrNmI2cDefault strI2c;
sint8 s8Ret = M2M_SUCCESS;
if(u32Addr < 0xff) { /* clockless i2c */
b[0] = 0x09;
b[1] = (uint8)(u32Addr);
rsz = 1;
strI2c.u16Sz = 2;
} else {
b[0] = 0x80;
b[1] = (uint8)(u32Addr >> 24);
b[2] = (uint8)(u32Addr >> 16);
b[3] = (uint8)(u32Addr >> 8);
b[4] = (uint8)(u32Addr);
b[5] = 0x04;
rsz = 4;
strI2c.u16Sz = 6;
}
strI2c.pu8Buf = b;
if(M2M_SUCCESS == nm_bus_ioctl(NM_BUS_IOCTL_W, &strI2c))
{
strI2c.u16Sz = rsz;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strI2c))
{
//M2M_ERR("read error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
else
{
M2M_ERR("failed to send cfg bytes\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
if (rsz == 1) {
*pu32RetVal = b[0];
} else {
*pu32RetVal = b[0] | ((uint32)b[1] << 8) | ((uint32)b[2] << 16) | ((uint32)b[3] << 24);
}
return s8Ret;
}
/*
* @fn nm_i2c_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
uint32 nm_i2c_read_reg(uint32 u32Addr)
{
uint32 val;
nm_i2c_read_reg_with_ret(u32Addr, &val);
return val;
}
/*
* @fn nm_i2c_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_i2c_write_reg(uint32 u32Addr, uint32 u32Val)
{
tstrNmI2cDefault strI2c;
uint8 b[16];
sint8 s8Ret = M2M_SUCCESS;
if(u32Addr < 0xff) { /* clockless i2c */
b[0] = 0x19;
b[1] = (uint8)(u32Addr);
b[2] = (uint8)(u32Val);
strI2c.u16Sz = 3;
} else {
b[0] = 0x90;
b[1] = (uint8)(u32Addr >> 24);
b[2] = (uint8)(u32Addr >> 16);
b[3] = (uint8)(u32Addr >> 8);
b[4] = (uint8)u32Addr;
b[5] = 0x04;
b[6] = (uint8)u32Val;
b[7] = (uint8)(u32Val >> 8);
b[8] = (uint8)(u32Val >> 16);
b[9] = (uint8)(u32Val >> 24);
strI2c.u16Sz = 10;
}
strI2c.pu8Buf = b;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strI2c))
{
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
return s8Ret;
}
/*
* @fn nm_i2c_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u16Sz
* Number of bytes to read. The buffer size must be >= u16Sz
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_i2c_read_block(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz)
{
tstrNmI2cDefault strI2c;
uint8 au8Buf[7];
sint8 s8Ret = M2M_SUCCESS;
au8Buf[0] = 0x02;
au8Buf[1] = (uint8)(u32Addr >> 24);
au8Buf[2] = (uint8)(u32Addr >> 16);
au8Buf[3] = (uint8)(u32Addr >> 8);
au8Buf[4] = (uint8)(u32Addr >> 0);
au8Buf[5] = (uint8)(u16Sz >> 8);
au8Buf[6] = (uint8)(u16Sz);
strI2c.pu8Buf = au8Buf;
strI2c.u16Sz = sizeof(au8Buf);
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strI2c))
{
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
else
{
strI2c.pu8Buf = pu8Buf;
strI2c.u16Sz = u16Sz;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strI2c))
{
M2M_ERR("read error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
return s8Ret;
}
/*
* @fn nm_i2c_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u16Sz
* Number of bytes to write. The buffer size must be >= u16Sz
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_i2c_write_block(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz)
{
uint8 au8Buf[7];
tstrNmI2cSpecial strI2c;
sint8 s8Ret = M2M_SUCCESS;
au8Buf[0] = 0x12;
au8Buf[1] = (uint8)(u32Addr >> 24);
au8Buf[2] = (uint8)(u32Addr >> 16);
au8Buf[3] = (uint8)(u32Addr >> 8);
au8Buf[4] = (uint8)(u32Addr);
au8Buf[5] = (uint8)(u16Sz >> 8);
au8Buf[6] = (uint8)(u16Sz);
strI2c.pu8Buf1 = au8Buf;
strI2c.pu8Buf2 = pu8Buf;
strI2c.u16Sz1 = sizeof(au8Buf);
strI2c.u16Sz2 = u16Sz;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W_SPECIAL, &strI2c))
{
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
return s8Ret;
}
#endif
/* EOF */

900
src/winc1500/src/nmspi.c Normal file
View File

@ -0,0 +1,900 @@
/**
*
* \file
*
* \brief This module contains NMC1000 SPI protocol bus APIs implementation.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "common/include/nm_common.h"
#ifdef CONF_WINC_USE_SPI
#define USE_OLD_SPI_SW
#include "bus_wrapper/include/nm_bus_wrapper.h"
#include "driver/include/nmspi.h"
#define NMI_PERIPH_REG_BASE 0x1000
#define NMI_INTR_REG_BASE (NMI_PERIPH_REG_BASE+0xa00)
#define NMI_CHIPID (NMI_PERIPH_REG_BASE)
#define NMI_PIN_MUX_0 (NMI_PERIPH_REG_BASE + 0x408)
#define NMI_INTR_ENABLE (NMI_INTR_REG_BASE)
#define NMI_SPI_REG_BASE 0xe800
#define NMI_SPI_CTL (NMI_SPI_REG_BASE)
#define NMI_SPI_MASTER_DMA_ADDR (NMI_SPI_REG_BASE+0x4)
#define NMI_SPI_MASTER_DMA_COUNT (NMI_SPI_REG_BASE+0x8)
#define NMI_SPI_SLAVE_DMA_ADDR (NMI_SPI_REG_BASE+0xc)
#define NMI_SPI_SLAVE_DMA_COUNT (NMI_SPI_REG_BASE+0x10)
#define NMI_SPI_TX_MODE (NMI_SPI_REG_BASE+0x20)
#define NMI_SPI_PROTOCOL_CONFIG (NMI_SPI_REG_BASE+0x24)
#define NMI_SPI_INTR_CTL (NMI_SPI_REG_BASE+0x2c)
#define NMI_SPI_PROTOCOL_OFFSET (NMI_SPI_PROTOCOL_CONFIG-NMI_SPI_REG_BASE)
#define SPI_BASE NMI_SPI_REG_BASE
#define CMD_DMA_WRITE 0xc1
#define CMD_DMA_READ 0xc2
#define CMD_INTERNAL_WRITE 0xc3
#define CMD_INTERNAL_READ 0xc4
#define CMD_TERMINATE 0xc5
#define CMD_REPEAT 0xc6
#define CMD_DMA_EXT_WRITE 0xc7
#define CMD_DMA_EXT_READ 0xc8
#define CMD_SINGLE_WRITE 0xc9
#define CMD_SINGLE_READ 0xca
#define CMD_RESET 0xcf
#define N_OK 1
#define N_FAIL 0
#define N_RESET -1
#define N_RETRY -2
#define DATA_PKT_SZ_256 256
#define DATA_PKT_SZ_512 512
#define DATA_PKT_SZ_1K 1024
#define DATA_PKT_SZ_4K (4 * 1024)
#define DATA_PKT_SZ_8K (8 * 1024)
#ifdef SAMG55
#define DATA_PKT_SZ DATA_PKT_SZ_1K
#else
#define DATA_PKT_SZ DATA_PKT_SZ_8K
#endif
static uint8 gu8Crc_off = 0;
static sint8 nmi_spi_read(uint8* b, uint16 sz)
{
tstrNmSpiRw spi;
spi.pu8InBuf = NULL;
spi.pu8OutBuf = b;
spi.u16Sz = sz;
return nm_bus_ioctl(NM_BUS_IOCTL_RW, &spi);
}
static sint8 nmi_spi_write(uint8* b, uint16 sz)
{
tstrNmSpiRw spi;
spi.pu8InBuf = b;
spi.pu8OutBuf = NULL;
spi.u16Sz = sz;
return nm_bus_ioctl(NM_BUS_IOCTL_RW, &spi);
}
/********************************************
Crc7
********************************************/
static const uint8 crc7_syndrome_table[256] = {
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26,
0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d,
0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14,
0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b,
0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42,
0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69,
0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70,
0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e,
0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67,
0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55,
0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a,
0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03,
0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28,
0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
};
static uint8 crc7_byte(uint8 crc, uint8 data)
{
return crc7_syndrome_table[(crc << 1) ^ data];
}
static uint8 crc7(uint8 crc, const uint8 *buffer, uint32 len)
{
while (len--)
crc = crc7_byte(crc, *buffer++);
return crc;
}
/********************************************
Spi protocol Function
********************************************/
#define CMD_DMA_WRITE 0xc1
#define CMD_DMA_READ 0xc2
#define CMD_INTERNAL_WRITE 0xc3
#define CMD_INTERNAL_READ 0xc4
#define CMD_TERMINATE 0xc5
#define CMD_REPEAT 0xc6
#define CMD_DMA_EXT_WRITE 0xc7
#define CMD_DMA_EXT_READ 0xc8
#define CMD_SINGLE_WRITE 0xc9
#define CMD_SINGLE_READ 0xca
#define CMD_RESET 0xcf
#define DATA_PKT_SZ_256 256
#define DATA_PKT_SZ_512 512
#define DATA_PKT_SZ_1K 1024
#define DATA_PKT_SZ_4K (4 * 1024)
#define DATA_PKT_SZ_8K (8 * 1024)
#define DATA_PKT_SZ DATA_PKT_SZ_8K
static sint8 spi_cmd(uint8 cmd, uint32 adr, uint32 u32data, uint32 sz,uint8 clockless)
{
uint8 bc[9];
uint8 len = 5;
sint8 result = N_OK;
bc[0] = cmd;
switch (cmd) {
case CMD_SINGLE_READ: /* single word (4 bytes) read */
bc[1] = (uint8)(adr >> 16);
bc[2] = (uint8)(adr >> 8);
bc[3] = (uint8)adr;
len = 5;
break;
case CMD_INTERNAL_READ: /* internal register read */
bc[1] = (uint8)(adr >> 8);
if(clockless) bc[1] |= (1 << 7);
bc[2] = (uint8)adr;
bc[3] = 0x00;
len = 5;
break;
case CMD_TERMINATE: /* termination */
bc[1] = 0x00;
bc[2] = 0x00;
bc[3] = 0x00;
len = 5;
break;
case CMD_REPEAT: /* repeat */
bc[1] = 0x00;
bc[2] = 0x00;
bc[3] = 0x00;
len = 5;
break;
case CMD_RESET: /* reset */
bc[1] = 0xff;
bc[2] = 0xff;
bc[3] = 0xff;
len = 5;
break;
case CMD_DMA_WRITE: /* dma write */
case CMD_DMA_READ: /* dma read */
bc[1] = (uint8)(adr >> 16);
bc[2] = (uint8)(adr >> 8);
bc[3] = (uint8)adr;
bc[4] = (uint8)(sz >> 8);
bc[5] = (uint8)(sz);
len = 7;
break;
case CMD_DMA_EXT_WRITE: /* dma extended write */
case CMD_DMA_EXT_READ: /* dma extended read */
bc[1] = (uint8)(adr >> 16);
bc[2] = (uint8)(adr >> 8);
bc[3] = (uint8)adr;
bc[4] = (uint8)(sz >> 16);
bc[5] = (uint8)(sz >> 8);
bc[6] = (uint8)(sz);
len = 8;
break;
case CMD_INTERNAL_WRITE: /* internal register write */
bc[1] = (uint8)(adr >> 8);
if(clockless) bc[1] |= (1 << 7);
bc[2] = (uint8)(adr);
bc[3] = (uint8)(u32data >> 24);
bc[4] = (uint8)(u32data >> 16);
bc[5] = (uint8)(u32data >> 8);
bc[6] = (uint8)(u32data);
len = 8;
break;
case CMD_SINGLE_WRITE: /* single word write */
bc[1] = (uint8)(adr >> 16);
bc[2] = (uint8)(adr >> 8);
bc[3] = (uint8)(adr);
bc[4] = (uint8)(u32data >> 24);
bc[5] = (uint8)(u32data >> 16);
bc[6] = (uint8)(u32data >> 8);
bc[7] = (uint8)(u32data);
len = 9;
break;
default:
result = N_FAIL;
break;
}
if (result) {
if (!gu8Crc_off)
bc[len-1] = (crc7(0x7f, (const uint8 *)&bc[0], len-1)) << 1;
else
len-=1;
if (M2M_SUCCESS != nmi_spi_write(bc, len)) {
M2M_ERR("[nmi spi]: Failed cmd write, bus error...\n");
result = N_FAIL;
}
}
return result;
}
static sint8 spi_cmd_rsp(uint8 cmd)
{
uint8 rsp;
sint8 result = N_OK;
sint8 s8RetryCnt;
/**
Command/Control response
**/
if ((cmd == CMD_RESET) ||
(cmd == CMD_TERMINATE) ||
(cmd == CMD_REPEAT)) {
if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
result = N_FAIL;
goto _fail_;
}
}
/* wait for response */
s8RetryCnt = 10;
do
{
if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
M2M_ERR("[nmi spi]: Failed cmd response read, bus error...\n");
result = N_FAIL;
goto _fail_;
}
} while((rsp != cmd) && (s8RetryCnt-- >0));
/**
State response
**/
/* wait for response */
s8RetryCnt = 10;
do
{
if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
M2M_ERR("[nmi spi]: Failed cmd response read, bus error...\n");
result = N_FAIL;
goto _fail_;
}
} while((rsp != 0x00) && (s8RetryCnt-- >0));
_fail_:
return result;
}
static sint8 spi_data_read(uint8 *b, uint16 sz,uint8 clockless)
{
sint16 retry, ix, nbytes;
sint8 result = N_OK;
uint8 crc[2];
uint8 rsp;
/**
Data
**/
ix = 0;
do {
if (sz <= DATA_PKT_SZ)
nbytes = sz;
else
nbytes = DATA_PKT_SZ;
/**
Data Respnose header
**/
retry = 10;
do {
if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
M2M_ERR("[nmi spi]: Failed data response read, bus error...\n");
result = N_FAIL;
break;
}
if (((rsp >> 4) & 0xf) == 0xf)
break;
} while (retry--);
if (result == N_FAIL)
break;
if (retry <= 0) {
M2M_ERR("[nmi spi]: Failed data response read...(%02x)\n", rsp);
result = N_FAIL;
break;
}
/**
Read bytes
**/
if (M2M_SUCCESS != nmi_spi_read(&b[ix], nbytes)) {
M2M_ERR("[nmi spi]: Failed data block read, bus error...\n");
result = N_FAIL;
break;
}
if(!clockless)
{
/**
Read Crc
**/
if (!gu8Crc_off) {
if (M2M_SUCCESS != nmi_spi_read(crc, 2)) {
M2M_ERR("[nmi spi]: Failed data block crc read, bus error...\n");
result = N_FAIL;
break;
}
}
}
ix += nbytes;
sz -= nbytes;
} while (sz);
return result;
}
static sint8 spi_data_write(uint8 *b, uint16 sz)
{
sint16 ix;
uint16 nbytes;
sint8 result = 1;
uint8 cmd, order, crc[2] = {0};
//uint8 rsp;
/**
Data
**/
ix = 0;
do {
if (sz <= DATA_PKT_SZ)
nbytes = sz;
else
nbytes = DATA_PKT_SZ;
/**
Write command
**/
cmd = 0xf0;
if (ix == 0) {
if (sz <= DATA_PKT_SZ)
order = 0x3;
else
order = 0x1;
} else {
if (sz <= DATA_PKT_SZ)
order = 0x3;
else
order = 0x2;
}
cmd |= order;
if (M2M_SUCCESS != nmi_spi_write(&cmd, 1)) {
M2M_ERR("[nmi spi]: Failed data block cmd write, bus error...\n");
result = N_FAIL;
break;
}
/**
Write data
**/
if (M2M_SUCCESS != nmi_spi_write(&b[ix], nbytes)) {
M2M_ERR("[nmi spi]: Failed data block write, bus error...\n");
result = N_FAIL;
break;
}
/**
Write Crc
**/
if (!gu8Crc_off) {
if (M2M_SUCCESS != nmi_spi_write(crc, 2)) {
M2M_ERR("[nmi spi]: Failed data block crc write, bus error...\n");
result = N_FAIL;
break;
}
}
ix += nbytes;
sz -= nbytes;
} while (sz);
return result;
}
/********************************************
Spi Internal Read/Write Function
********************************************/
/********************************************
Spi interfaces
********************************************/
static sint8 spi_write_reg(uint32 addr, uint32 u32data)
{
sint8 result = N_OK;
uint8 cmd = CMD_SINGLE_WRITE;
uint8 clockless = 0;
if (addr <= 0x30)
{
/**
NMC1000 clockless registers.
**/
cmd = CMD_INTERNAL_WRITE;
clockless = 1;
}
else
{
cmd = CMD_SINGLE_WRITE;
clockless = 0;
}
#if defined USE_OLD_SPI_SW
result = spi_cmd(cmd, addr, u32data, 4, clockless);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed cmd, write reg (%08x)...\n", (unsigned int)addr);
return N_FAIL;
}
result = spi_cmd_rsp(cmd);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed cmd response, write reg (%08x)...\n", (unsigned int)addr);
spi_cmd(CMD_RESET, 0, 0, 0, 0);
return N_FAIL;
}
return N_OK;
#else
result = spi_cmd_complete(cmd, addr, (uint8*)&u32data, 4, clockless);
if (result != N_OK) {
M2M_ERR( "[nmi spi]: Failed cmd, write reg (%08x)...\n", addr);
}
return result;
#endif
}
static sint8 nm_spi_write(uint32 addr, uint8 *buf, uint16 size)
{
sint8 result;
uint8 cmd = CMD_DMA_EXT_WRITE;
/**
Command
**/
#if defined USE_OLD_SPI_SW
result = spi_cmd(cmd, addr, 0, size,0);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed cmd, write block (%08x)...\n", (unsigned int)addr);
return N_FAIL;
}
result = spi_cmd_rsp(cmd);
if (result != N_OK) {
M2M_ERR("[nmi spi ]: Failed cmd response, write block (%08x)...\n", (unsigned int)addr);
spi_cmd(CMD_RESET, 0, 0, 0, 0);
return N_FAIL;
}
#else
result = spi_cmd_complete(cmd, addr, NULL, size, 0);
if (result != N_OK) {
M2M_ERR( "[nmi spi]: Failed cmd, write block (%08x)...\n", addr);
return N_FAIL;
}
#endif
/**
Data
**/
result = spi_data_write(buf, size);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed block data write...\n");
spi_cmd(CMD_RESET, 0, 0, 0, 0);
}
return N_OK;
}
static sint8 spi_read_reg(uint32 addr, uint32 *u32data)
{
sint8 result = N_OK;
uint8 cmd = CMD_SINGLE_READ;
uint8 tmp[4];
uint8 clockless = 0;
if (addr <= 0xff)
{
/**
NMC1000 clockless registers.
**/
cmd = CMD_INTERNAL_READ;
clockless = 1;
}
else
{
cmd = CMD_SINGLE_READ;
clockless = 0;
}
#if defined USE_OLD_SPI_SW
result = spi_cmd(cmd, addr, 0, 4, clockless);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed cmd, read reg (%08x)...\n", (unsigned int)addr);
return N_FAIL;
}
result = spi_cmd_rsp(cmd);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed cmd response, read reg (%08x)...\n", (unsigned int)addr);
spi_cmd(CMD_RESET, 0, 0, 0, 0);
return N_FAIL;
}
/* to avoid endianess issues */
result = spi_data_read(&tmp[0], 4, clockless);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed data read...\n");
spi_cmd(CMD_RESET, 0, 0, 0, 0);
return N_FAIL;
}
#else
result = spi_cmd_complete(cmd, addr, (uint8*)&tmp[0], 4, clockless);
if (result != N_OK) {
M2M_ERR( "[nmi spi]: Failed cmd, read reg (%08x)...\n", addr);
return N_FAIL;
}
#endif
*u32data = tmp[0] |
((uint32)tmp[1] << 8) |
((uint32)tmp[2] << 16) |
((uint32)tmp[3] << 24);
return N_OK;
}
static sint8 nm_spi_read(uint32 addr, uint8 *buf, uint16 size)
{
uint8 cmd = CMD_DMA_EXT_READ;
sint8 result;
/**
Command
**/
#if defined USE_OLD_SPI_SW
result = spi_cmd(cmd, addr, 0, size,0);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed cmd, read block (%08x)...\n", (unsigned int)addr);
return N_FAIL;
}
result = spi_cmd_rsp(cmd);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed cmd response, read block (%08x)...\n", (unsigned int)addr);
spi_cmd(CMD_RESET, 0, 0, 0, 0);
return N_FAIL;
}
/**
Data
**/
result = spi_data_read(buf, size,0);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed block data read...\n");
spi_cmd(CMD_RESET, 0, 0, 0, 0);
return N_FAIL;
}
#else
result = spi_cmd_complete(cmd, addr, buf, size, 0);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed cmd, read block (%08x)...\n", addr);
return N_FAIL;
}
#endif
return N_OK;
}
/********************************************
Bus interfaces
********************************************/
static void spi_init_pkt_sz(void)
{
uint32 val32;
/* Make sure SPI max. packet size fits the defined DATA_PKT_SZ. */
val32 = nm_spi_read_reg(SPI_BASE+0x24);
val32 &= ~(0x7 << 4);
switch(DATA_PKT_SZ)
{
case 256: val32 |= (0 << 4); break;
case 512: val32 |= (1 << 4); break;
case 1024: val32 |= (2 << 4); break;
case 2048: val32 |= (3 << 4); break;
case 4096: val32 |= (4 << 4); break;
case 8192: val32 |= (5 << 4); break;
}
nm_spi_write_reg(SPI_BASE+0x24, val32);
}
/*
* @fn nm_spi_init
* @brief Initialize the SPI
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_spi_init(void)
{
uint32 chipid;
uint32 reg =0;
/**
configure protocol
**/
gu8Crc_off = 0;
// TODO: We can remove the CRC trials if there is a definite way to reset
// the SPI to it's initial value.
if (!spi_read_reg(NMI_SPI_PROTOCOL_CONFIG, &reg)) {
/* Read failed. Try with CRC off. This might happen when module
is removed but chip isn't reset*/
gu8Crc_off = 1;
M2M_ERR("[nmi spi]: Failed internal read protocol with CRC on, retyring with CRC off...\n");
if (!spi_read_reg(NMI_SPI_PROTOCOL_CONFIG, &reg)){
// Reaad failed with both CRC on and off, something went bad
M2M_ERR( "[nmi spi]: Failed internal read protocol...\n");
return 0;
}
}
if(gu8Crc_off == 0)
{
reg &= ~0xc; /* disable crc checking */
reg &= ~0x70;
reg |= (0x5 << 4);
if (!spi_write_reg(NMI_SPI_PROTOCOL_CONFIG, reg)) {
M2M_ERR( "[nmi spi]: Failed internal write protocol reg...\n");
return 0;
}
gu8Crc_off = 1;
}
/**
make sure can read back chip id correctly
**/
if (!spi_read_reg(0x1000, &chipid)) {
M2M_ERR("[nmi spi]: Fail cmd read chip id...\n");
return M2M_ERR_BUS_FAIL;
}
M2M_DBG("[nmi spi]: chipid (%08x)\n", (unsigned int)chipid);
spi_init_pkt_sz();
return M2M_SUCCESS;
}
/*
* @fn nm_spi_init
* @brief DeInitialize the SPI
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Samer Sarhan
* @date 27 Feb 2015
* @version 1.0
*/
sint8 nm_spi_deinit(void)
{
gu8Crc_off = 0;
return M2M_SUCCESS;
}
/*
* @fn nm_spi_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
uint32 nm_spi_read_reg(uint32 u32Addr)
{
uint32 u32Val;
spi_read_reg(u32Addr, &u32Val);
return u32Val;
}
/*
* @fn nm_spi_read_reg_with_ret
* @brief Read register with error code return
* @param [in] u32Addr
* Register address
* @param [out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_spi_read_reg_with_ret(uint32 u32Addr, uint32* pu32RetVal)
{
sint8 s8Ret;
s8Ret = spi_read_reg(u32Addr,pu32RetVal);
if(N_OK == s8Ret) s8Ret = M2M_SUCCESS;
else s8Ret = M2M_ERR_BUS_FAIL;
return s8Ret;
}
/*
* @fn nm_spi_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_spi_write_reg(uint32 u32Addr, uint32 u32Val)
{
sint8 s8Ret;
s8Ret = spi_write_reg(u32Addr, u32Val);
if(N_OK == s8Ret) s8Ret = M2M_SUCCESS;
else s8Ret = M2M_ERR_BUS_FAIL;
return s8Ret;
}
/*
* @fn nm_spi_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u16Sz
* Number of bytes to read. The buffer size must be >= u16Sz
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_spi_read_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz)
{
sint8 s8Ret;
s8Ret = nm_spi_read(u32Addr, puBuf, u16Sz);
if(N_OK == s8Ret) s8Ret = M2M_SUCCESS;
else s8Ret = M2M_ERR_BUS_FAIL;
return s8Ret;
}
/*
* @fn nm_spi_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u16Sz
* Number of bytes to write. The buffer size must be >= u16Sz
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_spi_write_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz)
{
sint8 s8Ret;
s8Ret = nm_spi_write(u32Addr, puBuf, u16Sz);
if(N_OK == s8Ret) s8Ret = M2M_SUCCESS;
else s8Ret = M2M_ERR_BUS_FAIL;
return s8Ret;
}
#endif

536
src/winc1500/src/nmuart.c Normal file
View File

@ -0,0 +1,536 @@
/**
*
* \file
*
* \brief This module contains NMC1000 UART protocol bus APIs implementation.
*
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "common/include/nm_common.h"
#ifdef CONF_WINC_USE_UART
#include "driver/include/nmuart.h"
#include "bus_wrapper/include/nm_bus_wrapper.h"
#define HDR_SZ 12
static uint8 get_cs(uint8* b, uint8 sz){
int i;
uint8 cs = 0;
for(i = 0; i < sz; i++)
cs ^= b[i];
return cs;
}
/*
* @fn nm_uart_sync_cmd
* @brief Check COM Port
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Dina El Sissy
* @date 13 AUG 2012
* @version 1.0
*/
sint8 nm_uart_sync_cmd(void)
{
tstrNmUartDefault strUart;
sint8 s8Ret = -1;
uint8 b [HDR_SZ+1];
uint8 rsz;
uint8 onchip = 0;
/*read reg*/
b[0] = 0x12;
rsz = 1;
strUart.pu8Buf = b;
strUart.u16Sz = 1;
if(M2M_SUCCESS == nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
{
strUart.u16Sz = rsz;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
{
s8Ret = M2M_ERR_BUS_FAIL;
}
}
else
{
M2M_ERR("failed to send cfg bytes\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
if (b[0] == 0x5a)
{
s8Ret = 0;
onchip = 1;
M2M_INFO("Built-in WINC1500 UART Found\n");
}
else if(b[0] == 0x5b)
{
s8Ret = 0;
onchip = 0;
M2M_INFO("WINC1500 Serial Bridge Found\n");
}
/*TODO: this should be the way we read the register since the cortus is little endian*/
/**pu32RetVal = b[0] | ((uint32)b[1] << 8) | ((uint32)b[2] << 16) | ((uint32)b[3] << 24);*/
if(s8Ret == M2M_SUCCESS)
s8Ret = (sint8)onchip;
return s8Ret;
}
sint8 nm_uart_read_reg_with_ret(uint32 u32Addr, uint32* pu32RetVal)
{
tstrNmUartDefault strUart;
sint8 s8Ret = M2M_SUCCESS;
uint8 b [HDR_SZ+1];
uint8 rsz;
/*read reg*/
b[0] = 0xa5;
b[1] = 0;
b[2] = 0;
b[3] = 0;
b[4] = 0;
b[5] = (uint8)(u32Addr & 0x000000ff);
b[6] = (uint8)((u32Addr & 0x0000ff00)>>8);
b[7] = (uint8)((u32Addr & 0x00ff0000)>>16);
b[8] = (uint8)((u32Addr & 0xff000000)>>24);
b[9] = 0;
b[10] = 0;
b[11] = 0;
b[12] = 0;
b[2] = get_cs(&b[1],HDR_SZ);
rsz = 4;
strUart.pu8Buf = b;
strUart.u16Sz = sizeof(b);
if(M2M_SUCCESS == nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
{
if(!nm_bus_get_chip_type())
{
strUart.u16Sz = 1;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
{
s8Ret = M2M_ERR_BUS_FAIL;
}
if(b[0] == 0xAC)
{
M2M_DBG("Successfully sent the command\n");
strUart.u16Sz = rsz;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
{
s8Ret = M2M_ERR_BUS_FAIL;
}
}
else
{
s8Ret = M2M_ERR_BUS_FAIL;
}
}
else
{
strUart.u16Sz = rsz;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
{
s8Ret = M2M_ERR_BUS_FAIL;
}
}
}
else
{
M2M_ERR("failed to send cfg bytes\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
/*TODO: this should be the way we read the register since the cortus is little endian*/
/**pu32RetVal = b[0] | ((uint32)b[1] << 8) | ((uint32)b[2] << 16) | ((uint32)b[3] << 24);*/
*pu32RetVal = ((uint32)b[0] << 24) | ((uint32)b[1] << 16) | ((uint32)b[2] << 8) | b[3];
return s8Ret;
}
/*
* @fn nm_uart_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
* @author Dina El Sissy
* @date 13 AUG 2012
* @version 1.0
*/
uint32 nm_uart_read_reg(uint32 u32Addr)
{
uint32 val;
nm_uart_read_reg_with_ret(u32Addr , &val);
return val;
}
/*
* @fn nm_uart_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Dina El Sissy
* @date 13 AUG 2012
* @version 1.0
*/
sint8 nm_uart_write_reg(uint32 u32Addr, uint32 u32Val)
{
tstrNmUartDefault strUart;
sint8 s8Ret = M2M_SUCCESS;
uint8 b[HDR_SZ+1];
/*write reg*/
b[0] = 0xa5;
b[1] = 1;
b[2] = 0;
b[3] = 0;
b[4] = 0;
b[5] = (uint8)(u32Addr & 0x000000ff);
b[6] = (uint8)((u32Addr & 0x0000ff00)>>8);
b[7] = (uint8)((u32Addr & 0x00ff0000)>>16);
b[8] = (uint8)((u32Addr & 0xff000000)>>24);
b[9] = (uint8)(u32Val & 0x000000ff);
b[10] = (uint8)((u32Val & 0x0000ff00)>>8);
b[11] = (uint8)((u32Val & 0x00ff0000)>>16);
b[12] = (uint8)((u32Val & 0xff000000)>>24);
b[2] = get_cs(&b[1],HDR_SZ);
get_cs(&b[1],HDR_SZ);
strUart.pu8Buf = b;
strUart.u16Sz = sizeof(b);
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
{
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
else
{
if(!nm_bus_get_chip_type())
{
//check for the ack from the SAMD21 for the packet reception.
strUart.u16Sz = 1;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
{
s8Ret = M2M_ERR_BUS_FAIL;
}
if(b[0] == 0xAC)
{
M2M_DBG("Successfully sent the reg write command\n");
}
else
{
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
}
return s8Ret;
}
/**
* @fn nm_uart_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u16Sz
* Number of bytes to read. The buffer size must be >= u16Sz
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Dina El Sissy
* @date 13 AUG 2012
* @version 1.0
*/
sint8 nm_uart_read_block(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz)
{
tstrNmUartDefault strUart;
sint8 s8Ret = M2M_SUCCESS;
uint8 au8Buf[HDR_SZ+1];
au8Buf[0] = 0xa5;
au8Buf[1] = 2;
au8Buf[2] = 0;
au8Buf[3] = (uint8)(u16Sz & 0x00ff);
au8Buf[4] = (uint8)((u16Sz & 0xff00)>>8);
au8Buf[5] = (uint8)(u32Addr & 0x000000ff);
au8Buf[6] = (uint8)((u32Addr & 0x0000ff00)>>8);
au8Buf[7] = (uint8)((u32Addr & 0x00ff0000)>>16);
au8Buf[8] = (uint8)((u32Addr & 0xff000000)>>24);
au8Buf[9] = 0;
au8Buf[10] = 0;
au8Buf[11] = 0;
au8Buf[12] = 0;
au8Buf[2] = get_cs(&au8Buf[1],HDR_SZ);
strUart.pu8Buf = au8Buf;
strUart.u16Sz = sizeof(au8Buf);
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
{
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
else
{
if(!nm_bus_get_chip_type())
{
//check for the ack from the SAMD21 for the packet reception.
strUart.u16Sz = 1;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
{
s8Ret = M2M_ERR_BUS_FAIL;
}
if(au8Buf[0] == 0xAC)
{
M2M_DBG("Successfully sent the block read command\n");
strUart.pu8Buf = pu8Buf;
strUart.u16Sz = u16Sz;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
{
M2M_ERR("read error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
else
{
M2M_ERR("write error (Error sending the block read command)\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
else
{
strUart.pu8Buf = pu8Buf;
strUart.u16Sz = u16Sz;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
{
M2M_ERR("read error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
}
return s8Ret;
}
/**
* @fn nm_uart_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u16Sz
* Number of bytes to write. The buffer size must be >= u16Sz
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Dina El Sissy
* @date 13 AUG 2012
* @version 1.0
*/
sint8 nm_uart_write_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz)
{
tstrNmUartDefault strUart;
sint8 s8Ret = M2M_SUCCESS;
static uint8 au8Buf[HDR_SZ+1];
au8Buf[0] = 0xa5;
au8Buf[1] = 3;
au8Buf[2] = 0;
au8Buf[3] = (uint8)(u16Sz & 0x00ff);
au8Buf[4] = (uint8)((u16Sz & 0xff00)>>8);
au8Buf[5] = (uint8)(u32Addr & 0x000000ff);
au8Buf[6] = (uint8)((u32Addr & 0x0000ff00)>>8);
au8Buf[7] = (uint8)((u32Addr & 0x00ff0000)>>16);
au8Buf[8] = (uint8)((u32Addr & 0xff000000)>>24);
au8Buf[9] = 0;
au8Buf[10] = 0;
au8Buf[11] = 0;
au8Buf[12] = 0;
au8Buf[2] = get_cs(&au8Buf[1],HDR_SZ);
strUart.pu8Buf = au8Buf;
strUart.u16Sz = sizeof(au8Buf);
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
{
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
else
{
if(!nm_bus_get_chip_type())
{
//check for the ack from the SAMD21 for the packet reception.
strUart.u16Sz = 1;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
{
s8Ret = M2M_ERR_BUS_FAIL;
}
if(au8Buf[0] == 0xAC)
{
M2M_DBG("Successfully sent the block Write command\n");
strUart.pu8Buf = puBuf;
strUart.u16Sz = u16Sz;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
{
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
else
{
//check for the ack from the SAMD21 for the payload reception.
strUart.pu8Buf = au8Buf;
strUart.u16Sz = 1;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
{
s8Ret = M2M_ERR_BUS_FAIL;
}
if(au8Buf[0] == 0xAC)
{
M2M_DBG("Successfully sent the data payload\n");
}
else
{
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
}
else
{
M2M_ERR("write error (Error sending the block write command)\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
else
{
strUart.pu8Buf = puBuf;
strUart.u16Sz = u16Sz;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
{
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
}
return s8Ret;
}
/**
* @fn nm_uart_reconfigure
* @brief Reconfigures the UART interface
* @param [in] ptr
* Pointer to a DWORD containing baudrate at this moment.
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Viswanathan Murugesan
* @date 22 OCT 2014
* @version 1.0
*/
sint8 nm_uart_reconfigure(void *ptr)
{
tstrNmUartDefault strUart;
sint8 s8Ret = M2M_SUCCESS;
uint8 b[HDR_SZ+1];
/*write reg*/
b[0] = 0xa5;
b[1] = 5;
b[2] = 0;
b[3] = 0;
b[4] = 0;
b[5] = 0;
b[6] = 0;
b[7] = 0;
b[8] = 0;
b[9] = (uint8)((*(unsigned long *)ptr) & 0x000000ff);
b[10] = (uint8)(((*(unsigned long *)ptr) & 0x0000ff00)>>8);
b[11] = (uint8)(((*(unsigned long *)ptr) & 0x00ff0000)>>16);
b[12] = (uint8)(((*(unsigned long *)ptr) & 0xff000000)>>24);
b[2] = get_cs(&b[1],HDR_SZ);
get_cs(&b[1],HDR_SZ);
strUart.pu8Buf = b;
strUart.u16Sz = sizeof(b);
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart))
{
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
else
{
if(!nm_bus_get_chip_type())
{
//check for the ack from the SAMD21 for the packet reception.
strUart.u16Sz = 1;
if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
{
s8Ret = M2M_ERR_BUS_FAIL;
}
if(b[0] == 0xAC)
{
M2M_DBG("Successfully sent the UART reconfigure command\n");
}
else
{
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
}
return s8Ret;
}
#endif
/* EOF */

1224
src/winc1500/src/socket.c Normal file

File diff suppressed because it is too large Load Diff