atwinc1500

This commit is contained in:
Matthew Kennedy 2024-03-01 15:37:55 -05:00 committed by rusefi
parent b684315f6d
commit 8ad1285b48
75 changed files with 31730 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,31 @@
ATWINC_DIR = $(PROJECT_DIR)/ext/atwinc1500
ALLINC += \
$(ATWINC_DIR)
# $(ATWINC_DIR)/bsp/include \
# $(ATWINC_DIR)/bus_wrapper/include \
# $(ATWINC_DIR)/common/include \
# $(ATWINC_DIR)/driver/include \
# $(ATWINC_DIR)/common/include \
ALLCPPSRC += \
$(ATWINC_DIR)/common/source/nm_common.cpp \
$(ATWINC_DIR)/driver/source/m2m_ate_mode.cpp \
$(ATWINC_DIR)/driver/source/m2m_crypto.cpp \
$(ATWINC_DIR)/driver/source/m2m_hif.cpp \
$(ATWINC_DIR)/driver/source/m2m_ota.cpp \
$(ATWINC_DIR)/driver/source/m2m_periph.cpp \
$(ATWINC_DIR)/driver/source/m2m_wifi.cpp \
$(ATWINC_DIR)/driver/source/nmasic.cpp \
$(ATWINC_DIR)/driver/source/nmbus.cpp \
$(ATWINC_DIR)/driver/source/nmdrv.cpp \
$(ATWINC_DIR)/driver/source/nmi2c.cpp \
$(ATWINC_DIR)/driver/source/nmspi.cpp \
$(ATWINC_DIR)/driver/source/nmuart.cpp \
$(ATWINC_DIR)/socket/source/socket.cpp \
$(ATWINC_DIR)/spi_flash/source/spi_flash.cpp \
#$(ATWINC_DIR)/driver/source/m2m_ssl.c

View File

@ -0,0 +1,317 @@
/**
*
* \file
*
* \brief WINC BSP API Declarations.
*
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
/** @defgroup nm_bsp BSP
@brief
Description of the BSP (<strong>B</strong>oard <strong>S</strong>upport <strong>P</strong>ackage) module.
@{
@defgroup DataT Data Types
@defgroup BSPDefine Defines
@defgroup BSPAPI Functions
@brief
Lists the available BSP (<strong>B</strong>oard <strong>S</strong>upport <strong>P</strong>ackage) APIs.
@}
*/
/**@addtogroup BSPDefine
@{
*/
#ifndef _NM_BSP_H_
#define _NM_BSP_H_
#define NMI_API
/*!<
* Attribute used to define the memory section to map Functions in host memory.
*/
#define CONST const
/*!<
* Used for code portability.
*/
#ifndef NULL
#define NULL (nullptr)
#endif
/*!<
* Void Pointer to '0' in case NULL is not defined.
*/
#define BSP_MIN(x,y) ((x)>(y)?(y):(x))
/*!<
* Computes the minimum value between \b x and \b y.
*/
/**@}*/ //BSPDefine
/**@addtogroup DataT
* @{
*/
/*!
* @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);
/*!
* @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;
/**@}*/ //DataTypes
#ifndef CORTUS_APP
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup NmBspInitFn nm_bsp_init
* @ingroup BSPAPI
* Initialization for BSP (<strong>B</strong>oard <strong>S</strong>upport <strong>P</strong>ackage)
* such as Reset and Chip Enable Pins for WINC, delays, register ISR, enable/disable IRQ for WINC, etc.
* You must use this function at the head of your application to enable WINC and Host Driver to
* communicate with each other.
* @{
*/
/*!
* @fn sint8 nm_bsp_init(void);
* @brief This function is used to initialize the <strong>B</strong>oard <strong>S</strong>upport
* <strong>P</strong>ackage <strong>(BSP)</strong> in order to prepare the WINC before any
* WINC API calls.
* @details The nm_bsp_init function is the first function that should be called at the beginning of
* every application to initialize the BSP and the WINC board. Otherwise, the rest of the BSP
* function calls will return with failure. This function should also be called after the WINC
* has been switched off with a successful call to @ref nm_bsp_deinit in order to reinitialize
* the BSP before the Application can use any of the WINC APIs again. After the function
* initializes the WINC, a hard reset must be applied to start the WINC board by calling
* @ref nm_bsp_reset.
*
* @note Implementation of this function is host dependent.
* @warning Omitting this function will lead to unavailability of host-chip communication.
*
* @see nm_bsp_deinit, nm_bsp_reset
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
sint8 nm_bsp_init(void);
/**@}*/ //NmBspInitFn
/** @defgroup NmBspDeinitFn nm_bsp_deinit
* @ingroup BSPAPI
* De-initialization of the BSP (<strong>B</strong>oard <strong>S</strong>upport <strong>P</strong>ackage).\n
* This function should be called only after a successful call to @ref nm_bsp_init.
* @{
*/
/*!
* @fn sint8 nm_bsp_deinit(void);
* @brief This function is used to de-initialize the BSP and turn off the WINC board.
* @details The nm_bsp_deinit is the last function that should be called after the application has
* finished and before the WINC is switched off. A call to this function will turn off the WINC
* board by setting CHIP_EN and RESET_N signals low. Every function call of @ref nm_bsp_init
* should be matched with a call to nm_bsp_deinit. Failure to do so may result in the WINC
* consuming higher power than expected, since it won't be properly de-initialized.
* @pre The BSP should be initialized through @ref nm_bsp_init first.
* @note Implementation of this function is host dependent.
* @warning Omitting this function may lead to unknown behavior in case of soft reset.
* @see nm_bsp_init
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
sint8 nm_bsp_deinit(void);
/**@}*/ //NmBspDeinitFn
/** @defgroup NmBspResetFn nm_bsp_reset
* @ingroup BSPAPI
* Resets the WINC SoC by setting CHIP_EN and RESET_N signals low, then after an appropriate delay,
* this function will put CHIP_EN high then RESET_N high, for more details on the timing between signals
* please check the WINC data-sheet.
* @{
*/
/*!
* @fn void nm_bsp_reset(void);
* @brief Performs a hardware reset to the WINC board.
* @details The nm_bsp_reset is used to perform a hard reset on the WINC board by setting CHIP_EN and
* RESET_N signals low, then after an appropriate delay this function puts CHIP_EN high then
* RESET_N high, for more details on the timing between signals please check the WINC data-sheet.
* After a successful call, the WINC board firmware will kick off to load and start the WINC
* firmware. This function should be called to reset the WINC firmware after the BSP is
* initialized and before the start of any communication with WINC board. Calling this
* function at any other time will result in losing the state and connections saved in the
* WINC board and starting again from the initial state. The host driver will need to be
* de-initialized before calling nm_bsp_reset and initialized again, which can be achieved by
* use of @ref m2m_wifi_init and @ref m2m_wifi_deinit.
* @pre Initialize the BSP first by calling @ref nm_bsp_init.
* @note Implementation of this function is host dependent and called by HIF layer.
* @warning Calling this function will drop any connection and lose the internal state saved on the WINC firmware.
* @see nm_bsp_init, m2m_wifi_init, m2m_wifi_deinit
* @return None
*/
void nm_bsp_reset(void);
/**@}*/ //NmBspResetFn
/** @defgroup NmBspSleepFn nm_bsp_sleep
* @ingroup BSPAPI
* Sleep in units of milliseconds.\n
* This function used by the HIF Layer on several different scenarios.
* @{
*/
/*!
* @fn void nm_bsp_sleep(uint32 u32TimeMsec);
* @brief Used to put the host to sleep for the specified duration (in milliseconds).
* Forcing the host to sleep for extended period may lead to host not being able to respond
* to WINC board events. It is important to be considerate while choosing the sleep period.
* @param [in] u32TimeMsec
* Time unit in milliseconds.
* @pre Initialize @ref nm_bsp_init first.
* @note Implementation of this function is host dependent.
* @warning Maximum value must nor exceed 4294967295 milliseconds which is equal to 4294967.295 seconds.
* @see nm_bsp_init
* @return None
*/
void nm_bsp_sleep(uint32 u32TimeMsec);
/**@}*/ //NmBspSleepFn
/** @defgroup NmBspRegisterFn nm_bsp_register_isr
* @ingroup BSPAPI
* Register ISR (Interrupt Service Routine) in the initialization of the HIF (Host Interface) Layer.
* When the interrupt is triggered, the BSP layer should call the pfisr function from the interrupt handler.
* @{
*/
/*!
* @fn void nm_bsp_register_isr(tpfNmBspIsr pfIsr);
* @brief Register the host interface interrupt service routine.
* @details The WINC board uses the SPI interface to communicate with the host. This function registers
* the SPI interrupt to notify the host whenever there is an outstanding message from the WINC
* board. This function should be called during the initialization of the host interface. It is
* an internal driver function and shouldn't be called by the Application.
* @param [in] pfIsr
* Pointer to ISR handler in the HIF layer.
* @note Implementation of this function is host dependent and called by HIF layer.
* @warning Make sure that ISR for IRQ pin for WINC is disabled by default in your implementation.
* @see tpfNmBspIsr
* @return None
*/
void nm_bsp_register_isr(tpfNmBspIsr pfIsr);
/**@}*/ //NmBspRegisterFn
/** @defgroup NmBspInterruptCtrl nm_bsp_interrupt_ctrl
* @ingroup BSPAPI
* Synchronous enable/disable of WINC to host interrupts.
* @{
*/
/*!
* @fn void nm_bsp_interrupt_ctrl(uint8 u8Enable);
* @brief Enable/Disable interrupts from the WINC.
* @details This function can be used to enable/disable the WINC to host interrupts, depending on how
* the driver is implemented. It is an internal driver function and shouldn't be called by
* the application.
* @param [in] u8Enable
* - '0' disable interrupts.
* - '1' enable interrupts.
* @pre The interrupt must be registered using @ref nm_bsp_register_isr first.
* @note Implementation of this function is host dependent and called by HIF layer.
* @see tpfNmBspIsr, nm_bsp_register_isr
* @return None
*/
void nm_bsp_interrupt_ctrl(uint8 u8Enable);
/**@}*/ //NmBspInterruptCtrl
#ifdef __cplusplus
}
#endif
#endif
/**
* @addtogroup BSPDefine
* @{
*/
#ifdef _NM_BSP_BIG_END
/*! Switch endianness of 32bit word (In the case that Host is BE) */
#define NM_BSP_B_L_32(x) \
((((x) & 0x000000FF) << 24) + \
(((x) & 0x0000FF00) << 8) + \
(((x) & 0x00FF0000) >> 8) + \
(((x) & 0xFF000000) >> 24))
/*! Switch endianness of 16bit word (In the case that Host is BE) */
#define NM_BSP_B_L_16(x) \
((((x) & 0x00FF) << 8) + \
(((x) & 0xFF00) >> 8))
#else
/*! Retain endianness of 32bit word (In the case that Host is LE) */
#define NM_BSP_B_L_32(x) (x)
/*! Retain endianness of 16bit word (In the case that Host is LE) */
#define NM_BSP_B_L_16(x) (x)
#endif
/**@}*/ //BSPDefine
#endif /*_NM_BSP_H_*/

View File

@ -0,0 +1,136 @@
/**
*
* \file
*
* \brief This module contains NMC1500 BSP APIs declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
/**@defgroup BSPDefine Defines
* @ingroup nm_bsp
* @{
*/
#ifndef _NM_BSP_INTERNAL_H_
#define _NM_BSP_INTERNAL_H_
#include "loggingcentral.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 __SAMR21G18A__) || (defined __SAMR21E18A__)
#include "bsp/include/nm_bsp_samr21.h"
#endif
#if (defined __SAML21J18A__) || (defined __SAML21J18B__)
#include "bsp/include/nm_bsp_saml21.h"
#endif
#if (defined __SAML22N18A__)
#include "bsp/include/nm_bsp_saml22.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
#if (defined __SAME70Q21__) || (defined __SAME70Q21B__) || (defined __SAMV71Q21__)
#include "bsp/include/nm_bsp_same70.h"
#endif
#if (defined __SAMR30G18A__) || (defined __SAMR30E18A__)
#include "bsp/include/nm_bsp_samr30.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
#define NM_EDGE_INTERRUPT (1)
#define HIGH (1)
#define LOW (0)
#define CONF_WINC_USE_SPI (1)
#define CONF_WINC_DEBUG (1)
#define NM_DEBUG (1)
#define CONF_WINC_PRINTF(...) efiPrintf(__VA_ARGS__)
#endif //_NM_BSP_INTERNAL_H_

View File

@ -0,0 +1,46 @@
/**
*
* \file
*
* \brief This module contains SAM4S BSP APIs declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef _NM_BSP_SAM4S_H_
#define _NM_BSP_SAM4S_H_
#include "conf_winc.h"
#define NM_LEVEL_INTERRUPT (1)
#define NM_DEBUG CONF_WINC_DEBUG
#define NM_BSP_PRINTF CONF_WINC_PRINTF
#endif /* _NM_BSP_SAM4S_H_ */

View File

@ -0,0 +1,46 @@
/**
*
* \file
*
* \brief This module contains SAMD21 BSP APIs declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef _NM_BSP_SAMD21_H_
#define _NM_BSP_SAMD21_H_
#include "conf_winc.h"
#include "math.h"
#define NM_EDGE_INTERRUPT (1)
#define NM_DEBUG CONF_WINC_DEBUG
#define NM_BSP_PRINTF CONF_WINC_PRINTF
#endif /* _NM_BSP_SAMD21_H_ */

View File

@ -0,0 +1,45 @@
/**
*
* \file
*
* \brief This module contains SAME70 BSP APIs declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef _NM_BSP_SAME70_H_
#define _NM_BSP_SAME70_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_SAME70_H_ */

View File

@ -0,0 +1,46 @@
/**
*
* \file
*
* \brief This module contains SAMG53 BSP APIs declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef _NM_BSP_SAMG53_H_
#define _NM_BSP_SAMG53_H_
#include "conf_winc.h"
#define NM_LEVEL_INTERRUPT (1)
#define NM_DEBUG CONF_WINC_DEBUG
#define NM_BSP_PRINTF CONF_WINC_PRINTF
#endif /* _NM_BSP_SAMG53_H_ */

View File

@ -0,0 +1,46 @@
/**
*
* \file
*
* \brief This module contains SAMG55 BSP APIs declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef _NM_BSP_SAMG55_H_
#define _NM_BSP_SAMG55_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_SAMG55_H_ */

View File

@ -0,0 +1,45 @@
/**
*
* \file
*
* \brief This module contains SAML21 BSP APIs declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef _NM_BSP_SAML21_H_
#define _NM_BSP_SAML21_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_SAML21_H_ */

View File

@ -0,0 +1,45 @@
/**
*
* \file
*
* \brief This module contains SAML22 BSP APIs declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef _NM_BSP_SAML22_H_
#define _NM_BSP_SAML22_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_SAML22_H_ */

View File

@ -0,0 +1,45 @@
/**
*
* \file
*
* \brief This module contains SAMR21 BSP APIs declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef _NM_BSP_SAMR21_H_
#define _NM_BSP_SAMR21_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_SAMR21_H_ */

View File

@ -0,0 +1,45 @@
/**
*
* \file
*
* \brief This module contains SAML21 BSP APIs declarations.
*
* Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef _NM_BSP_SAMR30_H_
#define _NM_BSP_SAMR30_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_SAML30_H_ */

View File

@ -0,0 +1,172 @@
/**
*
* \file
*
* \brief This module contains SAM4S BSP APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_common.h"
#include "asf.h"
#include "conf_winc.h"
static tpfNmBspIsr gpfIsr;
static void chip_isr(uint32_t id, uint32_t mask)
{
if ((id == CONF_WINC_SPI_INT_PIO_ID) && (mask == CONF_WINC_SPI_INT_MASK)) {
if (gpfIsr) {
gpfIsr();
}
}
}
/**
* @fn nm_bsp_reset
* @brief Reset NMC1500 SoC by setting CHIP_EN and RESET_N signals low,
* CHIP_EN high then RESET_N high
*/
void nm_bsp_reset(void)
{
pio_set_pin_low(CONF_WINC_PIN_CHIP_ENABLE);
pio_set_pin_low(CONF_WINC_PIN_RESET);
nm_bsp_sleep(1);
pio_set_pin_high(CONF_WINC_PIN_CHIP_ENABLE);
nm_bsp_sleep(10);
pio_set_pin_high(CONF_WINC_PIN_RESET);
}
/*
* @fn init_chip_pins
* @brief Initialize reset, chip enable and wake pin
*/
static void init_chip_pins(void)
{
#ifdef __SAM4SD32C__
pio_configure_pin(CONF_WINC_PIN_RESET, PIO_TYPE_PIO_OUTPUT_0|PIO_PULLUP);
pio_configure_pin(CONF_WINC_PIN_CHIP_ENABLE, PIO_TYPE_PIO_OUTPUT_0|PIO_PULLUP);
pio_configure_pin(CONF_WINC_PIN_WAKE, PIO_TYPE_PIO_OUTPUT_0|PIO_PULLUP);
pio_configure_pin(CONF_WINC_SPI_CS_GPIO, PIO_DEFAULT|PIO_PULLUP);
pio_set_pin_high(CONF_WINC_SPI_CS_GPIO);
#else
pio_configure_pin(CONF_WINC_PIN_RESET, PIO_TYPE_PIO_OUTPUT_0);
pio_configure_pin(CONF_WINC_PIN_CHIP_ENABLE, PIO_TYPE_PIO_OUTPUT_0);
pio_configure_pin(CONF_WINC_PIN_WAKE, PIO_TYPE_PIO_OUTPUT_0);
#endif
}
/*
* @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;
/* Initialize chip IOs. */
init_chip_pins();
/* Make sure a 1ms Systick is configured. */
if (!(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk && SysTick->CTRL & SysTick_CTRL_TICKINT_Msk)) {
delay_init();
}
/* Perform chip reset. */
nm_bsp_reset();
return 0;
}
/**
* @fn nm_bsp_deinit
* @brief De-iInitialize BSP
* @return 0 in case of success and -1 in case of failure
*/
sint8 nm_bsp_deinit(void)
{
pio_set_pin_low(CONF_WINC_PIN_CHIP_ENABLE);
pio_set_pin_low(CONF_WINC_PIN_RESET);
return M2M_SUCCESS;
}
/*
* @fn nm_bsp_sleep
* @brief Sleep in units of mSec
* @param[IN] u32TimeMsec
* Time in milliseconds
*/
void nm_bsp_sleep(uint32 u32TimeMsec)
{
while(u32TimeMsec--) {
delay_ms(1);
}
}
/*
* @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;
/* Configure PGIO pin for interrupt from SPI slave, used when slave has data to send. */
sysclk_enable_peripheral_clock(CONF_WINC_SPI_INT_PIO_ID);
pio_configure_pin(CONF_WINC_SPI_INT_PIN, PIO_TYPE_PIO_INPUT);
pio_pull_up(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK, PIO_PULLUP);
// pio_set_debounce_filter(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK, 10);
pio_handler_set_pin(CONF_WINC_SPI_INT_PIN, PIO_IT_LOW_LEVEL, chip_isr);
pio_get_interrupt_status(CONF_WINC_SPI_INT_PIO);
pio_enable_interrupt(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK);
pio_handler_set_priority(CONF_WINC_SPI_INT_PIO, (IRQn_Type)CONF_WINC_SPI_INT_PIO_ID,
CONF_WINC_SPI_INT_PRIORITY);
}
/*
* @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) {
pio_get_interrupt_status(CONF_WINC_SPI_INT_PIO);
pio_enable_interrupt(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK);
}
else {
pio_disable_interrupt(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK);
}
}

View File

@ -0,0 +1,191 @@
/**
*
* \file
*
* \brief This module contains SAMD21 BSP APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "bsp/include/nm_bsp.h"
#include "bsp/include/nm_bsp_internal.h"
#include "common/include/nm_common.h"
#include "asf.h"
#include "conf_winc.h"
static tpfNmBspIsr gpfIsr;
static void chip_isr(void)
{
if (gpfIsr) {
gpfIsr();
}
}
/*
* @fn init_chip_pins
* @brief Initialize reset, chip enable and wake pin
*/
static void init_chip_pins(void)
{
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as output. */
pin_conf.direction = PORT_PIN_DIR_OUTPUT;
port_pin_set_config(CONF_WINC_PIN_RESET, &pin_conf);
port_pin_set_config(CONF_WINC_PIN_CHIP_ENABLE, &pin_conf);
port_pin_set_config(CONF_WINC_PIN_WAKE, &pin_conf);
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
}
/*
* @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;
/* Initialize chip IOs. */
init_chip_pins();
/* Make sure a 1ms Systick is configured. */
if (!(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk && SysTick->CTRL & SysTick_CTRL_TICKINT_Msk)) {
delay_init();
}
#if 0
/*For uart debug only*/
/* Perform chip reset. */
nm_bsp_reset();
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as input with pull up. */
pin_conf.direction = PORT_PIN_DIR_INPUT;
pin_conf.input_pull = PORT_PIN_PULL_UP;
port_pin_set_config(PIN_PA07, &pin_conf);
port_pin_set_config(PIN_PA04, &pin_conf);
port_pin_set_config(PIN_PA05, &pin_conf);
port_pin_set_config(PIN_PA06, &pin_conf);
while(1);
#endif
system_interrupt_enable_global();
return M2M_SUCCESS;
}
/**
* @fn nm_bsp_deinit
* @brief De-iInitialize BSP
* @return 0 in case of success and -1 in case of failure
*/
sint8 nm_bsp_deinit(void)
{
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as input no pull up. */
pin_conf.direction = PORT_PIN_DIR_INPUT;
pin_conf.input_pull = PORT_PIN_PULL_NONE;
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
port_pin_set_config(CONF_WINC_SPI_INT_PIN, &pin_conf);
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)
{
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
nm_bsp_sleep(1);
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, true);
nm_bsp_sleep(10);
port_pin_set_output_level(CONF_WINC_PIN_RESET, true);
}
/*
* @fn nm_bsp_sleep
* @brief Sleep in units of mSec
* @param[IN] u32TimeMsec
* Time in milliseconds
*/
void nm_bsp_sleep(uint32 u32TimeMsec)
{
while (u32TimeMsec--) {
delay_ms(1);
}
}
/*
* @fn nm_bsp_register_isr
* @brief Register interrupt service routine
* @param[IN] pfIsr
* Pointer to ISR handler
*/
void nm_bsp_register_isr(tpfNmBspIsr pfIsr)
{
struct extint_chan_conf config_extint_chan;
gpfIsr = pfIsr;
extint_chan_get_config_defaults(&config_extint_chan);
config_extint_chan.gpio_pin = CONF_WINC_SPI_INT_PIN;
config_extint_chan.gpio_pin_mux = CONF_WINC_SPI_INT_MUX;
config_extint_chan.gpio_pin_pull = EXTINT_PULL_UP;
config_extint_chan.detection_criteria = EXTINT_DETECT_FALLING;
extint_chan_set_config(CONF_WINC_SPI_INT_EIC, &config_extint_chan);
extint_register_callback(chip_isr, CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
extint_chan_enable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
}
/*
* @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_chan_enable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
} else {
extint_chan_disable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
}
}

View File

@ -0,0 +1,169 @@
/**
*
* \file
*
* \brief This module contains SAME70 BSP APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_common.h"
#include "asf.h"
#include "conf_winc.h"
static tpfNmBspIsr gpfIsr;
static void chip_isr(uint32_t id, uint32_t mask)
{
if ((id == CONF_WINC_SPI_INT_PIO_ID) && (mask == CONF_WINC_SPI_INT_MASK)) {
if (gpfIsr) {
gpfIsr();
}
}
}
/*
* @fn init_chip_pins
* @brief Initialize reset, chip enable and wake pin
*/
static void init_chip_pins(void)
{
ioport_init();
ioport_set_pin_dir(CONF_WINC_PIN_RESET, IOPORT_DIR_OUTPUT);
ioport_set_pin_level(CONF_WINC_PIN_RESET, IOPORT_PIN_LEVEL_HIGH);
ioport_set_pin_dir(CONF_WINC_PIN_CHIP_ENABLE, IOPORT_DIR_OUTPUT);
ioport_set_pin_level(CONF_WINC_PIN_CHIP_ENABLE, IOPORT_PIN_LEVEL_HIGH);
ioport_set_pin_dir(CONF_WINC_PIN_WAKE, IOPORT_DIR_OUTPUT);
ioport_set_pin_level(CONF_WINC_PIN_WAKE, IOPORT_PIN_LEVEL_HIGH);
}
/*
* @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;
/* Initialize chip IOs. */
init_chip_pins();
/* Make sure a 1ms Systick is configured. */
if (!(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk && SysTick->CTRL & SysTick_CTRL_TICKINT_Msk)) {
delay_init();
}
/* Perform chip reset. */
nm_bsp_reset();
return 0;
}
/**
* @fn nm_bsp_deinit
* @brief De-iInitialize BSP
* @return 0 in case of success and -1 in case of failure
*/
sint8 nm_bsp_deinit(void)
{
ioport_set_pin_level(CONF_WINC_PIN_CHIP_ENABLE, IOPORT_PIN_LEVEL_LOW);
ioport_set_pin_level(CONF_WINC_PIN_RESET, IOPORT_PIN_LEVEL_LOW);
return M2M_SUCCESS;
}
/**
* @fn nm_bsp_reset
* @brief Reset WINC1500 SoC by setting CHIP_EN and RESET_N signals low,
* CHIP_EN high then RESET_N high
*/
void nm_bsp_reset(void)
{
ioport_set_pin_level(CONF_WINC_PIN_CHIP_ENABLE, IOPORT_PIN_LEVEL_LOW);
ioport_set_pin_level(CONF_WINC_PIN_RESET, IOPORT_PIN_LEVEL_LOW);
nm_bsp_sleep(1);
ioport_set_pin_level(CONF_WINC_PIN_CHIP_ENABLE, IOPORT_PIN_LEVEL_HIGH);
nm_bsp_sleep(10);
ioport_set_pin_level(CONF_WINC_PIN_RESET, IOPORT_PIN_LEVEL_HIGH);
}
/*
* @fn nm_bsp_sleep
* @brief Sleep in units of mSec
* @param[IN] u32TimeMsec
* Time in milliseconds
*/
void nm_bsp_sleep(uint32 u32TimeMsec)
{
while(u32TimeMsec--) {
delay_ms(4);
}
}
/*
* @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;
/* Configure PGIO pin for interrupt from SPI slave, used when slave has data to send. */
pmc_enable_periph_clk(CONF_WINC_SPI_INT_PIO_ID);
pio_configure_pin(CONF_WINC_SPI_INT_PIN, PIO_TYPE_PIO_INPUT);
pio_pull_up(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK, PIO_PULLUP);
/*Interrupt on falling edge*/
pio_handler_set(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_PIO_ID,
CONF_WINC_SPI_INT_MASK, PIO_PULLUP | PIO_IT_FALL_EDGE, chip_isr);
pio_get_interrupt_status(CONF_WINC_SPI_INT_PIO);
pio_enable_interrupt(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK);
NVIC_EnableIRQ((IRQn_Type) CONF_WINC_SPI_INT_PIO_ID);
pio_handler_set_priority(CONF_WINC_SPI_INT_PIO, (IRQn_Type)CONF_WINC_SPI_INT_PIO_ID,
CONF_WINC_SPI_INT_PRIORITY);
}
/*
* @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) {
pio_get_interrupt_status(CONF_WINC_SPI_INT_PIO);
pio_enable_interrupt(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK);
}
else {
pio_disable_interrupt(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK);
}
}

View File

@ -0,0 +1,166 @@
/**
*
* \file
*
* \brief This module contains SAMG53 BSP APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_common.h"
#include "asf.h"
#include "conf_winc.h"
static tpfNmBspIsr gpfIsr;
static void chip_isr(uint32_t id, uint32_t mask)
{
if ((id == CONF_WINC_SPI_INT_PIO_ID) && (mask == CONF_WINC_SPI_INT_MASK)) {
if (gpfIsr) {
gpfIsr();
}
}
}
/*
* @fn init_chip_pins
* @brief Initialize reset, chip enable and wake pin
*/
static void init_chip_pins(void)
{
ioport_init();
ioport_set_pin_dir(CONF_WINC_PIN_RESET, IOPORT_DIR_OUTPUT);
ioport_set_pin_level(CONF_WINC_PIN_RESET, IOPORT_PIN_LEVEL_HIGH);
ioport_set_pin_dir(CONF_WINC_PIN_CHIP_ENABLE, IOPORT_DIR_OUTPUT);
ioport_set_pin_level(CONF_WINC_PIN_CHIP_ENABLE, IOPORT_PIN_LEVEL_HIGH);
}
/*
* @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;
/* Initialize chip IOs. */
init_chip_pins();
/* Make sure a 1ms Systick is configured. */
if (!(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk && SysTick->CTRL & SysTick_CTRL_TICKINT_Msk)) {
delay_init();
}
/* Perform chip reset. */
nm_bsp_reset();
return 0;
}
/**
* @fn nm_bsp_deinit
* @brief De-iInitialize BSP
* @return 0 in case of success and -1 in case of failure
*/
sint8 nm_bsp_deinit(void)
{
ioport_set_pin_level(CONF_WINC_PIN_CHIP_ENABLE, false);
ioport_set_pin_level(CONF_WINC_PIN_RESET, false);
return M2M_SUCCESS;
}
/**
* @fn nm_bsp_reset
* @brief Reset WINC1500 SoC by setting CHIP_EN and RESET_N signals low,
* CHIP_EN high then RESET_N high
*/
void nm_bsp_reset(void)
{
pio_set_pin_low(CONF_WINC_PIN_CHIP_ENABLE);
pio_set_pin_low(CONF_WINC_PIN_RESET);
nm_bsp_sleep(1);
pio_set_pin_high(CONF_WINC_PIN_CHIP_ENABLE);
nm_bsp_sleep(10);
pio_set_pin_high(CONF_WINC_PIN_RESET);
}
/*
* @fn nm_bsp_sleep
* @brief Sleep in units of mSec
* @param[IN] u32TimeMsec
* Time in milliseconds
*/
void nm_bsp_sleep(uint32 u32TimeMsec)
{
while(u32TimeMsec--) {
delay_ms(1);
}
}
/*
* @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;
/* Configure PGIO pin for interrupt from SPI slave, used when slave has data to send. */
sysclk_enable_peripheral_clock(CONF_WINC_SPI_INT_PIO_ID);
pio_configure_pin(CONF_WINC_SPI_INT_PIN, PIO_TYPE_PIO_INPUT);
pio_pull_up(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK, PIO_PULLUP);
// pio_set_debounce_filter(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK, 10);
pio_handler_set_pin(CONF_WINC_SPI_INT_PIN, PIO_IT_LOW_LEVEL, chip_isr);
pio_get_interrupt_status(CONF_WINC_SPI_INT_PIO);
pio_enable_interrupt(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK);
NVIC_EnableIRQ((IRQn_Type) CONF_WINC_SPI_INT_PIO_ID);
pio_handler_set_priority(CONF_WINC_SPI_INT_PIO, (IRQn_Type)CONF_WINC_SPI_INT_PIO_ID,
CONF_WINC_SPI_INT_PRIORITY);
}
/*
* @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) {
pio_get_interrupt_status(CONF_WINC_SPI_INT_PIO);
pio_enable_interrupt(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK);
}
else {
pio_disable_interrupt(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK);
}
}

View File

@ -0,0 +1,167 @@
/**
*
* \file
*
* \brief This module contains SAMG55 BSP APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_common.h"
#include "asf.h"
#include "conf_winc.h"
static tpfNmBspIsr gpfIsr;
static void chip_isr(uint32_t id, uint32_t mask)
{
if ((id == CONF_WINC_SPI_INT_PIO_ID) && (mask == CONF_WINC_SPI_INT_MASK)) {
if (gpfIsr) {
gpfIsr();
}
}
}
/*
* @fn init_chip_pins
* @brief Initialize reset, chip enable and wake pin
*/
static void init_chip_pins(void)
{
ioport_init();
ioport_set_pin_dir(CONF_WINC_PIN_RESET, IOPORT_DIR_OUTPUT);
ioport_set_pin_level(CONF_WINC_PIN_RESET, IOPORT_PIN_LEVEL_HIGH);
ioport_set_pin_dir(CONF_WINC_PIN_CHIP_ENABLE, IOPORT_DIR_OUTPUT);
ioport_set_pin_level(CONF_WINC_PIN_CHIP_ENABLE, IOPORT_PIN_LEVEL_HIGH);
}
/*
* @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;
/* Initialize chip IOs. */
init_chip_pins();
/* Make sure a 1ms Systick is configured. */
if (!(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk && SysTick->CTRL & SysTick_CTRL_TICKINT_Msk)) {
delay_init();
}
/* Perform chip reset. */
nm_bsp_reset();
return 0;
}
/**
* @fn nm_bsp_deinit
* @brief De-iInitialize BSP
* @return 0 in case of success and -1 in case of failure
*/
sint8 nm_bsp_deinit(void)
{
ioport_set_pin_level(CONF_WINC_PIN_CHIP_ENABLE, false);
ioport_set_pin_level(CONF_WINC_PIN_RESET, false);
return M2M_SUCCESS;
}
/**
* @fn nm_bsp_reset
* @brief Reset WINC1500 SoC by setting CHIP_EN and RESET_N signals low,
* CHIP_EN high then RESET_N high
*/
void nm_bsp_reset(void)
{
ioport_set_pin_level(CONF_WINC_PIN_CHIP_ENABLE, IOPORT_PIN_LEVEL_LOW);
ioport_set_pin_level(CONF_WINC_PIN_RESET, IOPORT_PIN_LEVEL_LOW);
nm_bsp_sleep(1);
ioport_set_pin_level(CONF_WINC_PIN_CHIP_ENABLE, IOPORT_PIN_LEVEL_HIGH);
nm_bsp_sleep(10);
ioport_set_pin_level(CONF_WINC_PIN_RESET, IOPORT_PIN_LEVEL_HIGH);
}
/*
* @fn nm_bsp_sleep
* @brief Sleep in units of mSec
* @param[IN] u32TimeMsec
* Time in milliseconds
*/
void nm_bsp_sleep(uint32 u32TimeMsec)
{
while(u32TimeMsec--) {
delay_ms(1);
}
}
/*
* @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;
/* Configure PGIO pin for interrupt from SPI slave, used when slave has data to send. */
pmc_enable_periph_clk(CONF_WINC_SPI_INT_PIO_ID);
pio_configure_pin(CONF_WINC_SPI_INT_PIN, PIO_TYPE_PIO_INPUT);
pio_pull_up(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK, PIO_PULLUP);
/*Interrupt on falling edge*/
pio_handler_set(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_PIO_ID,
CONF_WINC_SPI_INT_MASK, PIO_PULLUP | PIO_IT_FALL_EDGE, chip_isr);
pio_get_interrupt_status(CONF_WINC_SPI_INT_PIO);
pio_enable_interrupt(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK);
NVIC_EnableIRQ((IRQn_Type) CONF_WINC_SPI_INT_PIO_ID);
pio_handler_set_priority(CONF_WINC_SPI_INT_PIO, (IRQn_Type)CONF_WINC_SPI_INT_PIO_ID,
CONF_WINC_SPI_INT_PRIORITY);
}
/*
* @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) {
pio_get_interrupt_status(CONF_WINC_SPI_INT_PIO);
pio_enable_interrupt(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK);
}
else {
pio_disable_interrupt(CONF_WINC_SPI_INT_PIO, CONF_WINC_SPI_INT_MASK);
}
}

View File

@ -0,0 +1,179 @@
/**
*
* \file
*
* \brief This module contains SAML21 BSP APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_common.h"
#include "asf.h"
#include "conf_winc.h"
static tpfNmBspIsr gpfIsr;
static void chip_isr(void)
{
if (gpfIsr) {
gpfIsr();
}
}
/*
* @fn init_chip_pins
* @brief Initialize reset, chip enable and wake pin
*/
static void init_chip_pins(void)
{
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as output. */
pin_conf.direction = PORT_PIN_DIR_OUTPUT;
port_pin_set_config(CONF_WINC_PIN_RESET, &pin_conf);
port_pin_set_config(CONF_WINC_PIN_CHIP_ENABLE, &pin_conf);
port_pin_set_config(CONF_WINC_PIN_WAKE, &pin_conf);
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
}
/*
* @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;
/* Initialize chip IOs. */
init_chip_pins();
/* Make sure a 1ms Systick is configured. */
if (!(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk && SysTick->CTRL & SysTick_CTRL_TICKINT_Msk)) {
delay_init();
}
/* Perform chip reset. */
nm_bsp_reset();
system_interrupt_enable_global();
return M2M_SUCCESS;
}
/**
* @fn nm_bsp_deinit
* @brief De-iInitialize BSP
* @return 0 in case of success and -1 in case of failure
*/
sint8 nm_bsp_deinit(void)
{
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as input no pull up. */
pin_conf.direction = PORT_PIN_DIR_INPUT;
pin_conf.input_pull = PORT_PIN_PULL_NONE;
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
port_pin_set_config(CONF_WINC_SPI_INT_PIN, &pin_conf);
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)
{
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
nm_bsp_sleep(1);
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, true);
nm_bsp_sleep(10);
port_pin_set_output_level(CONF_WINC_PIN_RESET, true);
}
/*
* @fn nm_bsp_sleep
* @brief Sleep in units of mSec
* @param[IN] u32TimeMsec
* Time in milliseconds
*/
void nm_bsp_sleep(uint32 u32TimeMsec)
{
while (u32TimeMsec--) {
delay_ms(1);
}
}
/*
* @fn nm_bsp_register_isr
* @brief Register interrupt service routine
* @param[IN] pfIsr
* Pointer to ISR handler
*/
void nm_bsp_register_isr(tpfNmBspIsr pfIsr)
{
struct extint_chan_conf config_extint_chan;
gpfIsr = pfIsr;
extint_chan_get_config_defaults(&config_extint_chan);
config_extint_chan.gpio_pin = CONF_WINC_SPI_INT_PIN;
config_extint_chan.gpio_pin_mux = CONF_WINC_SPI_INT_MUX;
config_extint_chan.gpio_pin_pull = EXTINT_PULL_UP;
config_extint_chan.detection_criteria = EXTINT_DETECT_FALLING;
extint_chan_set_config(CONF_WINC_SPI_INT_EIC, &config_extint_chan);
extint_register_callback(chip_isr, CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
extint_chan_enable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
}
/*
* @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_chan_enable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
} else {
extint_chan_disable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
}
}

View File

@ -0,0 +1,179 @@
/**
*
* \file
*
* \brief This module contains SAML22 BSP APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_common.h"
#include "asf.h"
#include "conf_winc.h"
static tpfNmBspIsr gpfIsr;
static void chip_isr(void)
{
if (gpfIsr) {
gpfIsr();
}
}
/*
* @fn init_chip_pins
* @brief Initialize reset, chip enable and wake pin
*/
static void init_chip_pins(void)
{
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as output. */
pin_conf.direction = PORT_PIN_DIR_OUTPUT;
port_pin_set_config(CONF_WINC_PIN_RESET, &pin_conf);
port_pin_set_config(CONF_WINC_PIN_CHIP_ENABLE, &pin_conf);
port_pin_set_config(CONF_WINC_PIN_WAKE, &pin_conf);
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
}
/*
* @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;
/* Initialize chip IOs. */
init_chip_pins();
/* Make sure a 1ms Systick is configured. */
if (!(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk && SysTick->CTRL & SysTick_CTRL_TICKINT_Msk)) {
delay_init();
}
/* Perform chip reset. */
nm_bsp_reset();
system_interrupt_enable_global();
return M2M_SUCCESS;
}
/**
* @fn nm_bsp_deinit
* @brief De-iInitialize BSP
* @return 0 in case of success and -1 in case of failure
*/
sint8 nm_bsp_deinit(void)
{
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as input no pull up. */
pin_conf.direction = PORT_PIN_DIR_INPUT;
pin_conf.input_pull = PORT_PIN_PULL_NONE;
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
port_pin_set_config(CONF_WINC_SPI_INT_PIN, &pin_conf);
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)
{
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
nm_bsp_sleep(1);
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, true);
nm_bsp_sleep(10);
port_pin_set_output_level(CONF_WINC_PIN_RESET, true);
}
/*
* @fn nm_bsp_sleep
* @brief Sleep in units of mSec
* @param[IN] u32TimeMsec
* Time in milliseconds
*/
void nm_bsp_sleep(uint32 u32TimeMsec)
{
while (u32TimeMsec--) {
delay_ms(1);
}
}
/*
* @fn nm_bsp_register_isr
* @brief Register interrupt service routine
* @param[IN] pfIsr
* Pointer to ISR handler
*/
void nm_bsp_register_isr(tpfNmBspIsr pfIsr)
{
struct extint_chan_conf config_extint_chan;
gpfIsr = pfIsr;
extint_chan_get_config_defaults(&config_extint_chan);
config_extint_chan.gpio_pin = CONF_WINC_SPI_INT_PIN;
config_extint_chan.gpio_pin_mux = CONF_WINC_SPI_INT_MUX;
config_extint_chan.gpio_pin_pull = EXTINT_PULL_UP;
config_extint_chan.detection_criteria = EXTINT_DETECT_FALLING;
extint_chan_set_config(CONF_WINC_SPI_INT_EIC, &config_extint_chan);
extint_register_callback(chip_isr, CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
extint_chan_enable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
}
/*
* @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_chan_enable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
} else {
extint_chan_disable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
}
}

View File

@ -0,0 +1,179 @@
/**
*
* \file
*
* \brief This module contains SAMD21 BSP APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_common.h"
#include "asf.h"
#include "conf_winc.h"
static tpfNmBspIsr gpfIsr;
static void chip_isr(void)
{
if (gpfIsr) {
gpfIsr();
}
}
/*
* @fn init_chip_pins
* @brief Initialize reset, chip enable and wake pin
*/
static void init_chip_pins(void)
{
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as output. */
pin_conf.direction = PORT_PIN_DIR_OUTPUT;
port_pin_set_config(CONF_WINC_PIN_RESET, &pin_conf);
port_pin_set_config(CONF_WINC_PIN_CHIP_ENABLE, &pin_conf);
port_pin_set_config(CONF_WINC_PIN_WAKE, &pin_conf);
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
}
/*
* @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;
/* Initialize chip IOs. */
init_chip_pins();
/* Make sure a 1ms Systick is configured. */
if (!(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk && SysTick->CTRL & SysTick_CTRL_TICKINT_Msk)) {
delay_init();
}
/* Perform chip reset. */
nm_bsp_reset();
system_interrupt_enable_global();
return M2M_SUCCESS;
}
/**
* @fn nm_bsp_deinit
* @brief De-iInitialize BSP
* @return 0 in case of success and -1 in case of failure
*/
sint8 nm_bsp_deinit(void)
{
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as input no pull up. */
pin_conf.direction = PORT_PIN_DIR_INPUT;
pin_conf.input_pull = PORT_PIN_PULL_NONE;
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
port_pin_set_config(CONF_WINC_SPI_INT_PIN, &pin_conf);
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)
{
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
nm_bsp_sleep(1);
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, true);
nm_bsp_sleep(10);
port_pin_set_output_level(CONF_WINC_PIN_RESET, true);
}
/*
* @fn nm_bsp_sleep
* @brief Sleep in units of mSec
* @param[IN] u32TimeMsec
* Time in milliseconds
*/
void nm_bsp_sleep(uint32 u32TimeMsec)
{
while (u32TimeMsec--) {
delay_ms(1);
}
}
/*
* @fn nm_bsp_register_isr
* @brief Register interrupt service routine
* @param[IN] pfIsr
* Pointer to ISR handler
*/
void nm_bsp_register_isr(tpfNmBspIsr pfIsr)
{
struct extint_chan_conf config_extint_chan;
gpfIsr = pfIsr;
extint_chan_get_config_defaults(&config_extint_chan);
config_extint_chan.gpio_pin = CONF_WINC_SPI_INT_PIN;
config_extint_chan.gpio_pin_mux = CONF_WINC_SPI_INT_MUX;
config_extint_chan.gpio_pin_pull = EXTINT_PULL_UP;
config_extint_chan.detection_criteria = EXTINT_DETECT_FALLING;
extint_chan_set_config(CONF_WINC_SPI_INT_EIC, &config_extint_chan);
extint_register_callback(chip_isr, CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
extint_chan_enable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
}
/*
* @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_chan_enable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
} else {
extint_chan_disable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
}
}

View File

@ -0,0 +1,179 @@
/**
*
* \file
*
* \brief This module contains SAML21 BSP APIs implementation.
*
* Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_common.h"
#include "asf.h"
#include "conf_winc.h"
static tpfNmBspIsr gpfIsr;
static void chip_isr(void)
{
if (gpfIsr) {
gpfIsr();
}
}
/*
* @fn init_chip_pins
* @brief Initialize reset, chip enable and wake pin
*/
static void init_chip_pins(void)
{
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as output. */
pin_conf.direction = PORT_PIN_DIR_OUTPUT;
port_pin_set_config(CONF_WINC_PIN_RESET, &pin_conf);
port_pin_set_config(CONF_WINC_PIN_CHIP_ENABLE, &pin_conf);
port_pin_set_config(CONF_WINC_PIN_WAKE, &pin_conf);
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
}
/*
* @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;
/* Initialize chip IOs. */
init_chip_pins();
/* Make sure a 1ms Systick is configured. */
if (!(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk && SysTick->CTRL & SysTick_CTRL_TICKINT_Msk)) {
delay_init();
}
/* Perform chip reset. */
nm_bsp_reset();
system_interrupt_enable_global();
return M2M_SUCCESS;
}
/**
* @fn nm_bsp_deinit
* @brief De-iInitialize BSP
* @return 0 in case of success and -1 in case of failure
*/
sint8 nm_bsp_deinit(void)
{
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as input no pull up. */
pin_conf.direction = PORT_PIN_DIR_INPUT;
pin_conf.input_pull = PORT_PIN_PULL_NONE;
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
port_pin_set_config(CONF_WINC_SPI_INT_PIN, &pin_conf);
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)
{
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, false);
port_pin_set_output_level(CONF_WINC_PIN_RESET, false);
nm_bsp_sleep(1);
port_pin_set_output_level(CONF_WINC_PIN_CHIP_ENABLE, true);
nm_bsp_sleep(10);
port_pin_set_output_level(CONF_WINC_PIN_RESET, true);
}
/*
* @fn nm_bsp_sleep
* @brief Sleep in units of mSec
* @param[IN] u32TimeMsec
* Time in milliseconds
*/
void nm_bsp_sleep(uint32 u32TimeMsec)
{
while (u32TimeMsec--) {
delay_ms(1);
}
}
/*
* @fn nm_bsp_register_isr
* @brief Register interrupt service routine
* @param[IN] pfIsr
* Pointer to ISR handler
*/
void nm_bsp_register_isr(tpfNmBspIsr pfIsr)
{
struct extint_chan_conf config_extint_chan;
gpfIsr = pfIsr;
extint_chan_get_config_defaults(&config_extint_chan);
config_extint_chan.gpio_pin = CONF_WINC_SPI_INT_PIN;
config_extint_chan.gpio_pin_mux = CONF_WINC_SPI_INT_MUX;
config_extint_chan.gpio_pin_pull = EXTINT_PULL_UP;
config_extint_chan.detection_criteria = EXTINT_DETECT_FALLING;
extint_chan_set_config(CONF_WINC_SPI_INT_EIC, &config_extint_chan);
extint_register_callback(chip_isr, CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
extint_chan_enable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
}
/*
* @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_chan_enable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
} else {
extint_chan_disable_callback(CONF_WINC_SPI_INT_EIC,
EXTINT_CALLBACK_TYPE_DETECT);
}
}

View File

@ -0,0 +1,195 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus wrapper APIs declarations.
*
* Copyright (c) 2016-2022 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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);
sint8 nm_bus_break(void);
#endif
/**
* @fn nm_bus_speed
* @brief Either set the bus speed to default (HIGH) or a reduced speed (LOW)
to increase stability during WINC wakeup
* @param [in] uint8 level
* HIGH(1) or LOW(0)
* @return M2M_SUCCESS in case of success and M2M_ERR_INVALID_ARG in case of an
incorrect parameter
*/
sint8 nm_bus_speed(uint8 level);
/**
* @fn spi_rw
* @brief Process SPI Read/Write operation
* @param pu8Mosi TX Data buffer
* @param pu8Miso RX Data buffer
* @param u16Sz Transfer length
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
#ifdef CONF_WINC_USE_SPI
sint8 nm_spi_rw(uint8* pu8Mosi, uint8* pu8Miso, uint16 u16Sz);
#endif
#ifdef __cplusplus
}
#endif
#endif /*_NM_BUS_WRAPPER_H_*/

View File

@ -0,0 +1,340 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus wrapper APIs implementation.
*
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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 "asf.h"
#include "conf_winc.h"
#define xSPI_ASSERT_CS() {gpio_set_pin_low(CONF_WINC_SPI_CS_GPIO);}
#define xSPI_DEASSERT_CS() {gpio_set_pin_high(CONF_WINC_SPI_CS_GPIO);}
#define SPI_ASSERT_CS() do {p_pio->PIO_CODR = 1 << (CONF_WINC_SPI_CS_GPIO & 0x1F);}while(0)
#define SPI_DEASSERT_CS() do {p_pio->PIO_SODR = 1 << (CONF_WINC_SPI_CS_GPIO & 0x1F);}while(0)
#ifdef CONF_WINC_USE_SPI
/** Pointer to Pdc data structure. */
static Pdc *g_p_spim_pdc;
#endif
#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. */
Pio *p_pio;
sint8 nm_spi_rw(uint8* pu8Mosi, uint8* pu8Miso, uint16 u16Sz)
{
#ifdef DMA_SPI
pdc_packet_t pdc_spi_tx_packet,pdc_spi_rx_packet;
p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (CONF_WINC_SPI_CS_GPIO >> 5)));
pdc_spi_tx_packet.ul_addr = NULL;
pdc_spi_rx_packet.ul_addr = NULL;
pdc_spi_tx_packet.ul_size = u16Sz;
pdc_spi_rx_packet.ul_size = u16Sz;
if (pu8Mosi) {
pdc_spi_tx_packet.ul_addr = (uint32_t)pu8Mosi;
}
if(pu8Miso) {
pdc_spi_rx_packet.ul_addr = (uint32_t)pu8Miso;
}
pdc_tx_init(g_p_spim_pdc, &pdc_spi_tx_packet, NULL);
pdc_rx_init(g_p_spim_pdc, &pdc_spi_rx_packet, NULL);
/*Assert CS*/
SPI_ASSERT_CS();
/* Enable the RX and TX PDC transfer requests */
g_p_spim_pdc->PERIPH_PTCR = PERIPH_PTCR_RXTEN|PERIPH_PTCR_TXTEN;
/* Waiting transfer done*/
while((CONF_WINC_SPI->SPI_SR & SPI_SR_RXBUFF) == 0);
/*DEASSERT CS*/
SPI_DEASSERT_CS();
/* Disable the RX and TX PDC transfer requests */
g_p_spim_pdc->PERIPH_PTCR = PERIPH_PTCR_TXTDIS|PERIPH_PTCR_RXTDIS;
return M2M_SUCCESS;
#elif (defined LOW_DELAY)
uint8 u8Dummy = 0;
uint8 u8SkipMosi = 0, u8SkipMiso = 0;
uint8_t uc_pcs = 0;
p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (CONF_WINC_SPI_CS_GPIO >> 5)));
if (!pu8Mosi) {
pu8Mosi = &u8Dummy;
u8SkipMosi = 1;
}
else if(!pu8Miso) {
/*RX must be zero*/
pu8Miso = &u8Dummy;
u8SkipMiso = 1;
}
else {
return M2M_ERR_BUS_FAIL;
}
/*TX path*/
if(!u8SkipMosi)
{
SPI_ASSERT_CS();
while (u16Sz--)
{
CONF_WINC_SPI->SPI_TDR = SPI_TDR_TD((uint16)*pu8Mosi);
while (!(CONF_WINC_SPI->SPI_SR & SPI_SR_TDRE));
pu8Mosi++;
}
SPI_DEASSERT_CS();
}
/*RX path*/
if(!u8SkipMiso)
{
uc_pcs = 0;
SPI_ASSERT_CS();
while (u16Sz--)
{
CONF_WINC_SPI->SPI_TDR = SPI_TDR_TD((uint16)*pu8Mosi);
while (!(CONF_WINC_SPI->SPI_SR & SPI_SR_TDRE));
while (!(CONF_WINC_SPI->SPI_SR & (SPI_SR_RDRF)));
*pu8Miso = (uint16_t) ((CONF_WINC_SPI->SPI_RDR) & SPI_RDR_RD_Msk);
pu8Miso++;
}
SPI_DEASSERT_CS();
}
return M2M_SUCCESS;
#else
uint8 u8Dummy = 0;
uint8 u8SkipMosi = 0, u8SkipMiso = 0;
uint16_t txd_data = 0;
uint16_t rxd_data = 0;
uint8_t uc_pcs = 0;
p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (CONF_WINC_SPI_CS_GPIO >> 5)));
if (!pu8Mosi) {
pu8Mosi = &u8Dummy;
u8SkipMosi = 1;
}
else if(!pu8Miso) {
pu8Miso = &u8Dummy;
u8SkipMiso = 1;
}
else {
return M2M_ERR_BUS_FAIL;
}
SPI_ASSERT_CS();
while (u16Sz) {
txd_data = *pu8Mosi;
spi_write(CONF_WINC_SPI, txd_data, 0, 0);
spi_read(CONF_WINC_SPI, &rxd_data, &uc_pcs);
*pu8Miso = rxd_data;
u16Sz--;
if (!u8SkipMiso)
pu8Miso++;
if (!u8SkipMosi)
pu8Mosi++;
}
SPI_DEASSERT_CS();
return M2M_SUCCESS;
#endif
}
#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;
#ifdef CONF_WINC_USE_I2C
#elif defined CONF_WINC_USE_SPI
uint8_t spi_baudrate_divider;
/* Configure SPI pins. */
gpio_configure_pin(CONF_WINC_SPI_MISO_GPIO, CONF_WINC_SPI_MISO_FLAGS);
gpio_configure_pin(CONF_WINC_SPI_MOSI_GPIO, CONF_WINC_SPI_MOSI_FLAGS);
gpio_configure_pin(CONF_WINC_SPI_CLK_GPIO, CONF_WINC_SPI_CLK_FLAGS);
gpio_configure_pin(CONF_WINC_SPI_CS_GPIO, CONF_WINC_SPI_CS_FLAGS);
SPI_DEASSERT_CS();
/* Configure SPI module. */
spi_enable_clock(CONF_WINC_SPI);
spi_disable(CONF_WINC_SPI);
spi_reset(CONF_WINC_SPI);
spi_set_master_mode(CONF_WINC_SPI);
spi_disable_mode_fault_detect(CONF_WINC_SPI);
#ifdef __SAM4SD32C__
spi_set_fixed_peripheral_select(CONF_WINC_SPI);
#else
spi_set_peripheral_chip_select_value(CONF_WINC_SPI, CONF_WINC_SPI_NPCS);
#endif
spi_set_clock_polarity(CONF_WINC_SPI,
CONF_WINC_SPI_NPCS, CONF_WINC_SPI_POL);
spi_set_clock_phase(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, CONF_WINC_SPI_PHA);
spi_set_bits_per_transfer(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, SPI_CSR_BITS_8_BIT);
//printf("sys clk %d\r\n",sysclk_get_cpu_hz());
spi_baudrate_divider = (sysclk_get_cpu_hz() / CONF_WINC_SPI_CLOCK);
if ((uint32_t)(spi_baudrate_divider * CONF_WINC_SPI_CLOCK) < sysclk_get_cpu_hz()){
++spi_baudrate_divider;
}
spi_set_baudrate_div(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, spi_baudrate_divider);
spi_set_transfer_delay(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, CONF_WINC_SPI_DLYBS,
CONF_WINC_SPI_DLYBCT);
spi_enable(CONF_WINC_SPI);
/* Get pointer to SPI master PDC register base. */
g_p_spim_pdc = spi_get_pdc_base(CONF_WINC_SPI);
pdc_disable_transfer(g_p_spim_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
nm_bsp_reset();
nm_bsp_sleep(1);
SPI_DEASSERT_CS();
#endif
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 depending 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 = nm_spi_rw(pstrParam->pu8InBuf, pstrParam->pu8OutBuf, pstrParam->u16Sz);
}
break;
#endif
default:
s8Ret = -1;
M2M_ERR("invalid 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,438 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus wrapper APIs implementation.
*
* Copyright (c) 2016-2022 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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 "asf.h"
#include "conf_winc.h"
#define NM_BUS_MAX_TRX_SZ 256
tstrNmBusCapabilities egstrNmBusCapabilities =
{
NM_BUS_MAX_TRX_SZ
};
#ifdef CONF_WINC_USE_I2C
struct i2c_master_module i2c_master_instance;
#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_SUCCESS;
uint16_t timeout = 0;
struct i2c_master_packet packet = {
.address = SLAVE_ADDRESS,
.data_length = sz,
.data = b,
};
/* Write buffer to slave until success. */
while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) {
/* Increment timeout counter and check if timed out. */
if (timeout++ == I2C_TIMEOUT) {
break;
}
}
return result;
}
static sint8 nm_i2c_read(uint8 *rb, uint16 sz)
{
uint16_t timeout = 0;
sint8 result = M2M_SUCCESS;
struct i2c_master_packet packet = {
.address = SLAVE_ADDRESS,
.data_length = sz,
.data = rb,
};
/* Write buffer to slave until success. */
while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) {
/* Increment timeout counter and check if timed out. */
if (timeout++ == I2C_TIMEOUT) {
break;
}
}
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
struct spi_module master;
struct spi_slave_inst slave_inst;
#ifdef CONF_WINC_SPI_DMA
static volatile bool spi_dma_tx_done;
static volatile bool spi_dma_rx_done;
struct dma_resource dma_res_tx;
struct dma_resource dma_res_rx;
COMPILER_ALIGNED(32) DmacDescriptor dma_dsc_tx;
COMPILER_ALIGNED(32) DmacDescriptor dma_dsc_rx;
struct dma_descriptor_config dma_cfg_rx;
struct dma_descriptor_config dma_cfg_tx;
static void spi_dma_tx_completion_callback(const struct dma_resource* const resource)
{
spi_dma_tx_done = true;
}
static void spi_dma_rx_completion_callback(const struct dma_resource* const resource)
{
spi_dma_rx_done = true;
}
static inline sint8 spi_rw_dma(uint8* pu8Mosi, uint8* pu8Miso, uint16 u16Sz)
{
uint32_t dummy_buf = 0;
spi_dma_tx_done = false;
spi_dma_rx_done = false;
dma_cfg_tx.block_transfer_count = u16Sz;
dma_cfg_rx.block_transfer_count = u16Sz;
if (pu8Mosi) {
dma_cfg_tx.src_increment_enable = true;
dma_cfg_tx.source_address = (uint32_t)pu8Mosi + u16Sz;
} else {
dma_cfg_tx.src_increment_enable = false;
dma_cfg_tx.source_address = &dummy_buf;
}
dma_descriptor_create(&dma_dsc_tx, &dma_cfg_tx);
if (pu8Miso) {
dma_cfg_rx.dst_increment_enable = true;
dma_cfg_rx.destination_address = (uint32_t)pu8Miso + u16Sz;
} else {
dma_cfg_rx.dst_increment_enable = false;
dma_cfg_rx.destination_address = &dummy_buf;
}
dma_descriptor_create(&dma_dsc_rx, &dma_cfg_rx);
spi_select_slave(&master, &slave_inst, true);
dma_start_transfer_job(&dma_res_rx);
dma_start_transfer_job(&dma_res_tx);
/* Must wait until both spi tx dma and spi rx dma are complete.
* spi rx dma will be the last to complete, so could just wait on that. */
while((!spi_dma_tx_done) || (!spi_dma_rx_done));
spi_select_slave(&master, &slave_inst, false);
return M2M_SUCCESS;
}
#endif //CONF_WINC_SPI_DMA
static inline sint8 spi_rw_pio(uint8* pu8Mosi, uint8* pu8Miso, uint16 u16Sz)
{
uint8 u8Dummy = 0;
uint8 u8SkipMosi = 0, u8SkipMiso = 0;
uint16_t txd_data = 0;
uint16_t rxd_data = 0;
if(((pu8Miso == NULL) && (pu8Mosi == NULL)) ||(u16Sz == 0)) {
return M2M_ERR_INVALID_ARG;
}
if (!pu8Mosi) {
pu8Mosi = &u8Dummy;
u8SkipMosi = 1;
}
else if(!pu8Miso) {
pu8Miso = &u8Dummy;
u8SkipMiso = 1;
}
else {
return M2M_ERR_BUS_FAIL;
}
spi_select_slave(&master, &slave_inst, true);
while (u16Sz) {
txd_data = *pu8Mosi;
while(!spi_is_ready_to_write(&master));
while(spi_write(&master, txd_data) != STATUS_OK);
/* Read SPI master data register. */
while(!spi_is_ready_to_read(&master));
while(spi_read(&master, &rxd_data) != STATUS_OK);
*pu8Miso = rxd_data;
u16Sz--;
if (!u8SkipMiso)
pu8Miso++;
if (!u8SkipMosi)
pu8Mosi++;
}
while (!spi_is_write_complete(&master))
;
spi_select_slave(&master, &slave_inst, false);
return M2M_SUCCESS;
}
sint8 nm_spi_rw(uint8* pu8Mosi, uint8* pu8Miso, uint16 u16Sz)
{
#ifdef CONF_WINC_SPI_DMA
if (u16Sz >= 8) {
return spi_rw_dma(pu8Mosi, pu8Miso, u16Sz);
}
else
#endif //CONF_WINC_SPI_DMA
{
return spi_rw_pio(pu8Mosi, pu8Miso, u16Sz);
}
}
#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;
#ifdef CONF_WINC_USE_I2C
/* Initialize config structure and software module. */
struct i2c_master_config config_i2c_master;
i2c_master_get_config_defaults(&config_i2c_master);
/* Change buffer timeout to something longer. */
config_i2c_master.buffer_timeout = 1000;
/* Initialize and enable device with config. */
i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master);
i2c_master_enable(&i2c_master_instance);
#elif defined CONF_WINC_USE_SPI
/* Structure for SPI configuration. */
struct spi_config config;
struct spi_slave_inst_config slave_config;
/* Select SPI slave CS pin. */
/* This step will set the CS high */
spi_slave_inst_get_config_defaults(&slave_config);
slave_config.ss_pin = CONF_WINC_SPI_CS_PIN;
spi_attach_slave(&slave_inst, &slave_config);
/* Configure the SPI master. */
spi_get_config_defaults(&config);
config.mux_setting = CONF_WINC_SPI_SERCOM_MUX;
config.pinmux_pad0 = CONF_WINC_SPI_PINMUX_PAD0;
config.pinmux_pad1 = CONF_WINC_SPI_PINMUX_PAD1;
config.pinmux_pad2 = CONF_WINC_SPI_PINMUX_PAD2;
config.pinmux_pad3 = CONF_WINC_SPI_PINMUX_PAD3;
config.master_slave_select_enable = false;
config.mode_specific.master.baudrate = CONF_WINC_SPI_CLOCK;
if (spi_init(&master, CONF_WINC_SPI_MODULE, &config) != STATUS_OK) {
return M2M_ERR_BUS_FAIL;
}
/* Enable the SPI master. */
spi_enable(&master);
#ifdef CONF_WINC_SPI_DMA
{
struct dma_resource_config dma_config;
spi_dma_tx_done = false;
spi_dma_rx_done = false;
dma_get_config_defaults(&dma_config);
dma_config.peripheral_trigger = CONF_WINC_SPI_DMA_PERIPHERAL_TRIGGER_RX;
dma_config.trigger_action = DMA_TRIGGER_ACTION_BEAT;
dma_allocate(&dma_res_rx, &dma_config);
dma_add_descriptor(&dma_res_rx, &dma_dsc_rx);
dma_register_callback(&dma_res_rx, spi_dma_rx_completion_callback, DMA_CALLBACK_TRANSFER_DONE);
dma_enable_callback(&dma_res_rx, DMA_CALLBACK_TRANSFER_DONE);
dma_get_config_defaults(&dma_config);
dma_config.peripheral_trigger = CONF_WINC_SPI_DMA_PERIPHERAL_TRIGGER_TX;
dma_config.trigger_action = DMA_TRIGGER_ACTION_BEAT;
dma_allocate(&dma_res_tx, &dma_config);
dma_add_descriptor(&dma_res_tx, &dma_dsc_tx);
dma_register_callback(&dma_res_tx, spi_dma_tx_completion_callback, DMA_CALLBACK_TRANSFER_DONE);
dma_enable_callback(&dma_res_tx, DMA_CALLBACK_TRANSFER_DONE);
dma_descriptor_get_config_defaults(&dma_cfg_rx);
dma_descriptor_get_config_defaults(&dma_cfg_tx);
dma_cfg_tx.destination_address = (uint32_t)(&master.hw->SPI.DATA.reg);
dma_cfg_tx.dst_increment_enable = false;
dma_cfg_rx.source_address = (uint32_t)(&master.hw->SPI.DATA.reg);
dma_cfg_rx.src_increment_enable = false;
}
#endif // CONF_WINC_SPI_DMA
#endif // CONF_WINC_USE_I2C/SPI
nm_bsp_reset();
nm_bsp_sleep(1);
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 depending 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 = nm_spi_rw(pstrParam->pu8InBuf, pstrParam->pu8OutBuf, pstrParam->u16Sz);
}
break;
#endif
default:
s8Ret = -1;
M2M_ERR("invalid ioclt cmd\n");
break;
}
return s8Ret;
}
/**
* @fn nm_bus_deinit
* @brief De-initialize the bus wrapper
*/
sint8 nm_bus_deinit(void)
{
sint8 result = M2M_SUCCESS;
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as input no pull up. */
pin_conf.direction = PORT_PIN_DIR_INPUT;
pin_conf.input_pull = PORT_PIN_PULL_NONE;
#ifdef CONF_WINC_USE_I2C
i2c_master_disable(&i2c_master_instance);
port_pin_set_config(CONF_WINC_I2C_SCL, &pin_conf);
port_pin_set_config(CONF_WINC_I2C_SDA, &pin_conf);
#endif /* CONF_WINC_USE_I2C */
#ifdef CONF_WINC_USE_SPI
nm_bsp_deinit();
spi_disable(&master);
port_pin_set_config(CONF_WINC_SPI_MOSI, &pin_conf);
port_pin_set_config(CONF_WINC_SPI_MISO, &pin_conf);
port_pin_set_config(CONF_WINC_SPI_SCK, &pin_conf);
port_pin_set_config(CONF_WINC_SPI_SS, &pin_conf);
#ifdef CONF_WINC_SPI_DMA
dma_free(&dma_res_tx);
dma_free(&dma_res_rx);
#endif //CONF_WINC_SPI_DMA
//port_pin_set_output_level(CONF_WINC_SPI_MOSI, false);
//port_pin_set_output_level(CONF_WINC_SPI_MISO, false);
//port_pin_set_output_level(CONF_WINC_SPI_SCK, false);
//port_pin_set_output_level(CONF_WINC_SPI_SS, false);
#endif /* CONF_WINC_USE_SPI */
return result;
}
/**
* @fn nm_bus_reinit
* @brief re-initialize the bus wrapper
* @param [in] void *config
* re-init configuration data
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_bus_reinit(void* config)
{
return M2M_SUCCESS;
}
/**
* @fn nm_bus_speed
* @brief Either set the bus speed to default (HIGH) or a reduced speed (LOW)
to increase stability during WINC wakeup
* @param [in] uint8 level
* HIGH(1) or LOW(0)
* @return M2M_SUCCESS in case of success and M2M_ERR_INVALID_ARG in case of an
incorrect parameter
*/
sint8 nm_bus_speed(uint8 level)
{
/* No clock adjustment is necessary for SAMD21 */
if ((level == HIGH) || (level == LOW))
return M2M_SUCCESS;
return M2M_ERR_INVALID_ARG;
}

View File

@ -0,0 +1,307 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus wrapper APIs implementation.
*
* Copyright (c) 2016-2022 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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 "asf.h"
#include "conf_winc.h"
#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_SUCCESS;
twihs_packet_t packet_tx;
uint16_t timeout = 0;
/* Configure the data packet to be transmitted */
packet_tx.chip = SLAVE_ADDRESS;
packet_tx.addr[0] = 0;
packet_tx.addr[1] = 0;
packet_tx.addr[2] = 0;
packet_tx.addr_length = 0;
packet_tx.buffer = b;
packet_tx.length = sz;
while(twihs_master_write(CONF_WINC_I2C, &packet_tx) != TWIHS_SUCCESS) {
if (timeout++ == I2C_TIMEOUT) {
break;
}
}
return result;
}
static sint8 nm_i2c_read(uint8 *rb, uint16 sz)
{
sint8 result = M2M_SUCCESS;
twihs_packet_t packet_rx;
uint16_t timeout = 0;
/* Configure the data packet to be received */
packet_rx.chip = SLAVE_ADDRESS;
packet_rx.addr[0] = 0;
packet_rx.addr[1] = 0;
packet_rx.addr[2] = 0;
packet_rx.addr_length = 0;
packet_rx.buffer = rb;
packet_rx.length = sz;
while (twihs_master_read(CONF_WINC_I2C, &packet_rx) != TWIHS_SUCCESS) {
if (timeout++ == I2C_TIMEOUT) {
break;
}
}
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. */
Pio *p_pio_cs;
/** Fast CS macro. */
#define SPI_ASSERT_CS() do {p_pio_cs->PIO_CODR = 1 << (CONF_WINC_SPI_CS_GPIO & 0x1F);} while(0)
#define SPI_DEASSERT_CS() do {p_pio_cs->PIO_SODR = 1 << (CONF_WINC_SPI_CS_GPIO & 0x1F);} while(0)
sint8 nm_spi_rw(uint8 *pu8Mosi, uint8 *pu8Miso, uint16 u16Sz)
{
uint8 u8Dummy = 0;
uint8 u8SkipMosi = 0, u8SkipMiso = 0;
uint16_t txd_data = 0;
uint16_t rxd_data = 0;
uint8_t uc_pcs;
if (!pu8Mosi) {
pu8Mosi = &u8Dummy;
u8SkipMosi = 1;
}
else if(!pu8Miso) {
pu8Miso = &u8Dummy;
u8SkipMiso = 1;
}
else {
return M2M_ERR_BUS_FAIL;
}
SPI_ASSERT_CS();
while (u16Sz) {
txd_data = *pu8Mosi;
spi_write(CONF_WINC_SPI, txd_data, 0, 0);
/* Read SPI master data register. */
spi_read(CONF_WINC_SPI, &rxd_data, &uc_pcs);
*pu8Miso = rxd_data;
u16Sz--;
if (!u8SkipMiso)
pu8Miso++;
if (!u8SkipMosi)
pu8Mosi++;
}
SPI_DEASSERT_CS();
return M2M_SUCCESS;
}
#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;
#ifdef CONF_WINC_USE_I2C
twihs_options_t opt;
/* Enable the peripheral clock for TWI */
pmc_enable_periph_clk(CONF_WINC_I2C_ID);
/* Configure the options of TWI driver */
opt.master_clk = sysclk_get_peripheral_hz();
opt.speed = CONF_WINC_TWIHS_CLOCK;
if (twihs_master_init(CONF_WINC_I2C, &opt) != TWIHS_SUCCESS) {
M2M_ERR("-E-\tTWI master initialization failed.\r");
while (1) {
/* Capture error */
}
}
#elif CONF_WINC_USE_SPI
/* Configure SPI pins. */
ioport_set_pin_mode(CONF_WINC_SPI_MISO_GPIO, CONF_WINC_SPI_MISO_FLAGS);
ioport_set_pin_mode(CONF_WINC_SPI_MOSI_GPIO, CONF_WINC_SPI_MOSI_FLAGS);
ioport_set_pin_mode(CONF_WINC_SPI_CLK_GPIO, CONF_WINC_SPI_CLK_FLAGS);
ioport_set_pin_mode(CONF_WINC_SPI_CS_GPIO, CONF_WINC_SPI_CS_FLAGS);
ioport_disable_pin(CONF_WINC_SPI_MISO_GPIO);
ioport_disable_pin(CONF_WINC_SPI_MOSI_GPIO);
ioport_disable_pin(CONF_WINC_SPI_CLK_GPIO);
/* Configure CS for manual (GPIO) control. */
p_pio_cs = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (CONF_WINC_SPI_CS_GPIO >> 5)));
SPI_DEASSERT_CS();
ioport_set_pin_dir(CONF_WINC_SPI_CS_GPIO, IOPORT_DIR_OUTPUT);
ioport_enable_pin(CONF_WINC_SPI_CS_GPIO);
spi_enable_clock(CONF_WINC_SPI);
spi_disable(CONF_WINC_SPI);
spi_reset(CONF_WINC_SPI);
spi_set_master_mode(CONF_WINC_SPI);
spi_disable_mode_fault_detect(CONF_WINC_SPI);
spi_set_peripheral_chip_select_value(CONF_WINC_SPI, CONF_WINC_SPI_NPCS);
spi_set_clock_polarity(CONF_WINC_SPI,
CONF_WINC_SPI_NPCS, CONF_WINC_SPI_POL);
spi_set_clock_phase(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, CONF_WINC_SPI_PHA);
spi_set_bits_per_transfer(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, SPI_CSR_BITS_8_BIT);
spi_set_baudrate_div(CONF_WINC_SPI, CONF_WINC_SPI_NPCS,
(sysclk_get_peripheral_hz() / CONF_WINC_SPI_CLOCK));
spi_set_transfer_delay(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, CONF_WINC_SPI_DLYBS,
CONF_WINC_SPI_DLYBCT);
spi_enable(CONF_WINC_SPI);
nm_bsp_reset();
nm_bsp_sleep(1);
#endif
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 CONF_WINC_USE_SPI
case NM_BUS_IOCTL_RW: {
tstrNmSpiRw *pstrParam = (tstrNmSpiRw *)pvParameter;
s8Ret = nm_spi_rw(pstrParam->pu8InBuf, pstrParam->pu8OutBuf, pstrParam->u16Sz);
}
break;
#endif
default:
s8Ret = -1;
M2M_ERR("Invalid IOCTL command!\n");
break;
}
return s8Ret;
}
/*
* @fn nm_bus_deinit
* @brief De-initialize the bus wrapper
*/
sint8 nm_bus_deinit(void)
{
sint8 result = M2M_SUCCESS;
#ifdef CONF_WINC_USE_I2C
//TODO:
#endif /* CONF_WINC_USE_I2C */
#ifdef CONF_WINC_USE_SPI
spi_disable(CONF_WINC_SPI);
ioport_set_pin_dir(CONF_WINC_SPI_MOSI_GPIO, IOPORT_DIR_INPUT);
ioport_set_pin_dir(CONF_WINC_SPI_MISO_GPIO, IOPORT_DIR_INPUT);
ioport_set_pin_dir(CONF_WINC_SPI_CLK_GPIO, IOPORT_DIR_INPUT);
ioport_set_pin_dir(CONF_WINC_SPI_CS_GPIO, IOPORT_DIR_INPUT);
#endif /* CONF_WINC_USE_SPI */
return result;
}
/**
* @fn nm_bus_speed
* @brief Either set the bus speed to default (HIGH) or a reduced speed (LOW)
to increase stability during WINC wakeup
* @param [in] uint8 level
* HIGH(1) or LOW(0)
* @return M2M_SUCCESS in case of success and M2M_ERR_INVALID_ARG in case of an
incorrect parameter
*/
sint8 nm_bus_speed(uint8 level)
{
/* No clock adjustment is necessary for SAM4S */
if ((level == HIGH) || (level == LOW))
return M2M_SUCCESS;
return M2M_ERR_INVALID_ARG;
}

View File

@ -0,0 +1,252 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus wrapper APIs implementation.
*
* Copyright (c) 2016-2022 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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 "asf.h"
#include "conf_winc.h"
#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. */
Pio *p_pio_cs;
/** Fast CS macro. */
#define SPI_ASSERT_CS() do {p_pio_cs->PIO_CODR = 1 << (CONF_WINC_SPI_CS_GPIO & 0x1F);} while(0)
#define SPI_DEASSERT_CS() do {p_pio_cs->PIO_SODR = 1 << (CONF_WINC_SPI_CS_GPIO & 0x1F);} while(0)
/** Pointer to PDC SPI data structure. */
static Pdc *g_p_pdc_spi;
sint8 nm_spi_rw(uint8 *pu8Mosi, uint8 *pu8Miso, uint16 u16Sz)
{
pdc_packet_t pdc_spi_tx_packet, pdc_spi_rx_packet;
if(((pu8Miso == NULL) && (pu8Mosi == NULL)) || (u16Sz == 0)) {
return M2M_ERR_INVALID_ARG;
}
pdc_spi_tx_packet.ul_addr = (uint32_t)pu8Mosi;;
pdc_spi_rx_packet.ul_addr = (uint32_t)pu8Miso;
pdc_spi_tx_packet.ul_size = u16Sz;
pdc_spi_rx_packet.ul_size = u16Sz;
if (pu8Miso == 0) {
pdc_spi_rx_packet.ul_addr = (uint32_t)0x400000;
}
pdc_tx_init(g_p_pdc_spi, &pdc_spi_tx_packet, NULL);
pdc_rx_init(g_p_pdc_spi, &pdc_spi_rx_packet, NULL);
/* Trigger SPI PDC transfer. */
SPI_ASSERT_CS();
g_p_pdc_spi->PERIPH_PTCR = PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN;
while ((CONF_WINC_SPI->SPI_SR & SPI_SR_RXBUFF) == 0)
;
SPI_DEASSERT_CS();
g_p_pdc_spi->PERIPH_PTCR = PERIPH_PTCR_TXTDIS | PERIPH_PTCR_RXTDIS;
return M2M_SUCCESS;
}
#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;
#ifdef CONF_WINC_USE_I2C
#elif CONF_WINC_USE_SPI
/* Configure SPI pins. */
ioport_set_pin_mode(CONF_WINC_SPI_MISO_GPIO, CONF_WINC_SPI_MISO_FLAGS);
ioport_set_pin_mode(CONF_WINC_SPI_MOSI_GPIO, CONF_WINC_SPI_MOSI_FLAGS);
ioport_set_pin_mode(CONF_WINC_SPI_CLK_GPIO, CONF_WINC_SPI_CLK_FLAGS);
ioport_set_pin_mode(CONF_WINC_SPI_CS_GPIO, CONF_WINC_SPI_CS_FLAGS);
ioport_disable_pin(CONF_WINC_SPI_MISO_GPIO);
ioport_disable_pin(CONF_WINC_SPI_MOSI_GPIO);
ioport_disable_pin(CONF_WINC_SPI_CLK_GPIO);
ioport_disable_pin(CONF_WINC_SPI_CS_GPIO);
/* Get the PIO instance used for CS. */
p_pio_cs = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (CONF_WINC_SPI_CS_GPIO >> 5)));
SPI_DEASSERT_CS();
/* Configure SPI module. */
spi_enable_clock(CONF_WINC_SPI);
spi_disable(CONF_WINC_SPI);
spi_reset(CONF_WINC_SPI);
spi_set_master_mode(CONF_WINC_SPI);
spi_disable_mode_fault_detect(CONF_WINC_SPI);
spi_set_peripheral_chip_select_value(CONF_WINC_SPI, CONF_WINC_SPI_NPCS);
spi_set_clock_polarity(CONF_WINC_SPI,
CONF_WINC_SPI_NPCS, CONF_WINC_SPI_POL);
spi_set_clock_phase(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, CONF_WINC_SPI_PHA);
spi_set_bits_per_transfer(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, SPI_CSR_BITS_8_BIT);
spi_set_baudrate_div(CONF_WINC_SPI, CONF_WINC_SPI_NPCS,
spi_calc_baudrate_div(CONF_WINC_SPI_CLOCK, sysclk_get_cpu_hz()));
spi_set_transfer_delay(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, CONF_WINC_SPI_DLYBS,
CONF_WINC_SPI_DLYBCT);
spi_enable(CONF_WINC_SPI);
/* Get pointer to SPI master PDC register base. */
g_p_pdc_spi = spi_get_pdc_base(CONF_WINC_SPI);
pdc_disable_transfer(g_p_pdc_spi, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
nm_bsp_reset();
nm_bsp_sleep(1);
SPI_DEASSERT_CS();
#endif
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 CONF_WINC_USE_SPI
case NM_BUS_IOCTL_RW: {
tstrNmSpiRw *pstrParam = (tstrNmSpiRw *)pvParameter;
s8Ret = nm_spi_rw(pstrParam->pu8InBuf, pstrParam->pu8OutBuf, pstrParam->u16Sz);
}
break;
#endif
default:
s8Ret = -1;
M2M_ERR("Invalid IOCTL command!\n");
break;
}
return s8Ret;
}
/*
* @fn nm_bus_deinit
* @brief De-initialize the bus wrapper
*/
sint8 nm_bus_deinit(void)
{
sint8 result = M2M_SUCCESS;
#ifdef CONF_WINC_USE_SPI
spi_disable(CONF_WINC_SPI);
ioport_set_pin_dir(CONF_WINC_SPI_MOSI_GPIO, IOPORT_DIR_INPUT);
ioport_set_pin_dir(CONF_WINC_SPI_MISO_GPIO, IOPORT_DIR_INPUT);
ioport_set_pin_dir(CONF_WINC_SPI_CLK_GPIO, IOPORT_DIR_INPUT);
ioport_set_pin_dir(CONF_WINC_SPI_CS_GPIO, IOPORT_DIR_INPUT);
#endif /* CONF_WINC_USE_SPI */
return result;
}
/**
* @fn nm_bus_speed
* @brief Either set the bus speed to default (HIGH) or a reduced speed (LOW)
to increase stability during WINC wakeup
* @param [in] uint8 level
* HIGH(1) or LOW(0)
* @return M2M_SUCCESS in case of success and M2M_ERR_INVALID_ARG in case of an
incorrect parameter
*/
sint8 nm_bus_speed(uint8 level)
{
/* No clock adjustment is necessary for SAM4S */
if ((level == HIGH) || (level == LOW))
return M2M_SUCCESS;
return M2M_ERR_INVALID_ARG;
}

View File

@ -0,0 +1,258 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus wrapper APIs implementation.
*
* Copyright (c) 2016-2022 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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 "asf.h"
#include "conf_winc.h"
#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. */
Pio *p_pio_cs;
/** Fast CS macro. */
#define SPI_ASSERT_CS() do {p_pio_cs->PIO_CODR = 1 << (CONF_WINC_SPI_CS_GPIO & 0x1F);} while(0)
#define SPI_DEASSERT_CS() do {p_pio_cs->PIO_SODR = 1 << (CONF_WINC_SPI_CS_GPIO & 0x1F);} while(0)
/** Pointer to PDC SPI data structure. */
static Pdc *g_p_pdc_spi;
sint8 nm_spi_rw(uint8 *pu8Mosi, uint8 *pu8Miso, uint16 u16Sz)
{
pdc_packet_t pdc_spi_tx_packet, pdc_spi_rx_packet;
if(((pu8Miso == NULL)&& (pu8Mosi == NULL)) ||(u16Sz == 0)) {
return M2M_ERR_INVALID_ARG;
}
pdc_spi_tx_packet.ul_addr = (uint32_t)pu8Mosi;;
pdc_spi_rx_packet.ul_addr = (uint32_t)pu8Miso;
pdc_spi_tx_packet.ul_size = u16Sz;
pdc_spi_rx_packet.ul_size = u16Sz;
if (pu8Miso == 0) {
pdc_spi_rx_packet.ul_addr = (uint32_t)0x400000;
}
pdc_tx_init(g_p_pdc_spi, &pdc_spi_tx_packet, NULL);
pdc_rx_init(g_p_pdc_spi, &pdc_spi_rx_packet, NULL);
/* Trigger SPI PDC transfer. */
SPI_ASSERT_CS();
g_p_pdc_spi->PERIPH_PTCR = PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN;
while ((CONF_WINC_SPI->SPI_SR & SPI_SR_RXBUFF) == 0)
;
SPI_DEASSERT_CS();
g_p_pdc_spi->PERIPH_PTCR = PERIPH_PTCR_TXTDIS | PERIPH_PTCR_RXTDIS;
return M2M_SUCCESS;
}
#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;
#ifdef CONF_WINC_USE_I2C
#elif CONF_WINC_USE_SPI
/* Configure SPI pins. */
ioport_set_pin_mode(CONF_WINC_SPI_MISO_GPIO, CONF_WINC_SPI_MISO_FLAGS);
ioport_set_pin_mode(CONF_WINC_SPI_MOSI_GPIO, CONF_WINC_SPI_MOSI_FLAGS);
ioport_set_pin_mode(CONF_WINC_SPI_CLK_GPIO, CONF_WINC_SPI_CLK_FLAGS);
ioport_set_pin_mode(CONF_WINC_SPI_CS_GPIO, CONF_WINC_SPI_CS_FLAGS);
ioport_disable_pin(CONF_WINC_SPI_MISO_GPIO);
ioport_disable_pin(CONF_WINC_SPI_MOSI_GPIO);
ioport_disable_pin(CONF_WINC_SPI_CLK_GPIO);
ioport_disable_pin(CONF_WINC_SPI_CS_GPIO);
/* Get the PIO instance used for CS. */
p_pio_cs = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (CONF_WINC_SPI_CS_GPIO >> 5)));
SPI_DEASSERT_CS();
/* Configure SPI module. */
if (!spi_is_enabled(CONF_WINC_SPI)) {
flexcom_enable(FLEXCOM5);
flexcom_set_opmode(FLEXCOM5, FLEXCOM_SPI);
}
spi_enable_clock(CONF_WINC_SPI);
spi_disable(CONF_WINC_SPI);
spi_reset(CONF_WINC_SPI);
spi_set_master_mode(CONF_WINC_SPI);
spi_disable_mode_fault_detect(CONF_WINC_SPI);
spi_set_peripheral_chip_select_value(CONF_WINC_SPI, CONF_WINC_SPI_NPCS);
spi_set_clock_polarity(CONF_WINC_SPI,
CONF_WINC_SPI_NPCS, CONF_WINC_SPI_POL);
spi_set_clock_phase(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, CONF_WINC_SPI_PHA);
spi_set_bits_per_transfer(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, SPI_CSR_BITS_8_BIT);
spi_set_baudrate_div(CONF_WINC_SPI, CONF_WINC_SPI_NPCS,
spi_calc_baudrate_div(CONF_WINC_SPI_CLOCK, sysclk_get_cpu_hz()));
spi_set_transfer_delay(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, CONF_WINC_SPI_DLYBS,
CONF_WINC_SPI_DLYBCT);
spi_enable(CONF_WINC_SPI);
/* Get pointer to SPI master PDC register base. */
g_p_pdc_spi = spi_get_pdc_base(CONF_WINC_SPI);
pdc_disable_transfer(g_p_pdc_spi, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
nm_bsp_reset();
nm_bsp_sleep(1);
SPI_DEASSERT_CS();
#endif
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 depending 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 CONF_WINC_USE_SPI
case NM_BUS_IOCTL_RW: {
tstrNmSpiRw *pstrParam = (tstrNmSpiRw *)pvParameter;
s8Ret = nm_spi_rw(pstrParam->pu8InBuf, pstrParam->pu8OutBuf, pstrParam->u16Sz);
}
break;
#endif
default:
s8Ret = -1;
M2M_ERR("Invalid IOCTL command!\n");
break;
}
return s8Ret;
}
/*
* @fn nm_bus_deinit
* @brief De-initialize the bus wrapper
*/
sint8 nm_bus_deinit(void)
{
sint8 result = M2M_SUCCESS;
#ifdef CONF_WINC_USE_SPI
spi_disable(CONF_WINC_SPI);
ioport_set_pin_dir(CONF_WINC_SPI_MOSI_GPIO, IOPORT_DIR_INPUT);
ioport_set_pin_dir(CONF_WINC_SPI_MISO_GPIO, IOPORT_DIR_INPUT);
ioport_set_pin_dir(CONF_WINC_SPI_CLK_GPIO, IOPORT_DIR_INPUT);
ioport_set_pin_dir(CONF_WINC_SPI_CS_GPIO, IOPORT_DIR_INPUT);
#endif /* CONF_WINC_USE_SPI */
return result;
}
/**
* @fn nm_bus_speed
* @brief Either set the bus speed to default (HIGH) or a reduced speed (LOW)
to increase stability during WINC wakeup
* @param [in] uint8 level
* HIGH(1) or LOW(0)
* @return M2M_SUCCESS in case of success and M2M_ERR_INVALID_ARG in case of an
incorrect parameter
*/
sint8 nm_bus_speed(uint8 level)
{
/* No clock adjustment is necessary */
if ((level == HIGH) || (level == LOW))
return M2M_SUCCESS;
return M2M_ERR_INVALID_ARG;
}

View File

@ -0,0 +1,325 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus wrapper APIs implementation.
*
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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 "asf.h"
#include "conf_winc.h"
#define NM_BUS_MAX_TRX_SZ 256
tstrNmBusCapabilities egstrNmBusCapabilities =
{
NM_BUS_MAX_TRX_SZ
};
#ifdef CONF_WINC_USE_I2C
struct i2c_master_module i2c_master_instance;
#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_SUCCESS;
uint16_t timeout = 0;
struct i2c_master_packet packet = {
.address = SLAVE_ADDRESS,
.data_length = sz,
.data = b,
};
/* Write buffer to slave until success. */
while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) {
/* Increment timeout counter and check if timed out. */
if (timeout++ == I2C_TIMEOUT) {
break;
}
}
return result;
}
static sint8 nm_i2c_read(uint8 *rb, uint16 sz)
{
uint16_t timeout = 0;
sint8 result = M2M_SUCCESS;
struct i2c_master_packet packet = {
.address = SLAVE_ADDRESS,
.data_length = sz,
.data = rb,
};
/* Write buffer to slave until success. */
while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) {
/* Increment timeout counter and check if timed out. */
if (timeout++ == I2C_TIMEOUT) {
break;
}
}
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
struct spi_module master;
struct spi_slave_inst slave_inst;
sint8 nm_spi_rw(uint8* pu8Mosi, uint8* pu8Miso, uint16 u16Sz)
{
uint8 u8Dummy = 0;
uint8 u8SkipMosi = 0, u8SkipMiso = 0;
uint16_t txd_data = 0;
uint16_t rxd_data = 0;
if((pu8Miso == NULL)&&(pu8Mosi == NULL)||(u16Sz == 0)) {
return M2M_ERR_INVALID_ARG;
}
if (pu8Mosi == NULL) {
pu8Mosi = &u8Dummy;
u8SkipMosi = 1;
}
if(pu8Miso == NULL) {
pu8Miso = &u8Dummy;
u8SkipMiso = 1;
}
spi_select_slave(&master, &slave_inst, true);
while (u16Sz) {
txd_data = *pu8Mosi;
while (!spi_is_ready_to_write(&master))
;
while(spi_write(&master, txd_data) != STATUS_OK)
;
/* Read SPI master data register. */
while (!spi_is_ready_to_read(&master))
;
while (spi_read(&master, &rxd_data) != STATUS_OK)
;
*pu8Miso = rxd_data;
u16Sz--;
if (!u8SkipMiso)
pu8Miso++;
if (!u8SkipMosi)
pu8Mosi++;
}
while (!spi_is_write_complete(&master))
;
spi_select_slave(&master, &slave_inst, false);
return M2M_SUCCESS;
}
#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;
#ifdef CONF_WINC_USE_I2C
/* Initialize config structure and software module. */
struct i2c_master_config config_i2c_master;
i2c_master_get_config_defaults(&config_i2c_master);
/* Change buffer timeout to something longer. */
config_i2c_master.buffer_timeout = 1000;
/* Initialize and enable device with config. */
i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master);
i2c_master_enable(&i2c_master_instance);
#elif defined CONF_WINC_USE_SPI
/* Structure for SPI configuration. */
struct spi_config config;
struct spi_slave_inst_config slave_config;
/* Select SPI slave CS pin. */
/* This step will set the CS high */
spi_slave_inst_get_config_defaults(&slave_config);
slave_config.ss_pin = CONF_WINC_SPI_CS_PIN;
spi_attach_slave(&slave_inst, &slave_config);
/* Configure the SPI master. */
spi_get_config_defaults(&config);
config.mux_setting = CONF_WINC_SPI_SERCOM_MUX;
config.pinmux_pad0 = CONF_WINC_SPI_PINMUX_PAD0;
config.pinmux_pad1 = CONF_WINC_SPI_PINMUX_PAD1;
config.pinmux_pad2 = CONF_WINC_SPI_PINMUX_PAD2;
config.pinmux_pad3 = CONF_WINC_SPI_PINMUX_PAD3;
config.master_slave_select_enable = false;
config.mode_specific.master.baudrate = CONF_WINC_SPI_CLOCK;
if (spi_init(&master, CONF_WINC_SPI_MODULE, &config) != STATUS_OK) {
return M2M_ERR_BUS_FAIL;
}
/* Enable the SPI master. */
spi_enable(&master);
nm_bsp_reset();
nm_bsp_sleep(1);
#endif
return result;
}
/*
* @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 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 = nm_spi_rw(pstrParam->pu8InBuf, pstrParam->pu8OutBuf, pstrParam->u16Sz);
}
break;
#endif
default:
s8Ret = -1;
M2M_ERR("invalid ioclt cmd\n");
break;
}
return s8Ret;
}
/*
* @fn nm_bus_deinit
* @brief De-initialize the bus wrapper
*/
sint8 nm_bus_deinit(void)
{
sint8 result = M2M_SUCCESS;
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as input no pull up. */
pin_conf.direction = PORT_PIN_DIR_INPUT;
pin_conf.input_pull = PORT_PIN_PULL_NONE;
#ifdef CONF_WINC_USE_I2C
i2c_master_disable(&i2c_master_instance);
#endif /* CONF_WINC_USE_I2C */
#ifdef CONF_WINC_USE_SPI
spi_disable(&master);
#endif /* CONF_WINC_USE_SPI */
return result;
}
/*
* @fn nm_bus_reinit
* @brief re-initialize the bus wrapper
* @param [in] void *config
* re-init configuration data
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Dina El Sissy
* @date 19 Sept 2012
* @version 1.0
*/
sint8 nm_bus_reinit(void* config)
{
return M2M_SUCCESS;
}
/**
* @fn nm_bus_speed
* @brief Either set the bus speed to default (HIGH) or a reduced speed (LOW)
to increase stability during WINC wakeup
* @param [in] uint8 level
* HIGH(1) or LOW(0)
* @return M2M_SUCCESS in case of success and M2M_ERR_INVALID_ARG in case of an
incorrect parameter
*/
sint8 nm_bus_speed(uint8 level)
{
/* No clock adjustment is necessary */
if ((level == HIGH) || (level == LOW))
return M2M_SUCCESS;
return M2M_ERR_INVALID_ARG;
}

View File

@ -0,0 +1,325 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus wrapper APIs implementation.
*
* Copyright (c) 2016-2022 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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 "asf.h"
#include "conf_winc.h"
#define NM_BUS_MAX_TRX_SZ 256
tstrNmBusCapabilities egstrNmBusCapabilities =
{
NM_BUS_MAX_TRX_SZ
};
#ifdef CONF_WINC_USE_I2C
struct i2c_master_module i2c_master_instance;
#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_SUCCESS;
uint16_t timeout = 0;
struct i2c_master_packet packet = {
.address = SLAVE_ADDRESS,
.data_length = sz,
.data = b,
};
/* Write buffer to slave until success. */
while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) {
/* Increment timeout counter and check if timed out. */
if (timeout++ == I2C_TIMEOUT) {
break;
}
}
return result;
}
static sint8 nm_i2c_read(uint8 *rb, uint16 sz)
{
uint16_t timeout = 0;
sint8 result = M2M_SUCCESS;
struct i2c_master_packet packet = {
.address = SLAVE_ADDRESS,
.data_length = sz,
.data = rb,
};
/* Write buffer to slave until success. */
while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) {
/* Increment timeout counter and check if timed out. */
if (timeout++ == I2C_TIMEOUT) {
break;
}
}
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
struct spi_module master;
struct spi_slave_inst slave_inst;
sint8 nm_spi_rw(uint8* pu8Mosi, uint8* pu8Miso, uint16 u16Sz)
{
uint8 u8Dummy = 0;
uint8 u8SkipMosi = 0, u8SkipMiso = 0;
uint16_t txd_data = 0;
uint16_t rxd_data = 0;
if(((pu8Miso == NULL) && (pu8Mosi == NULL)) || (u16Sz == 0)) {
return M2M_ERR_INVALID_ARG;
}
if (pu8Mosi == NULL) {
pu8Mosi = &u8Dummy;
u8SkipMosi = 1;
}
if(pu8Miso == NULL) {
pu8Miso = &u8Dummy;
u8SkipMiso = 1;
}
spi_select_slave(&master, &slave_inst, true);
while (u16Sz) {
txd_data = *pu8Mosi;
while (!spi_is_ready_to_write(&master))
;
while(spi_write(&master, txd_data) != STATUS_OK)
;
/* Read SPI master data register. */
while (!spi_is_ready_to_read(&master))
;
while (spi_read(&master, &rxd_data) != STATUS_OK)
;
*pu8Miso = rxd_data;
u16Sz--;
if (!u8SkipMiso)
pu8Miso++;
if (!u8SkipMosi)
pu8Mosi++;
}
while (!spi_is_write_complete(&master))
;
spi_select_slave(&master, &slave_inst, false);
return M2M_SUCCESS;
}
#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;
#ifdef CONF_WINC_USE_I2C
/* Initialize config structure and software module. */
struct i2c_master_config config_i2c_master;
i2c_master_get_config_defaults(&config_i2c_master);
/* Change buffer timeout to something longer. */
config_i2c_master.buffer_timeout = 1000;
/* Initialize and enable device with config. */
i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master);
i2c_master_enable(&i2c_master_instance);
#elif defined CONF_WINC_USE_SPI
/* Structure for SPI configuration. */
struct spi_config config;
struct spi_slave_inst_config slave_config;
/* Select SPI slave CS pin. */
/* This step will set the CS high */
spi_slave_inst_get_config_defaults(&slave_config);
slave_config.ss_pin = CONF_WINC_SPI_CS_PIN;
spi_attach_slave(&slave_inst, &slave_config);
/* Configure the SPI master. */
spi_get_config_defaults(&config);
config.mux_setting = CONF_WINC_SPI_SERCOM_MUX;
config.pinmux_pad0 = CONF_WINC_SPI_PINMUX_PAD0;
config.pinmux_pad1 = CONF_WINC_SPI_PINMUX_PAD1;
config.pinmux_pad2 = CONF_WINC_SPI_PINMUX_PAD2;
config.pinmux_pad3 = CONF_WINC_SPI_PINMUX_PAD3;
config.master_slave_select_enable = false;
config.mode_specific.master.baudrate = CONF_WINC_SPI_CLOCK;
if (spi_init(&master, CONF_WINC_SPI_MODULE, &config) != STATUS_OK) {
return M2M_ERR_BUS_FAIL;
}
/* Enable the SPI master. */
spi_enable(&master);
nm_bsp_reset();
nm_bsp_sleep(1);
#endif
return result;
}
/*
* @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 = nm_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)
{
sint8 result = M2M_SUCCESS;
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as input no pull up. */
pin_conf.direction = PORT_PIN_DIR_INPUT;
pin_conf.input_pull = PORT_PIN_PULL_NONE;
#ifdef CONF_WINC_USE_I2C
i2c_master_disable(&i2c_master_instance);
#endif /* CONF_WINC_USE_I2C */
#ifdef CONF_WINC_USE_SPI
spi_disable(&master);
#endif /* CONF_WINC_USE_SPI */
return result;
}
/*
* @fn nm_bus_reinit
* @brief re-initialize the bus wrapper
* @param [in] void *config
* re-init configuration data
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Dina El Sissy
* @date 19 Sept 2012
* @version 1.0
*/
sint8 nm_bus_reinit(void* config)
{
return M2M_SUCCESS;
}
/**
* @fn nm_bus_speed
* @brief Either set the bus speed to default (HIGH) or a reduced speed (LOW)
to increase stability during WINC wakeup
* @param [in] uint8 level
* HIGH(1) or LOW(0)
* @return M2M_SUCCESS in case of success and M2M_ERR_INVALID_ARG in case of an
incorrect parameter
*/
sint8 nm_bus_speed(uint8 level)
{
/* No clock adjustment is necessary for SAM4S */
if ((level == HIGH) || (level == LOW))
return M2M_SUCCESS;
return M2M_ERR_INVALID_ARG;
}

View File

@ -0,0 +1,332 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus wrapper APIs implementation.
*
* Copyright (c) 2016-2022 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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 "asf.h"
#include "conf_winc.h"
#define NM_BUS_MAX_TRX_SZ 256
tstrNmBusCapabilities egstrNmBusCapabilities =
{
NM_BUS_MAX_TRX_SZ
};
#ifdef CONF_WINC_USE_I2C
struct i2c_master_module i2c_master_instance;
#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_SUCCESS;
uint16_t timeout = 0;
struct i2c_master_packet packet = {
.address = SLAVE_ADDRESS,
.data_length = sz,
.data = b,
};
/* Write buffer to slave until success. */
while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) {
/* Increment timeout counter and check if timed out. */
if (timeout++ == I2C_TIMEOUT) {
break;
}
}
return result;
}
static sint8 nm_i2c_read(uint8 *rb, uint16 sz)
{
uint16_t timeout = 0;
sint8 result = M2M_SUCCESS;
struct i2c_master_packet packet = {
.address = SLAVE_ADDRESS,
.data_length = sz,
.data = rb,
};
/* Write buffer to slave until success. */
while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) {
/* Increment timeout counter and check if timed out. */
if (timeout++ == I2C_TIMEOUT) {
break;
}
}
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
struct spi_module master;
struct spi_slave_inst slave_inst;
sint8 nm_spi_rw(uint8* pu8Mosi, uint8* pu8Miso, uint16 u16Sz)
{
uint8 u8Dummy = 0;
uint8 u8SkipMosi = 0, u8SkipMiso = 0;
uint16_t txd_data = 0;
uint16_t rxd_data = 0;
if(((pu8Miso == NULL) && (pu8Mosi == NULL)) ||(u16Sz == 0)) {
return M2M_ERR_INVALID_ARG;
}
if (pu8Mosi == NULL) {
pu8Mosi = &u8Dummy;
u8SkipMosi = 1;
}
if(pu8Miso == NULL) {
pu8Miso = &u8Dummy;
u8SkipMiso = 1;
}
spi_select_slave(&master, &slave_inst, true);
while (u16Sz) {
txd_data = *pu8Mosi;
while (!spi_is_ready_to_write(&master))
;
while(spi_write(&master, txd_data) != STATUS_OK)
;
/* Read SPI master data register. */
while (!spi_is_ready_to_read(&master))
;
while (spi_read(&master, &rxd_data) != STATUS_OK)
;
*pu8Miso = rxd_data;
u16Sz--;
if (!u8SkipMiso)
pu8Miso++;
if (!u8SkipMosi)
pu8Mosi++;
}
while (!spi_is_write_complete(&master))
;
spi_select_slave(&master, &slave_inst, false);
return M2M_SUCCESS;
}
#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;
#ifdef CONF_WINC_USE_I2C
/* Initialize config structure and software module. */
struct i2c_master_config config_i2c_master;
i2c_master_get_config_defaults(&config_i2c_master);
/* Change buffer timeout to something longer. */
config_i2c_master.buffer_timeout = 1000;
/* Initialize and enable device with config. */
i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master);
i2c_master_enable(&i2c_master_instance);
#elif defined CONF_WINC_USE_SPI
/* Structure for SPI configuration. */
struct spi_config config;
struct spi_slave_inst_config slave_config;
/* Select SPI slave CS pin. */
/* This step will set the CS high */
spi_slave_inst_get_config_defaults(&slave_config);
slave_config.ss_pin = CONF_WINC_SPI_CS_PIN;
spi_attach_slave(&slave_inst, &slave_config);
/* Configure the SPI master. */
spi_get_config_defaults(&config);
config.mux_setting = CONF_WINC_SPI_SERCOM_MUX;
config.pinmux_pad0 = CONF_WINC_SPI_PINMUX_PAD0;
config.pinmux_pad1 = CONF_WINC_SPI_PINMUX_PAD1;
config.pinmux_pad2 = CONF_WINC_SPI_PINMUX_PAD2;
config.pinmux_pad3 = CONF_WINC_SPI_PINMUX_PAD3;
config.master_slave_select_enable = false;
config.mode_specific.master.baudrate = CONF_WINC_SPI_CLOCK;
if (spi_init(&master, CONF_WINC_SPI_MODULE, &config) != STATUS_OK) {
return M2M_ERR_BUS_FAIL;
}
/* Enable the SPI master. */
spi_enable(&master);
nm_bsp_reset();
nm_bsp_sleep(1);
#endif
return result;
}
/*
* @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 = nm_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)
{
sint8 result = M2M_SUCCESS;
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as input no pull up. */
pin_conf.direction = PORT_PIN_DIR_INPUT;
pin_conf.input_pull = PORT_PIN_PULL_NONE;
#ifdef CONF_WINC_USE_I2C
i2c_master_disable(&i2c_master_instance);
port_pin_set_config(CONF_WINC_I2C_SCL, &pin_conf);
port_pin_set_config(CONF_WINC_I2C_SDA, &pin_conf);
#endif /* CONF_WINC_USE_I2C */
#ifdef CONF_WINC_USE_SPI
spi_disable(&master);
port_pin_set_config(CONF_WINC_SPI_MOSI, &pin_conf);
port_pin_set_config(CONF_WINC_SPI_MISO, &pin_conf);
port_pin_set_config(CONF_WINC_SPI_SCK, &pin_conf);
port_pin_set_config(CONF_WINC_SPI_SS, &pin_conf);
//port_pin_set_output_level(CONF_WINC_SPI_MOSI, false);
//port_pin_set_output_level(CONF_WINC_SPI_MISO, false);
//port_pin_set_output_level(CONF_WINC_SPI_SCK, false);
//port_pin_set_output_level(CONF_WINC_SPI_SS, false);
#endif /* CONF_WINC_USE_SPI */
return result;
}
/*
* @fn nm_bus_reinit
* @brief re-initialize the bus wrapper
* @param [in] void *config
* re-init configuration data
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_bus_reinit(void* config)
{
return M2M_SUCCESS;
}
/**
* @fn nm_bus_speed
* @brief Either set the bus speed to default (HIGH) or a reduced speed (LOW)
to increase stability during WINC wakeup
* @param [in] uint8 level
* HIGH(1) or LOW(0)
* @return M2M_SUCCESS in case of success and M2M_ERR_INVALID_ARG in case of an
incorrect parameter
*/
sint8 nm_bus_speed(uint8 level)
{
/* No clock adjustment is necessary for SAM4S */
if ((level == HIGH) || (level == LOW))
return M2M_SUCCESS;
return M2M_ERR_INVALID_ARG;
}

View File

@ -0,0 +1,325 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus wrapper APIs implementation.
*
* Copyright (c) 2020-2022 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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 "asf.h"
#include "conf_winc.h"
#define NM_BUS_MAX_TRX_SZ 256
tstrNmBusCapabilities egstrNmBusCapabilities =
{
NM_BUS_MAX_TRX_SZ
};
#ifdef CONF_WINC_USE_I2C
struct i2c_master_module i2c_master_instance;
#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_SUCCESS;
uint16_t timeout = 0;
struct i2c_master_packet packet = {
.address = SLAVE_ADDRESS,
.data_length = sz,
.data = b,
};
/* Write buffer to slave until success. */
while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) {
/* Increment timeout counter and check if timed out. */
if (timeout++ == I2C_TIMEOUT) {
break;
}
}
return result;
}
static sint8 nm_i2c_read(uint8 *rb, uint16 sz)
{
uint16_t timeout = 0;
sint8 result = M2M_SUCCESS;
struct i2c_master_packet packet = {
.address = SLAVE_ADDRESS,
.data_length = sz,
.data = rb,
};
/* Write buffer to slave until success. */
while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) {
/* Increment timeout counter and check if timed out. */
if (timeout++ == I2C_TIMEOUT) {
break;
}
}
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
struct spi_module master;
struct spi_slave_inst slave_inst;
sint8 nm_spi_rw(uint8* pu8Mosi, uint8* pu8Miso, uint16 u16Sz)
{
uint8 u8Dummy = 0;
uint8 u8SkipMosi = 0, u8SkipMiso = 0;
uint16_t txd_data = 0;
uint16_t rxd_data = 0;
if(((pu8Miso == NULL) && (pu8Mosi == NULL)) || (u16Sz == 0)) {
return M2M_ERR_INVALID_ARG;
}
if (pu8Mosi == NULL) {
pu8Mosi = &u8Dummy;
u8SkipMosi = 1;
}
if(pu8Miso == NULL) {
pu8Miso = &u8Dummy;
u8SkipMiso = 1;
}
spi_select_slave(&master, &slave_inst, true);
while (u16Sz) {
txd_data = *pu8Mosi;
while (!spi_is_ready_to_write(&master))
;
while(spi_write(&master, txd_data) != STATUS_OK)
;
/* Read SPI master data register. */
while (!spi_is_ready_to_read(&master))
;
while (spi_read(&master, &rxd_data) != STATUS_OK)
;
*pu8Miso = rxd_data;
u16Sz--;
if (!u8SkipMiso)
pu8Miso++;
if (!u8SkipMosi)
pu8Mosi++;
}
while (!spi_is_write_complete(&master))
;
spi_select_slave(&master, &slave_inst, false);
return M2M_SUCCESS;
}
#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;
#ifdef CONF_WINC_USE_I2C
/* Initialize config structure and software module. */
struct i2c_master_config config_i2c_master;
i2c_master_get_config_defaults(&config_i2c_master);
/* Change buffer timeout to something longer. */
config_i2c_master.buffer_timeout = 1000;
/* Initialize and enable device with config. */
i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master);
i2c_master_enable(&i2c_master_instance);
#elif defined CONF_WINC_USE_SPI
/* Structure for SPI configuration. */
struct spi_config config;
struct spi_slave_inst_config slave_config;
/* Select SPI slave CS pin. */
/* This step will set the CS high */
spi_slave_inst_get_config_defaults(&slave_config);
slave_config.ss_pin = CONF_WINC_SPI_CS_PIN;
spi_attach_slave(&slave_inst, &slave_config);
/* Configure the SPI master. */
spi_get_config_defaults(&config);
config.mux_setting = CONF_WINC_SPI_SERCOM_MUX;
config.pinmux_pad0 = CONF_WINC_SPI_PINMUX_PAD0;
config.pinmux_pad1 = CONF_WINC_SPI_PINMUX_PAD1;
config.pinmux_pad2 = CONF_WINC_SPI_PINMUX_PAD2;
config.pinmux_pad3 = CONF_WINC_SPI_PINMUX_PAD3;
config.master_slave_select_enable = false;
config.mode_specific.master.baudrate = CONF_WINC_SPI_CLOCK;
if (spi_init(&master, CONF_WINC_SPI_MODULE, &config) != STATUS_OK) {
return M2M_ERR_BUS_FAIL;
}
/* Enable the SPI master. */
spi_enable(&master);
nm_bsp_reset();
nm_bsp_sleep(1);
#endif
return result;
}
/*
* @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 = nm_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)
{
sint8 result = M2M_SUCCESS;
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
/* Configure control pins as input no pull up. */
pin_conf.direction = PORT_PIN_DIR_INPUT;
pin_conf.input_pull = PORT_PIN_PULL_NONE;
#ifdef CONF_WINC_USE_I2C
i2c_master_disable(&i2c_master_instance);
#endif /* CONF_WINC_USE_I2C */
#ifdef CONF_WINC_USE_SPI
spi_disable(&master);
#endif /* CONF_WINC_USE_SPI */
return result;
}
/*
* @fn nm_bus_reinit
* @brief re-initialize the bus wrapper
* @param [in] void *config
* re-init configuration data
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Dina El Sissy
* @date 19 Sept 2012
* @version 1.0
*/
sint8 nm_bus_reinit(void* config)
{
return M2M_SUCCESS;
}
/**
* @fn nm_bus_speed
* @brief Either set the bus speed to default (HIGH) or a reduced speed (LOW)
to increase stability during WINC wakeup
* @param [in] uint8 level
* HIGH(1) or LOW(0)
* @return M2M_SUCCESS in case of success and M2M_ERR_INVALID_ARG in case of an
incorrect parameter
*/
sint8 nm_bus_speed(uint8 level)
{
/* No clock adjustment is necessary for SAM4S */
if ((level == HIGH) || (level == LOW))
return M2M_SUCCESS;
return M2M_ERR_INVALID_ARG;
}

View File

@ -0,0 +1,265 @@
/**
*
* \file
*
* \brief WINC Driver Common API Declarations.
*
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
/** @defgroup COMMON Common
@{
@defgroup COMMONDEF Defines
@defgroup COMMONAPI Functions
@}
*/
#ifndef _NM_COMMON_H_
#define _NM_COMMON_H_
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_debug.h"
/**@addtogroup COMMONDEF
* @{
*/
#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)
#define M2M_ERR_INVALID ((sint8)-16)
/* I2C MASTER ERR */
#define I2C_ERR_LARGE_ADDRESS 0xE1UL /*!< The address exceeds 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 bytes in flash NMIS. */
#define ERR_FIRMWARE_EXCEED_SIZE 0xE5UL /*!< Total size of firmware exceeds 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)
/*! Maximum of two values */
#define M2M_MAX(A,B) ((A) > (B) ? (A) : (B))
/*! Choose one of three values */
#define M2M_SEL(x,m1,m2,m3) ((x>1)?((x>2)?(m3):(m2)):(m1))
/*! Align to next multiple of 4 */
#define WORD_ALIGN(val) (((val) & 0x03) ? ((val) + 4 - ((val) & 0x03)) : (val))
#define DATA_PKT_OFFSET 4
#if _BYTE_ORDER == _LITTLE_ENDIAN
/*! Most significant byte of 32bit word (LE) */
#define BYTE_0(word) ((uint8)(((word) >> 0) & 0x000000FFUL))
/*! Second most significant byte of 32bit word (LE) */
#define BYTE_1(word) ((uint8)(((word) >> 8) & 0x000000FFUL))
/*! Third most significant byte of 32bit word (LE) */
#define BYTE_2(word) ((uint8)(((word) >> 16) & 0x000000FFUL))
/*! Least significant byte of 32bit word (LE) */
#define BYTE_3(word) ((uint8)(((word) >> 24) & 0x000000FFUL))
#else
/*! Most significant byte of 32bit word (BE) */
#define BYTE_0(word) ((uint8)(((word) >> 24) & 0x000000FFUL))
/*! Second most significant byte of 32bit word (BE) */
#define BYTE_1(word) ((uint8)(((word) >> 16) & 0x000000FFUL))
/*! Third most significant byte of 32bit word (BE) */
#define BYTE_2(word) ((uint8)(((word) >> 8) & 0x000000FFUL))
/*! Least significant byte of 32bit word (BE) */
#define BYTE_3(word) ((uint8)(((word) >> 0) & 0x000000FFUL))
#endif
/**@}*/
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @ingroup COMMONAPI
* @fn void m2m_memcpy(uint8* pDst, uint8* pSrc, uint32 sz);
* @brief Copy specified number of bytes from source buffer to destination buffer.
* @param [in] sz
* Number of data bytes to copy.
* @param [in] pSrc
* Source buffer.
* @param [out] pDst
* Destination buffer.
* @return None
*/
NMI_API void m2m_memcpy(uint8 *pDst, const uint8 *pSrc, uint32 sz);
/*!
* @ingroup COMMONAPI
* @fn void m2m_memset(uint8* pBuf, uint8 val, uint32 sz);
* @brief Set specified number of data bytes in specified data buffer to specified value.
* @param [in] sz
* Number of data bytes (in specified data buffer whose values are to be set to the specified value).
* @param [in] val
* The specified value (to which data bytes in data buffer will be set).
* @param [out] pBuf
* The specified data buffer (whose data bytes will be set to the specified value).
* @return None
*/
NMI_API void m2m_memset(uint8 *pBuf, uint8 val, uint32 sz);
/*!
* @ingroup COMMONAPI
* @fn uint16 m2m_strlen(uint8 * pcStr);
* @brief Returns the length of a null terminated string buffer.
* @param [in] pcStr
* Null terminated string buffer.
* @return Length of the string in the specified string buffer.
*/
NMI_API uint16 m2m_strlen(uint8 *pcStr);
/*!
* @ingroup COMMONAPI
* @fn sint8 m2m_memcmp(uint8 *pu8Buff1, uint8 *pu8Buff2, uint32 u32Size);
* @brief Compare specified number of data bytes in pu8Buff1 and pu8Buff2 and decide if they all match.
* @param [in] u32Size
* Number of data bytes to compare.
* @param [in] pu8Buff1
* One of two data buffers for the comparison.
* @param [in] pu8Buff2
* One of two data buffers for the comparison.
* @return Zero if matched, one if not matched.
*/
NMI_API sint8 m2m_memcmp(uint8 *pu8Buff1, uint8 *pu8Buff2, uint32 u32Size);
/*!
* @ingroup COMMONAPI
* @fn uint8 m2m_strncmp(uint8 *pcS1, uint8 *pcS2, uint16 u16Len);
* @brief Compare specified number of data bytes in string buffers pcS1 and pcS2.
* @param [in] u16Len
* Number of data bytes to compare.
* @param [in] pcS1
* First of two string buffers for the comparison.
* @param [in] pcS2
* Second of two string buffers for the comparison.
* @return 0 if matched, -1 if the first non-matching byte in pcS1 is smaller than that in pcS2, +1 if it is bigger.
*/
NMI_API uint8 m2m_strncmp(uint8 *pcS1, uint8 *pcS2, uint16 u16Len);
/*!
* @ingroup COMMONAPI
* @fn uint8 * m2m_strstr(uint8 *pcIn, uint8 *pcStr);
* @brief Find the occurrence of pcStr string in pcIn string.
* @param [in] pcStr
* One of two string buffers.
* @param [in] pcIn
* One of two string buffers.
* @return If pcStr string is part of pcIn string return a valid pointer to the start of pcStr within pcIn. If not, a NULL Pointer is returned.
*/
NMI_API uint8 *m2m_strstr(uint8 *pcIn, uint8 *pcStr);
/*!
* @ingroup COMMONAPI
* @fn uint8 m2m_checksum(uint8* buf, int sz);
* @brief Calculates checksum for the specified number of data bytes in specified data buffer.
* @param [in] sz
* Number of data bytes used in the checksum calculation.
* @param [in] buf
* The specified data buffer (whose data bytes will be used to calculate the checksum).
* @return The calculated checksum.
*/
NMI_API uint8 m2m_checksum(uint8 *buf, int sz);
/*!
* @ingroup COMMONAPI
* @fn sint8 hexstr_2_bytes(uint8 *pu8Out, uint8 *pu8In, uint8 u8SizeOut);
* @brief Converts a string of hex characters to bytes.
* @param[out] pu8Out
* Output buffer (eg {0x11, 0x12, 0x13,...})
* @param[in] pu8In
* Input buffer (eg {0x31, 0x31, 0x31, 0x32, 0x31, 0x33, ...})
* @param[in] u8SizeOut
* Length of output buffer (should be half of the length of the input buffer).
* @return @ref M2M_SUCCESS if successful, M2M_ERR_INVALID_ARG otherwise (eg unrecognised hexchar in input).
*/
sint8 hexstr_2_bytes(uint8 *pu8Out, uint8 *pu8In, uint8 u8SizeOut);
/*!
* @ingroup COMMONAPI
* @fn void (*at_sb_printf)(const char *_format, ...);
* @brief Chooses which function to use in order to output debug.
*/
// NMI_API void (*at_sb_printf)(const char *_format, ...);
#ifdef __cplusplus
}
#endif
#endif /*_NM_COMMON_H_*/

View File

@ -0,0 +1,88 @@
/**
*
* \file
*
* \brief This module contains debug APIs declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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 __APS3_CORTUS__)
#define M2M_LOG_LEVEL M2M_LOG_INFO
#else
#define M2M_LOG_LEVEL M2M_LOG_REQ
#endif
#define M2M_ERR(...)
#define M2M_INFO(...)
#define M2M_REQ(...)
#define M2M_DBG(...)
#define M2M_PRINT(...)
#if (CONF_WINC_DEBUG == 1)
#undef M2M_PRINT
#define M2M_PRINT(...) do{CONF_WINC_PRINTF(__VA_ARGS__);}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 /*M2M_LOG_DBG*/
#endif /*M2M_LOG_REQ*/
#endif /*M2M_LOG_INFO*/
#endif /*M2M_LOG_ERROR*/
#endif /*CONF_WINC_DEBUG */
/**@}*/
#endif /* _NM_DEBUG_H_ */

View File

@ -0,0 +1,160 @@
/**
*
* \file
*
* \brief This module contains common APIs declarations.
*
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "common/include/nm_common.h"
#include <cstring>
void m2m_memcpy(uint8 *pDst, const uint8 *pSrc, uint32 sz)
{
memcpy(pDst, pSrc, 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 occurrence 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;
}
/* Convert hexchar to value 0-15 */
static uint8 hexchar_2_val(uint8 ch)
{
/* ch -= '0' */
ch -= 0x30;
if(ch <= 9)
return ch;
/* OR with 0x20 to convert upper case to lower case. */
ch |= 0x20;
/* ch -= ('a'-'0') */
ch -= 0x31;
if(ch <= 5)
return ch + 10;
return 0xFF;
}
/* Convert hexstring to bytes */
sint8 hexstr_2_bytes(uint8 *pu8Out, uint8 *pu8In, uint8 u8SizeOut)
{
while(u8SizeOut--)
{
uint8 u8Out = hexchar_2_val(*pu8In++);
if(u8Out > 0xF)
return M2M_ERR_INVALID_ARG;
*pu8Out = u8Out * 0x10;
u8Out = hexchar_2_val(*pu8In++);
if(u8Out > 0xF)
return M2M_ERR_INVALID_ARG;
*pu8Out += u8Out;
pu8Out++;
}
return M2M_SUCCESS;
}

View File

@ -0,0 +1,238 @@
/**
*
* \file
*
* \brief WINC Application Interface Internal Types.
*
* Copyright (c) 2017-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef __ECC_TYPES_H__
#define __ECC_TYPES_H__
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "m2m_types.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#define ECC_LARGEST_CURVE_SIZE (32)
/*!<
The size of the the largest supported EC. For now, assuming
the 256-bit EC is the largest supported curve type.
*/
#define ECC_POINT_MAX_SIZE ECC_LARGEST_CURVE_SIZE
/*!<
Maximum size of one coordinate of an EC point.
*/
#define ECC_POINT_MAX_SIZE_WORDS (ECC_POINT_MAX_SIZE / 4)
/*!<
SIZE in 32-bit words.
*/
#if 0
#define ECC_NUM_SUPP_CURVES ((sizeof(gastrECCSuppList)) / (sizeof(tstrEllipticCurve)))
#endif
/*!<
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
@enum \
tenuEcNamedCurve
@brief EC Named Curves
Defines a list of supported ECC named curves.
*/
typedef enum EcNamedCurve{
EC_SECP192R1 = 19,
/*!<
It is defined by NIST as P192 and by the SEC Group as secp192r1.
*/
EC_SECP256R1 = 23,
/*!<
It is defined by NIST as P256 and by the SEC Group as secp256r1.
*/
EC_SECP384R1 = 24,
/*!<
It is defined by NIST as P384 and by the SEC Group as secp384r1.
*/
EC_SECP521R1 = 25,
/*!<
It is defined by NIST as P521 and by the SEC Group as secp521r1.
*/
EC_UNKNOWN = 255
}tenuEcNamedCurve;
/*!
@struct \
tstrECPoint
@brief Elliptic Curve point representation
*/
typedef struct EcPoint{
uint8 X[ECC_POINT_MAX_SIZE];
/*!<
The X-coordinate of the ec point.
*/
uint8 Y[ECC_POINT_MAX_SIZE];
/*!<
The Y-coordinate of the ec point.
*/
uint16 u16Size;
/*!<
Point size in bytes (for each of the coordinates).
*/
uint16 u16PrivKeyID;
/*!<
ID for the corresponding private key.
*/
}tstrECPoint;
/*!
@struct \
tstrECDomainParam
@brief ECC Curve Domain Parameters
The structure defines the ECC domain parameters for curves defined over prime finite fields.
*/
typedef struct EcDomainParam{
uint32 p[ECC_POINT_MAX_SIZE_WORDS];
uint32 a[ECC_POINT_MAX_SIZE_WORDS];
uint32 b[ECC_POINT_MAX_SIZE_WORDS];
tstrECPoint G;
}tstrECDomainParam;
/*!
@struct \
tstrEllipticCurve
@brief
Definition of an elliptic curve
*/
typedef struct{
tenuEcNamedCurve enuType;
tstrECDomainParam strParam;
}tstrEllipticCurve;
typedef enum{
ECC_REQ_NONE,
ECC_REQ_CLIENT_ECDH,
ECC_REQ_SERVER_ECDH,
ECC_REQ_GEN_KEY,
ECC_REQ_SIGN_GEN,
ECC_REQ_SIGN_VERIFY
}tenuEccREQ;
typedef struct{
tstrECPoint strPubKey;
uint8 au8Key[ECC_POINT_MAX_SIZE];
}tstrEcdhReqInfo;
typedef struct{
uint32 u32nSig;
}tstrEcdsaVerifyReqInfo;
typedef struct{
uint16 u16CurveType;
uint16 u16HashSz;
}tstrEcdsaSignReqInfo;
typedef struct{
uint16 u16REQ;
uint16 u16Status;
uint32 u32UserData;
uint32 u32SeqNo;
union{
tstrEcdhReqInfo strEcdhREQ;
tstrEcdsaSignReqInfo strEcdsaSignREQ;
tstrEcdsaVerifyReqInfo strEcdsaVerifyREQ;
};
}tstrEccReqInfo;
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
GLOBALS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#if 0
static tstrEllipticCurve gastrECCSuppList[] = {
{
EC_SECP256R1,
{
{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF},
{0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF},
{0x27D2604B, 0x3BCE3C3E, 0xCC53B0F6, 0x651D06B0, 0x769886BC, 0xB3EBBD55, 0xAA3A93E7, 0x5AC635D8},
{
{
0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2,
0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96
},
{
0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16,
0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5
},
32
}
}
}
};
#endif
/*!<
List of supported Elliptic Curves ordered by security level (most secure curve is at index ZERO).
*/
#endif /* __ECC_TYPES_H__ */

View File

@ -0,0 +1,728 @@
/**
*
* \file
*
* \brief WINC ATE Test Driver Interface.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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"
/** \defgroup m2m_ate ATE
*/
/**@defgroup ATEDefine Defines
* @ingroup m2m_ate
* @{
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
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 completed successfully.
*/
#define M2M_ATE_ERR_VALIDATE (M2M_ERR_FAIL)
/*!< Error in parameters passed to functions.
*/
#define M2M_ATE_ERR_TX_ALREADY_RUNNING (-1)
/*!< Error in starting a transmission test. Another test is already running and its not allowed to start another ATE test.
*/
#define M2M_ATE_ERR_RX_ALREADY_RUNNING (-2)
/*!< Error in starting a reception test. Another test is already running and its not allowed to start another ATE test.
*/
#define M2M_ATE_ERR_UNHANDLED_CASE (-3)
/*!< Invalid case.
*/
#define M2M_ATE_RX_DISABLE_DA 0x0
/*!< Filter selection for received frames: Disable filtering received frames by the destination address.
*/
#define M2M_ATE_RX_ENABLE_DA 0x1
/*!< Filter selection for received frames: Enable filtering received frames by the destination address.
*/
#define M2M_ATE_RX_DISABLE_SA 0x0
/*!< Filter selection for received frames: Disable filtering received frames by the source address.
*/
#define M2M_ATE_RX_ENABLE_SA 0x1
/*!< Filter selection for received frames: Enable filtering received frames by the source address.
*/
#define M2M_ATE_DISABLE_SELF_MACADDR 0x0
/*!<Disable setting a new mac address through the ATE test application and use the pre-set mac address in the firmware.
*/
#define M2M_ATE_SET_SELF_MACADDR 0x1
/*!<Enable setting a new mac address through the ATE test application and use the pre-set mac address.
*/
#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
*/
//@}
/**@defgroup ATEDataTypes DataTypes
* @ingroup m2m_ate
* @{
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
*@enum tenuM2mAteFwState
*@brief Enumeration used to change ATE firmware states
*/
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 Enumeration used to index the TX rates that can be used during the transmission test.
*/
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 Enumeration used to index the TX duty cycle that can be used during the transmission test.
*/
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;
/*!
*@enum tenuM2mAteTxDpdControl
*@brief Enumeration for the allowed Digital-pre distortion(DPD) control values.
*/
typedef enum {
M2M_ATE_TX_DPD_DYNAMIC = 0x00,
/*!< Dynamic mode indicates that DPD values will be set dynamically from a lookup table pre-set with the DPD coefficients.
*/
M2M_ATE_TX_DPD_BYPASS = 0x01,
/*!< Bypass mode indicates that the DPD control will be bypassed.
*/
M2M_ATE_TX_DPD_ENABLED = 0x02,
/*!< Enabled mode allows the tester to manually set the DPD coefficients.
*/
}tenuM2mAteTxDpdControl;
/*!
*@enum tenuM2mAteTxGainSetting
*@brief Enumeration for the allowed TX gain selection modes.
*/
typedef enum {
M2M_ATE_TX_GAIN_DYNAMIC = 0x00,
/*!< Dynamic mode indicates that Tx gain values for the digital gain,pa and ppa, will be set dynamically from a lookup table based on the Tx_rate configured.
*/
M2M_ATE_TX_GAIN_BYPASS = 0x01,
/*!< Bypass mode indicates that Tx gain configurations will be bypassed.
*/
M2M_ATE_TX_GAIN_FCC = 0x02,
/*!< Using the FCC tx gain configuration indicates that the tx gain values will be used from the FCC flashed table(pre-configured values from a customer).
*/
M2M_ATE_TX_GAIN_TELEC = 0x03,
/*!< Using the TELEC tx gain configuration indicates that the tx gain values will be used from the TELEC flashed table(pre-configured values from a customer).
*/
}tenuM2mAteTxGainSetting;
/*!
*@enum tenuM2mAtePMUSetting
*@brief Used to Enable PMU or disable it
*/
typedef enum {
M2M_ATE_PMU_DISBLE = 0x00,
/*!< Disable using PMU mode
*/
M2M_ATE_PMU_ENABLE = 0x01,
/*!< Enable using PMU mode
*/
}tenuM2mAtePMUSetting;
/*!
*@enum tenuM2mAteTxSource
*@brief Used to define the Tx source, either PHY mode or MAC mode.
*/
typedef enum {
M2M_ATE_TX_SRC_MAC = 0x00,
/*!< When the TX Source is set to MAC, it indicates that the TX frames are manually framed and sent from the MAC layer
*/
M2M_ATE_TX_SRC_PHY = 0x01,
/*!< When the TX source is set to PHY, it indicates that transmission sequence occurs from PHY layer in the form of pulses
*/
}tenuM2mAteTxSource;
/*!
*@enum tenuM2mAteTxMode
*@brief Used to define the mode of PHY TX transmission source: Continuous Wave(CW) or Normal(i.e CW is disabled) TX sequence
*/
typedef enum {
M2M_ATE_TX_MODE_NORM = 0x00,
/*!< When the TX source is set to PHY,normal mode indicates that continuous transmission is disabled.
*/
M2M_ATE_TX_MODE_CW = 0x01,
/*!< When the TX source is set to PHY, continuous mode indicates that transmission sequences occur back to back in a continuous wave from the PHY layer.
*/
}tenuM2mAteTxMode;
/*!
*@enum tenuM2mAteRxPwrMode
*@brief Used to define type of RX mode either high power or low power
*/
typedef enum {
M2M_ATE_RX_PWR_HIGH = 0x00,
/*!< Indicates that receive mode is operating at high power
*/
M2M_ATE_RX_PWR_LOW = 0x01,
/*!< Indicates that receive mode is operating at low power
*/
}tenuM2mAteRxPwrMode;
/*!
*@enum tenuM2mAteChannels
*@brief Available channels for TX and RX in the 2.4GHz spectrum starting at 2412MHz with a 5MHz bandwidth.
*/
typedef enum {
M2M_ATE_CHANNEL_1 = 0x01,
/*!< Channel 1: 2412MHz
*/
M2M_ATE_CHANNEL_2 = 0x02,
/*!< Channel 2: 2417MHz
*/
M2M_ATE_CHANNEL_3 = 0x03,
/*!< Channel 3: 2422MHz
*/
M2M_ATE_CHANNEL_4 = 0x04,
/*!< Channel 4: 2427MHz
*/
M2M_ATE_CHANNEL_5 = 0x05,
/*!< Channel 5: 2432MHz
*/
M2M_ATE_CHANNEL_6 = 0x06,
/*!< Channel 6: 2437MHz
*/
M2M_ATE_CHANNEL_7 = 0x07,
/*!< Channel 7: 2442MHz
*/
M2M_ATE_CHANNEL_8 = 0x08,
/*!< Channel 8: 2447MHz
*/
M2M_ATE_CHANNEL_9 = 0x09,
/*!< Channel 9: 2452MHz
*/
M2M_ATE_CHANNEL_10 = 0x0A,
/*!< Channel 10: 2462MHz
*/
M2M_ATE_CHANNEL_11 = 0x0B,
/*!< Channel 11: 2467MHz
*/
M2M_ATE_CHANNEL_12 = 0x0C,
/*!< Channel 12: 2472MHz
*/
M2M_ATE_CHANNEL_13 = 0x0D,
/*!< Channel 13: 2472MHz
*/
M2M_ATE_CHANNEL_14 = 0x0E,
/*!< Channel 14: 2484MHz
*/
}tenuM2mAteChannels;
/*!
*@struct tstrM2mAteRxStatus
*@brief Used to save statistics for receive(RX) test case
*/
typedef struct {
uint32 num_rx_pkts;
/*!< Number of total RX packets
*/
uint32 num_err_pkts;
/*!< Number of RX failed packets
*/
uint32 num_good_pkts;
/*!< Number of RX packets actually received
*/
} tstrM2mAteRxStatus;
/*!
*@struct tstrM2mAteRxStatus
*@brief Used to save receive test case configuration
*@see tenuM2mAteRxPwrMode
*/
typedef struct {
uint8 u8RxPwrMode;
/*!< RX power mode review \ref tenuM2mAteRxPwrMode
*/
} tstrM2mAteInit;
/*!
*@struct tstrM2mAteTx
*@brief Used for the transmission(Tx) test configuration.
*/
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 send packets, to select a rate use values from the enumeration \ref tenuM2mAteTxIndexOfRates and pass it to \ref m2m_ate_get_tx_rate
*/
uint8 channel_num;
/*!< Channel number as enumerated at \ref tenuM2mAteChannels
*/
uint8 duty_cycle;
/*!< Duty cycle value between from 1 to 10, where maximum = 1, minimum = 10. As enumerated \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 Phy TX transmission either normal TX sequence or CW(Continuous Wave) TX sequence \ref tenuM2mAteTxMode
*/
uint32 xo_offset_x1000;
/*!< Signed XO offset value in Part Per Million(PPM) 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 for the reception(Rx) test configuration.
*/
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 overridden.
*/
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. Using the following flags \ref M2M_ATE_RX_ENABLE_DA
\ref M2M_ATE_RX_DISABLE_DA
*/
uint8 mac_filter_en_sa;
/*!< Flag set to enable or disable reception with source address as a filter.Using the following flags \ref M2M_ATE_RX_ENABLE_SA
\ref M2M_ATE_RX_DISABLE_SA
*/
uint8 override_self_mac_addr;
/*!< Flag set to enable or disable self mac address feature. Using the following flags \ref M2M_ATE_DISABLE_SELF_MACADDR
\ref M2M_ATE_SET_SELF_MACADDR
*/
} tstrM2mAteRx;
//@}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#ifdef __cplusplus
extern "C" {
#endif
/**@defgroup ATEFunction Function
* @ingroup m2m_ate
* @{
*/
/*!
@fn \
sint8 m2m_ate_init(void);
@brief
This function used to download the ATE firmware from flash and start it.
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
@see
m2m_ate_init_param
*/
sint8 m2m_ate_init(void);
/*!
@fn \
sint8 m2m_ate_init(tstrM2mAteInit *pstrInit);
@brief
This function is used to download and start the ATE firmware with an initialization value
stating the rx mode power \ref tstrM2mAteInit.
@param [in] tstrM2mAteInit *
Pointer to a structure \ref tstrM2mAteInit, defining the initial RX mode value.
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
@see
m2m_ate_init
*/
sint8 m2m_ate_init_param(tstrM2mAteInit *pstrInit);
/*!
@fn \
sint8 m2m_ate_deinit(void);
@brief
De-Initialization of ATE firmware mode
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
*/
sint8 m2m_ate_deinit(void);
/*!
@fn \
sint8 m2m_ate_set_fw_state(uint8);
@brief
This function is used to change the ATE firmware status from running to stopped or vice versa.
@param [in] u8State
Required state of the ATE firmware, one of \ref tenuM2mAteFwState enumeration values.
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
@see
m2m_ate_init
*/
sint8 m2m_ate_set_fw_state(uint8);
/*!
@fn \
sint8 m2m_ate_get_fw_state(uint8);
@brief
This function is used to return the status of ATE firmware.
@return
The function SHALL return the status of ATE firmware, one of \ref tenuM2mAteFwState enumeration values.
@see
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 is used to return value of TX rate required by application developer.
@param [in] u8Index
Index of the required rate , one of \ref tenuM2mAteTxIndexOfRates enumeration values.
@return
The function SHALL return 0 in case of receiving invalid index, otherwise the selected rate value is returned.
@see
tenuM2mAteTxIndexOfRates
*/
uint32 m2m_ate_get_tx_rate(uint8);
/*!
@fn \
sint8 m2m_ate_get_tx_status(void);
@brief
This function is used to return the status of TX test case either running or stopped.
@return
The function SHALL return the status of ATE firmware, 1 if TX test case is running or 0 if TX test case has been stopped.
@see
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 is used to start the TX test case.
@param [in] strM2mAteTx
Type of \ref tstrM2mAteTx, with the values required to enable TX test case. Application must use \ref m2m_ate_init first.
@return
The function SHALL return 0 for success and a negative value otherwise.
@see
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 is used to stop the TX test case.
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
@see
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 is used to return the status of RX test case either running or stopped.
@return
The function SHALL return status of ATE firmware, 1 if RX test case is running or 0 when the test case has been stopped.
@see
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 is used to start RX test case.
@param [in] strM2mAteRx
Type of \ref tstrM2mAteRx, with the values required to enable RX test case. Application must use \ref m2m_ate_init first.
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
@see
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 is used to stop RX test case.
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
@see
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 is used to read RX statistics from the ATE firmware.
@param [out] strM2mAteRxStatus
Type of \ref tstrM2mAteRxStatus used to save statistics of RX test case. Application must use \ref m2m_ate_start_rx first.
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
@see
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 value to the HW registers in dB.
@param [in] double dGaindB
The digital gain value required to be set.
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
@see
m2m_ate_get_dig_gain, m2m_ate_get_pa_gain,m2m_ate_get_ppa_gain,m2m_ate_get_tot_gain
*/
sint8 m2m_ate_set_dig_gain(double dGaindB);
/*!
@fn \
sint8 m2m_ate_get_dig_gain(double * dGaindB)
@brief
This function is used to retrieve the digital gain value from the HW registers in dB.
Digital gain is one of the values that are set to calculate the total tx gain value.
@param [out] double * dGaindB
The retrieved digital gain value obtained from HW registers in dB.
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
@see
m2m_ate_set_dig_gain, m2m_ate_get_pa_gain,m2m_ate_get_ppa_gain,m2m_ate_get_tot_gain
*/
sint8 m2m_ate_get_dig_gain(double * dGaindB);
/*!
@fn \
void m2m_ate_set_pa_gain(uint8 gain_db)
@brief
This function is used to set the PA gain (18/15/12/9/6/3/0 only)
@param [in] uint8 gain_db
PA gain level allowed (18/15/12/9/6/3/0 only)
*/
void m2m_ate_set_pa_gain(uint8 gain_db);
/*!
@fn \
sint8 m2m_ate_get_pa_gain(double *paGaindB)
@brief
This function is used to get the Power Amplifier(PA) gain
@param [out] double *paGaindB
The retrieved PA gain value obtained from HW registers in dB.
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
@see
m2m_ate_set_dig_gain, m2m_ate_get_dig_gain,m2m_ate_get_ppa_gain,m2m_ate_get_tot_gain
*/
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 Pre-Power Amplifier(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.
@see
m2m_ate_set_dig_gain, m2m_ate_get_dig_gain,m2m_ate_get_pa_gain,m2m_ate_get_tot_gain
*/
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 tx gain value
@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 @ref M2M_SUCCESS for success and a negative value otherwise.
@see
m2m_ate_set_dig_gain, m2m_ate_get_dig_gain,m2m_ate_get_pa_gain,m2m_ate_get_ppa_gain
*/
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,264 @@
/**
*
* \file
*
* \brief WINC Crypto Application Interface.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef __M2M_CRYPTO_H__
#define __M2M_CRYPTO_H__
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "common/include/nm_common.h"
#include "driver/include/m2m_types.h"
#include "driver/source/m2m_hif.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#define M2M_MAX_RSA_LEN (256)
#define M2M_SHA256_DIGEST_LEN 32
#define M2M_SHA256_MAX_DATA (M2M_BUFFER_MAX_SIZE - M2M_SHA256_CONTEXT_BUFF_LEN - M2M_HIF_HDR_OFFSET)
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
@struct \
tstrM2mSha256Ctxt
@brief
SHA256 context data
*/
typedef struct sha256ctxt{
uint32 au32Sha256CtxtBuff[M2M_SHA256_CONTEXT_BUFF_LEN/sizeof(uint32)];
} tstrM2mSha256Ctxt;
/*!
@enum \
tenuRsaSignStatus
@brief
RSA Signature status: pass or fail.
@see
m2m_crypto_rsa_sign_gen
*/
typedef enum{
M2M_RSA_SIGN_OK,
M2M_RSA_SIGN_FAIL
} tenuRsaSignStatus;
/*!
@typedef \
tpfAppCryproCb
@brief Crypto Callback function receiving the crypto related messages
@param [in] u8MsgType
Crypto command about which the notification is received.
@param [in] pvResp
A pointer to the result associated with the notification.
@param [in] pvMsg
A pointer to a buffer containing the notification parameters (if any). It should be
Casted to the correct data type corresponding to the notification type.
@see
m2m_crypto_init
tenuM2mCryptoCmd
*/
typedef void (*tpfAppCryproCb) (uint8 u8MsgType,void * pvResp, void * pvMsg);
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#ifdef __cplusplus
extern "C" {
#endif
/*!
@fn \
sint8 m2m_crypto_init();
@brief crypto initialization.
@param[in] pfAppCryproCb
Pointer to the Crypto Callback function receiving the crypto related messages.
@see
tpfAppCryproCb
@return
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
*/
sint8 m2m_crypto_init(tpfAppCryproCb pfAppCryproCb);
/*!
@fn \
sint8 m2m_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt);
@brief SHA256 hash initialization
@param[in] psha256Ctxt
Pointer to a sha256 context allocated by the caller.
@return
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
*/
sint8 m2m_crypto_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt);
/*!
@fn \
sint8 m2m_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Data, uint16 u16DataLength);
@brief SHA256 hash update
@param [in] psha256Ctxt
Pointer to the sha256 context.
@param [in] pu8Data
Buffer holding the data submitted to the hash.
@param [in] u16DataLength
Size of the data buffer in bytes.
@pre SHA256 module should be initialized first through m2m_crypto_sha256_hash_init function.
@see m2m_crypto_sha256_hash_init
@return
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
*/
sint8 m2m_crypto_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Data, uint16 u16DataLength);
/*!
@fn \
sint8 m2m_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Sha256Digest);
@brief SHA256 hash finalization
@param[in] psha256Ctxt
Pointer to a sha256 context allocated by the caller.
@param [in] pu8Sha256Digest
Buffer allocated by the caller which will hold the resultant SHA256 Digest. It must be allocated no less than M2M_SHA256_DIGEST_LEN.
@return
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
*/
sint8 m2m_crypto_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Sha256Digest);
/*!
@fn \
sint8 m2m_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash, \
uint16 u16HashLength, uint8 *pu8RsaSignature);
@brief RSA Signature Verification
The function shall request the RSA Signature verification from the WINC Firmware for the given message. The signed message shall be
compressed to the corresponding hash algorithm before calling this function.
The hash type is identified by the given hash length. For example, if the hash length is 32 bytes, then it is SHA256.
@param[in] pu8N
RSA Key modulus n.
@param[in] u16NSize
Size of the RSA modulus n in bytes.
@param[in] pu8E
RSA public exponent.
@param[in] u16ESize
Size of the RSA public exponent in bytes.
@param[in] pu8SignedMsgHash
The hash digest of the signed message.
@param[in] u16HashLength
The length of the hash digest.
@param[out] pu8RsaSignature
Signature value to be verified.
@return
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
*/
sint8 m2m_crypto_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash,
uint16 u16HashLength, uint8 *pu8RsaSignature);
/*!
@fn \
sint8 m2m_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash, \
uint16 u16HashLength, uint8 *pu8RsaSignature);
@brief RSA Signature Generation
The function shall request the RSA Signature generation from the WINC Firmware for the given message. The signed message shall be
compressed to the corresponding hash algorithm before calling this function.
The hash type is identified by the given hash length. For example, if the hash length is 32 bytes, then it is SHA256.
@param[in] pu8N
RSA Key modulus n.
@param[in] u16NSize
Size of the RSA modulus n in bytes.
@param[in] pu8d
RSA private exponent.
@param[in] u16dSize
Size of the RSA private exponent in bytes.
@param[in] pu8SignedMsgHash
The hash digest of the signed message.
@param[in] u16HashLength
The length of the hash digest.
@param[out] pu8RsaSignature
Pointer to a user buffer allocated by the caller shall hold the generated signature.
@return
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
*/
sint8 m2m_crypto_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash,
uint16 u16HashLength, uint8 *pu8RsaSignature);
#ifdef __cplusplus
}
#endif
#endif /* __M2M_CRYPTO_H__ */

View File

@ -0,0 +1,888 @@
/**
*
* \file
*
* \brief WINC OTA Upgrade API Interface.
*
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
/**@defgroup OTAAPI OTA
@brief
The WINC supports OTA (Over-The-Air) updates. Using the APIs described in this module,
it is possible to request an ATWINC15x0 to update its firmware image, or safely rollback to
the previous firmware image.\n Note that it is NOT possible to update other areas of the WINC
flash (e.g. the HTTP file area) using the OTA mechanism.\n\n There are also APIs to download
files and store them in the WINC's Flash (supported by ATWINC1510 only), which can be used
for Host MCU OTA updates or accessing information stored remotely.
@{
@defgroup OTACALLBACKS Callbacks
@brief
Lists the different callbacks that can be used during OTA updates.\n
Callbacks of type @ref tpfOtaNotifCb and @ref tpfOtaUpdateCb should be passed
onto @ref m2m_ota_init at system initialization. Other callbacks are provided
to handle the various steps of Host File Download.
@defgroup OTADEFINE Defines
@brief
Specifies the macros and defines used by the OTA APIs.
@defgroup OTATYPEDEF Enumerations and Typedefs
@brief
Specifies the enums and Data Structures used by the OTA APIs.
@defgroup OTAFUNCTIONS Functions
@brief
Lists the full set of available APIs to manage OTA updates and Host File Downloads.
@{
@defgroup OTACOMMON Common
@defgroup WINCOTA WINC
@defgroup HFD HFD
@}
@}
*/
#ifndef __M2M_OTA_H__
#define __M2M_OTA_H__
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "common/include/nm_common.h"
#include "driver/include/m2m_types.h"
#include "driver/source/nmdrv.h"
#include <stddef.h>
/**@addtogroup OTATYPEDEF
* @{
*/
/*!
@enum \
tenuOTASSLOption
@brief
Enumeration for OTA SSL options
The following SSL options can be set for OTA
*/
typedef enum {
WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH = 0x1,
/*!<Server authentication for OTA SSL connections. Values are of type int \n
1: Bypass server authentication.\n*/
WIFI_OTA_SSL_OPT_SNI_VALIDATION = 0x2,
/*!<Server Name Indication. The actual server name to send must be passed using option @ref WIFI_OTA_SSL_OPT_SNI_SERVERNAME \n
Values are of type int \n
0: Do not check the received servername against the server provided one\n
1: Check the received servername against the server provided one\n
*/
WIFI_OTA_SSL_OPT_SNI_SERVERNAME = 0x4,
/*!<The server name string to send in the SNI extension. \n
Value is a null terminated string up to 64 characters in length including the null terminator.\n*/
} tenuOTASSLOption;
/**@}*/ //OTATYPEDEF
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/**@addtogroup OTACALLBACKS
* @{
*/
/*!
@typedef void (*tpfOtaNotifCb) (tstrOtaUpdateInfo *pstrOtaUpdateInfo);
@brief
A callback to get notification about a 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 provides the status type and its status.\n
The OTA callback provides the download status, the switch to the downloaded firmware status,
roll-back status and Host File Download status.
@param[in] u8OtaUpdateStatusType
Possible values are listed in @ref tenuOtaUpdateStatusType.
@param[in] u8OtaUpdateStatus
Possible values are listed as enumerated by @ref tenuOtaUpdateStatus.
@note
Executes other callbacks passed to the OTA module.
@see
tenuOtaUpdateStatusType
tenuOtaUpdateStatus
*/
typedef void (*tpfOtaUpdateCb)(uint8 u8OtaUpdateStatusType, uint8 u8OtaUpdateStatus);
/*!
@typedef void (*tpfFileGetCb) (uint8 u8Status, uint8 u8Handler, uint32 u32Size);
@brief
A callback to notify the application of the result of the download (success/fail),
the generated handler ID and the size of the file which has just finished
downloading (size expressed in bytes).
@param[in] u8Status
Status of the operation (see @ref tenuOtaUpdateStatus).
@param[in] u8Handler
Generated handler ID for the new file.
@param[in] u32Size
Total size of the downloaded file (in bytes).
@warning
The file handler passed onto this callback will be the valid file handler generated
by the WINC when the download finished successfully. This handler will be required
for all operations on the file like read and erase.
*/
typedef void (*tpfFileGetCb)(uint8 u8Status, uint8 u8Handler, uint32 u32Size);
/*!
@typedef void (*tpfFileReadCb) (uint8 u8Status, void *pBuff, uint32 u32Size);
@brief
A callback to handle a buffer of data after requesting a Host File read.
The callback will provide the status of the read operation and if successful,
a pointer to a valid placeholder containing the data read and the amount of
data available. Such callback is required when using Host File read via the HIF.
@param[in] u8Status
Status of the operation (see @ref tenuOtaUpdateStatus).
@param[in] pBuff
Pointer to a placeholder where the data can be retrieved from.
@param[in] u32Size
Amount of data available after reading (in bytes).
@warning
After the callback is executed, pBuff will be freed.
*/
typedef void (*tpfFileReadCb)(uint8 u8Status, void *pBuff, uint32 u32Size);
/*!
@typedef void (*tpfFileEraseCb) (uint8 u8Status);
@brief
A callback executed when the file erase has been completed.
@param[in] u8Status
Status of the operation (see @ref tenuOtaUpdateStatus).
*/
typedef void (*tpfFileEraseCb)(uint8 u8Status);
/**@}*/ //OTACALLBACKS
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#ifdef __cplusplus
extern "C" {
#endif
/*!
@ingroup OTACOMMON
@fn \
sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb);
@brief
Synchronous initialization function for the OTA layer by registering the update callback.\n
The notification callback is not supported at the current version. Calling this API is a
MUST for all the OTA API's.
@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);
/*!
@ingroup WINCOTA
@fn \
sint8 m2m_ota_notif_set_url(uint8 * u8Url);
@brief
Set the OTA notification server URL, the function needs to be called before any check for update.\n
This functionality is not supported by WINC firmware.
@param[in] u8Url
Set the OTA notification server URL, the function needs to be called before any check for update.
@pre
Prior calling of @ref m2m_ota_init is required.
@warning
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);
/*!
@ingroup WINCOTA
@fn \
sint8 m2m_ota_notif_check_for_update(void);
@brief
Synchronous function to check for the OTA update using the Notification Server URL.\n
Function is not implemented (not supported at the current version).
@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);
/*!
@ingroup WINCOTA
@fn \
sint8 m2m_ota_notif_sched(uint32 u32Period);
@brief
Schedule OTA notification Server check for update request after specific number of days.\n
Function is not implemented (not supported at the current version).
@param[in] u32Period
Period in days
@warning
Function is not implemented (not supported at the current version).
@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);
/*!
@ingroup WINCOTA
@fn \
sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl);
@brief
Request OTA start update using the download URL. The OTA module will download the OTA image, ensure integrity of the image
and update the validity of the image in the control structure. On completion, a callback of type @ref tpfOtaUpdateCb is called
(callback previously provided via @ref m2m_ota_init ). Switching to the updated image additionally requires completion of
@ref m2m_ota_switch_firmware and @ref system_reset
@param[in] pcDownloadUrl
The download firmware URL, 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.\n
Calling this API invalidates any previous valid rollback image, irrespective of the result, but when
the OTA succeeds, the current image will become the rollback image after @ref m2m_ota_switch_firmware.
@pre
@ref m2m_ota_init is a prerequisite and must have been called before using @ref m2m_ota_start_update \n
Switching to the newly downloaded image requires calling @ref m2m_ota_switch_firmware API.
@sa
@ref m2m_ota_init
@ref m2m_ota_switch_firmware
@ref tpfOtaUpdateCb
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
Note that successful operation in this context means the OTA update request has reached the firmware OTA module.
It does not indicate whether or not the image update succeeded.
@section OTAExample Example
This example shows how an OTA image update and switch is carried out.
It demonstrates use of the following OTA APIs:
- @ref m2m_ota_init
- @ref tpfOtaUpdateCb
- @ref m2m_ota_start_update
- @ref m2m_ota_switch_firmware
- @ref m2m_ota_rollback
@code
static void OtaUpdateCb(uint8 u8OtaUpdateStatusType, uint8 u8OtaUpdateStatus)
{
M2M_INFO("%d %d\n", u8OtaUpdateStatusType, u8OtaUpdateStatus);
switch(u8OtaUpdateStatusType)
{
case DL_STATUS:
if(u8OtaUpdateStatus == OTA_STATUS_SUCCESS)
{
M2M_INFO("OTA download succeeded\n");
// In this case the application MAY WANT TO update the host driver before calling
// @ref m2m_ota_switch_firmware(). Switching firmware image and resetting without
// updating host driver may lead to suboptimal functionality.
// Switch to the upgraded firmware
M2M_INFO("Now switching active partition...\n");
m2m_ota_switch_firmware();
}
break;
case SW_STATUS:
case RB_STATUS:
if(u8OtaUpdateStatus == OTA_STATUS_SUCCESS)
{
M2M_INFO("Switch/Rollback succeeded\n");
// Start the host SW upgrade if required, then system reset is required (Reinitialize the driver)
M2M_INFO("Now resetting the system...\n");
system_reset();
}
break;
}
}
static void wifi_event_cb(uint8 u8WiFiEvent, void *pvMsg)
{
// ...
case M2M_WIFI_REQ_DHCP_CONF:
{
// After successful connection, start the OTA upgrade
m2m_ota_start_update(OTA_URL);
}
break;
default:
break;
// ...
}
int main (void)
{
tstrWifiInitParam param;
sint8 s8Ret = M2M_SUCCESS;
bool rollback_required = FALSE;
tstr1xAuthCredentials gstrCred1x = AUTH_CREDENTIALS;
// System init, etc should be here...
m2m_memset((uint8*)&param, 0, sizeof(param));
param.pfAppWifiCb = wifi_event_cb;
// Initialize the WINC Driver
s8Ret = m2m_wifi_init(&param);
if(s8Ret == M2M_ERR_FW_VER_MISMATCH)
{
M2M_ERR("Firmware version mismatch\n");
}
if (M2M_SUCCESS != s8Ret)
{
M2M_ERR("Driver Init Failed <%d>\n",s8Ret);
while(1);
}
// Initialize the OTA module
m2m_ota_init(OtaUpdateCb,NULL);
// Connect to AP that provides 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(unsigned char *pcDownloadUrl);
/*!
@ingroup WINCOTA
@fn \
sint8 m2m_ota_rollback(void);
@brief
Request OTA Roll-back to the old (inactive) WINC image, the WINC firmware will check the validity of the inactive image
and activate it if valid. On completion, a callback of type @ref tpfOtaUpdateCb is called (application must previously have
provided the callback via @ref m2m_ota_init). If the callback indicates successful activation, the newly-activated image
will start running after next system reset.
@warning
If rollback requires a host driver update in order to maintain HIF compatibility (HIF
major value change), then it is recommended to update the host driver prior to calling this API.\n
In the event of system reset with incompatible driver/firmware, compatibility can be
recovered by calling @ref m2m_ota_rollback or @ref m2m_ota_switch_firmware. See @ref OTAExample.
@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);
/*!
@ingroup OTACOMMON
@fn \
sint8 m2m_ota_abort(void);
@brief
Request the WINC to abort an OTA or Host File download in progress.\n
If no download is in progress, the API will respond with failure.
@sa
m2m_ota_init
m2m_ota_start_update
@return
The function returns @ref M2M_SUCCESS for a successful operation and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_abort(void);
/*!
@ingroup WINCOTA
@fn \
sint8 m2m_ota_switch_firmware(void);
@brief
Request switch to the updated WINC image. The WINC firmware will check the validity of the
inactive image and activate it if valid. On completion, a callback of type @ref tpfOtaUpdateCb
is called (application must previously have provided the callback via @ref m2m_ota_init).
If the callback indicates successful activation, the newly-activated image will start running
after next system reset.
@warning
If switch requires a host driver update in order to maintain HIF compatibility (HIF
major value change), then it is recommended to update the host driver prior to calling this API.\n
In the event of system reset with incompatible driver/firmware, compatibility can be
recovered by calling @ref m2m_ota_rollback or @ref m2m_ota_switch_firmware. See @ref OTAExample.
@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);
/*!
@ingroup HFD
@fn \
sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb);
@brief
Download a file from a remote location and store it in WINC's Flash.
@param[in] pcDownloadUrl
Url pointing to the remote file. HTTP/HTTPS only.
@param[in] pfHFDGetCb
Pointer to a callback (see @ref tpfFileGetCb) to be executed when the download finishes.
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
@pre
Requires @ref m2m_ota_init to be called before a download can start.
@warning
This functionality is only supported from WINC release 19.6.1 onwards.
The maximum file size that can be stored in WINC1510 is 508KB, the
WINC1500 variant is not supported for Host File Download.\n
Concurrent use of Host File Get and WINC OTA is not possible.\n
Providing a callback is mandatory.
@sa
m2m_ota_init
tpfFileGetCb
*/
NMI_API sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb);
/*!
@ingroup HFD
@fn \
sint8 m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb);
@brief
Read a certain amount of bytes from a file previously stored in WINC's Flash using HIF transfer.
@param[in] u8Handler
Handler of the file we are trying to read from. Must be valid.
@param[in] u32Offset
Offset from start of the file to read from (in bytes).
@param[in] u32Size
The amount of data to read (in bytes).
@param[in] pfHFDReadCb
Callback (see @ref tpfFileReadCb) to be executed when the read operation completes.
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
@pre
Requires @ref m2m_ota_init to be called before a read via HIF can be requested.
@warning
There is a limitation on how much data can be transferred at a time using HIF read, which is 128 bytes.
The limitation described above can potentially reduce the speed of the read due to extra overhead, but
using the HIF is non-blocking and therefore the Application can continue execution as normal, being
interrupted only when data is available. Another advantage is that it does not require the WINC to be
reset or put in download mode, as it is the case for reading the file via SPI (see @ref m2m_ota_host_file_read_spi).\n
A valid file handler must be provided, this means that it needs to match the handler internally stored
by the WINC and must not be @ref HFD_INVALID_HANDLER \n
Providing a callback is mandatory.
@note
When calling this API while specifying a size > 128 bytes, the read will be limited to the first 128 bytes
starting at the read offset. It it recommended that a read for sizes above 128 bytes is performed in
multiple steps, using the callback to advance the offset and request another read of 128 bytes (or less) each time.
@sa
m2m_ota_init
m2m_ota_host_file_get
tpfFileReadCb
*/
NMI_API sint8 m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb);
/*!
@ingroup HFD
@fn \
sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size);
@brief
Read a certain amount of bytes from a file in WINC's Flash using SPI transfer.
@param[in] u8Handler
Handler of the file we are trying to read from. Must be valid.
@param[in] pu8Buff
Pointer to a buffer to store the data being read. Must not be NULL.
@param[in] u32Offset
Offset from start of the file to read from (in bytes).
@param[in] u32Size
The amount of data to read (in Bytes).
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
@warning
Reading of a file via SPI can be much faster than by reading it via the HIF. However, the read will
be blocking and it will require the WINC to be put into download mode prior to the read, the download
mode means that the WINC will act as Flash device and not as a Wifi device. So, before using
m2m_ota_host_file_read_spi, the Application should call @ref m2m_wifi_download_mode before trying to
read. After the read finishes, the WINC needs to be reset (see @ref m2m_wifi_reinit).\n
A valid file handler must be provided, this means that it needs to match the handler internally stored
by the WINC and must not be @ref HFD_INVALID_HANDLER.
@sa
m2m_ota_init
m2m_ota_host_file_get
\section Host File Download SPI Read Example
The following is an example of how to perform a read file from the WINC via SPI.
@code
typedef struct {
uint8 u8Handler;
uint32 u32Offset;
uint32 u32Size;
uint8 au8Buff[200];
}FileDescriptor;
tstrWifiInitParam gstrWifiParam;
static FileDescriptor gstrAppFile;
char *acURL = "http://www.microchip.com/_images/ics/medium-ATWINC1500-MODULE-28.png";
static void ReadFileSPI(void);
static void wifi_event_cb(uint8 u8WiFiEvent, void * pvMsg);
static void FileGetCallback(uint8 u8Status, uint8 u8Handler, uint32 u32Size);
static void OtaUpdateCb(uint8 u8OtaUpdateStatusType ,uint8 u8OtaUpdateStatus);
static void wifi_event_cb(uint8 u8WiFiEvent, void * pvMsg)
{
case M2M_WIFI_REQ_DHCP_CONF:
{
// After successfully connection, start the File Download
gstrAppFile.u32Offset = 0;
s8Ret = m2m_ota_host_file_get(acURL, FileGetCallback);
if(s8Ret != M2M_SUCCESS)
{
M2M_ERR("File Download Failed!\n");
}
}
break;
default:
break;
}
static void OtaUpdateCb(uint8 u8OtaUpdateStatusType ,uint8 u8OtaUpdateStatus)
{
M2M_INFO("%d %d\n",u8OtaUpdateStatusType,u8OtaUpdateStatus);
if(u8OtaUpdateStatus == OTA_STATUS_SUCCESS)
{
if(u8OtaUpdateStatusType == HFD_STATUS)
{
// Read the file and process it
ReadFileSPI();
}
}
}
static void FileGetCallback(uint8 u8Status, uint8 u8Handler, uint32 u32Size)
{
if(OTA_STATUS_SUCCESS == u8Status)
{
gstrAppFile.u8Handler = u8Handler;
gstrAppFile.u32Size = u32Size;
// File Get Successful
}
else
{
M2M_ERR("File Get Failed!\n");
// File Get Failed
}
}
static void ReadFileSPI(void)
{
sint8 s8Ret = M2M_ERR_FAIL;
if(WIFI_STATE_DEINIT != m2m_wifi_get_state())
m2m_wifi_deinit(NULL);
s8Ret = m2m_wifi_download_mode();
if(M2M_SUCCESS != s8Ret) goto EXIT;
// gstrAppFile.u32Offset can be changed to define a starting point for the read,
// in which case the size of the requested read should be adjusted to accommodate for this.
// This call assumes that m2m_ota_host_file_get was called earlier, in this example it is fine
// since ReadFileSPI is only called from the within OtaUpdateCb
// This example simply reads the first 200 bytes of the file.
uint32 u32AmountToRead = 200;
s8Ret = m2m_ota_host_file_read_spi(gstrAppFile.u8Handler, gstrAppFile.au8Buff, gstrAppFile.u32Offset, u32AmountToRead);
if(M2M_SUCCESS == s8Ret)
M2M_INFO("\nFile Read completed, Offset: %lu, Size of Read: %lu.\n", gstrAppFile.u32Offset, u32AmountToRead);
// *** Do something with the contents of gstrAppFile.au8Buff ***
s8Ret = m2m_wifi_reinit(&gstrWifiParam);
if(M2M_SUCCESS != s8Ret) goto EXIT;
// Initialize the OTA again and reconnect to the previously connected SSID
m2m_ota_init(OtaUpdateCb, NULL);
m2m_wifi_default_connect();
EXIT:
return;
}
void main(void)
{
nm_bsp_init();
m2m_memset((uint8*)&gstrWifiParam, 0, sizeof(gstrWifiParam));
gstrWifiParam.pfAppWifiCb = wifi_event_cb;
// Initialize the WINC Driver
sint8 s8Ret = m2m_wifi_init(&gstrWifiParam);
if (M2M_SUCCESS != s8Ret)
{
M2M_ERR("Driver Init Failed <%d>\n",s8Ret);
while(1);
}
// Initialize the OTA module
m2m_ota_init(OtaUpdateCb, NULL);
// *** Connect to a wifi network by calling m2m_wifi_connect() ***
while(1) m2m_wifi_handle_events(NULL);
}
@endcode
*/
NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size);
/*!
@ingroup HFD
@fn \
sint8 m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb);
@brief
Erase any traces of file stored in WINC's Flash.
@param[in] u8Handler
Handler of the file we are trying to erase. Must be valid.
@param[in] pfHFDEraseCb
Pointer to callback (see @ref tpfFileEraseCb) to execute when the file erase is completed by the WINC.
@return
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
@pre
In order to execute the callback, @ref m2m_ota_init must be called before requesting the erase.
@note
Providing a callback is optional.
If the current handler is invalid at this point, it means one of the three:
1. The file never existed;
2. The file has already been already deleted;
3. The request to get the file hasn't fully completed.
\par
For 1. and 2. there is no need to signal the WINC to erase the file in Flash.\n
For 3. the Flash can't be erased while a file download is ongoing.
@warning
A valid file handler must be provided, this means that it needs to match the handler internally stored
by the WINC and must not be @ref HFD_INVALID_HANDLER \n
The handlers will be destroyed regardless of the call returning success or not.
@sa
m2m_ota_init
m2m_ota_host_file_get
*/
NMI_API sint8 m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb);
#if 0
NMI_API sint8 m2m_ota_test(void);
#endif
/*!
@ingroup VERSIONAPI
@fn sint8 m2m_ota_get_firmware_version(tstrM2mRev* pstrRev);
@brief Get the OTA Firmware version.
@details Get OTA Firmware version info from the inactive partition, as defined in the structure tstrM2mRev.
@param[out] pstrRev
Pointer to the structure tstrM2mRev that contains the firmware version parameters.
@return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev *pstrRev);
/*!
@ingroup WINCOTA
@fn \
sint8 m2m_ota_set_ssl_option(tenuOTASSLOption enuOptionName, const void *pOptionValue, size_t OptionLen)
@brief
Set specific SSL options to be used when the WINC performs an OTA from an https server.
@details
The following options can be set:\n
@ref WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH \n
@ref WIFI_OTA_SSL_OPT_SNI_VALIDATION \n
@ref WIFI_OTA_SSL_OPT_SNI_SERVERNAME \n
The setting applies to all subsequent OTA attempts via @ref m2m_ota_start_update \n
@param[in] enuOptionName
The option to set.
@param[in] pOptionValue
Pointer to a buffer containing the value to set. The buffer must be at least as long as OptionLen.
If OptionLen is 0, then pOptionValue may be NULL.
@param[in] OptionLen
The length of the option value being set (including the null terminator for strings).
@return
The function returns @ref M2M_SUCCESS if the parameters are valid and @ref M2M_ERR_INVALID_ARG otherwise.
*/
NMI_API sint8 m2m_ota_set_ssl_option(tenuOTASSLOption enuOptionName, const void *pOptionValue, size_t OptionLen);
/*!
@ingroup WINCOTA
@fn \
sint8 m2m_ota_get_ssl_option(tenuOTASSLOption enuOptionName, void *pOptionValue, size_t *pOptionLen)
@brief
Get (read) SSL options relating to OTA
@details
The following options can be read:\n
@ref WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH \n
@ref WIFI_OTA_SSL_OPT_SNI_VALIDATION \n
@ref WIFI_OTA_SSL_OPT_SNI_SERVERNAME \n
@param[in] enuOptionName
The option to get.
@param[out] pOptionValue
Pointer to a buffer to contain the value to get. The buffer must be at least as long as the value pointed to by pOptionLen.
@param[inout] pOptionLen
Pointer to a length.
When calling the function, this length must be the length of the buffer available for reading the option value,
and must be large enough to hold the returned option value otherwise an @ref M2M_ERR_INVALID_ARG error will be returned.
When the function returns, this length is the length of the data that has been populated by the function.
@return
The function returns @ref M2M_SUCCESS if the parameters are valid and @ref M2M_ERR_INVALID_ARG otherwise.
*/
NMI_API sint8 m2m_ota_get_ssl_option(tenuOTASSLOption enuOptionName, void *pOptionValue, size_t *pOptionLen);
#ifdef __cplusplus
}
#endif
#endif /* __M2M_OTA_H__ */

View File

@ -0,0 +1,210 @@
/**
*
* \file
*
* \brief WINC Peripherals Application Interface.
*
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
@enum \
tenuGpioNum
@brief
A list of GPIO numbers configurable through the m2m_periph module.
*/
typedef enum {
M2M_PERIPH_GPIO0 = 0, /*!< GPIO0 pad */
M2M_PERIPH_GPIO1 = 1, /*!< GPIO1 pad */
M2M_PERIPH_GPIO2 = 2, /*!< GPIO2 pad */
M2M_PERIPH_GPIO3 = 3, /*!< GPIO3 pad */
M2M_PERIPH_GPIO4 = 4, /*!< GPIO4 pad */
M2M_PERIPH_GPIO5 = 5, /*!< GPIO5 pad */
M2M_PERIPH_GPIO6 = 6, /*!< GPIO6 pad */
M2M_PERIPH_GPIO_MAX
} tenuGpioNum;
/*!
@enum \
tenuPullupMask
@brief
Bitwise-ORed flags for use in @ref m2m_periph_pullup_ctrl.
@sa
m2m_periph_pullup_ctrl
*/
typedef enum {
M2M_PERIPH_PULLUP_DIS_HOST_WAKEUP = (1ul << 0),
M2M_PERIPH_PULLUP_DIS_RTC_CLK = (1ul << 1),
M2M_PERIPH_PULLUP_DIS_IRQN = (1ul << 2),
M2M_PERIPH_PULLUP_DIS_GPIO_3 = (1ul << 3),
M2M_PERIPH_PULLUP_DIS_GPIO_4 = (1ul << 4),
M2M_PERIPH_PULLUP_DIS_GPIO_5 = (1ul << 5),
M2M_PERIPH_PULLUP_DIS_SD_DAT3 = (1ul << 6),
M2M_PERIPH_PULLUP_DIS_SD_DAT2_SPI_RXD = (1ul << 7),
M2M_PERIPH_PULLUP_DIS_SD_DAT1_SPI_SSN = (1ul << 9),
M2M_PERIPH_PULLUP_DIS_SD_CMD_SPI_SCK = (1ul << 10),
M2M_PERIPH_PULLUP_DIS_SD_DAT0_SPI_TXD = (1ul << 11),
M2M_PERIPH_PULLUP_DIS_GPIO_6 = (1ul << 12),
M2M_PERIPH_PULLUP_DIS_SD_CLK = (1ul << 13),
M2M_PERIPH_PULLUP_DIS_I2C_SCL = (1ul << 14),
M2M_PERIPH_PULLUP_DIS_I2C_SDA = (1ul << 15),
M2M_PERIPH_PULLUP_DIS_GPIO_11 = (1ul << 16),
M2M_PERIPH_PULLUP_DIS_GPIO_12 = (1ul << 17),
M2M_PERIPH_PULLUP_DIS_GPIO_13 = (1ul << 18),
M2M_PERIPH_PULLUP_DIS_GPIO_14 = (1ul << 19),
M2M_PERIPH_PULLUP_DIS_GPIO_15 = (1ul << 20),
M2M_PERIPH_PULLUP_DIS_GPIO_16 = (1ul << 21),
M2M_PERIPH_PULLUP_DIS_GPIO_17 = (1ul << 22),
M2M_PERIPH_PULLUP_DIS_GPIO_18 = (1ul << 23),
M2M_PERIPH_PULLUP_DIS_GPIO_19 = (1ul << 24),
M2M_PERIPH_PULLUP_DIS_GPIO_20 = (1ul << 25),
M2M_PERIPH_PULLUP_DIS_GPIO_21 = (1ul << 26),
M2M_PERIPH_PULLUP_DIS_GPIO_22 = (1ul << 27),
M2M_PERIPH_PULLUP_DIS_GPIO_23 = (1ul << 28),
M2M_PERIPH_PULLUP_DIS_GPIO_24 = (1ul << 29),
} tenuPullupMask;
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#ifdef __cplusplus
extern "C" {
#endif
/*!
@fn \
NMI_API sint8 m2m_periph_gpio_set_dir(uint8 u8GpioNum, uint8 u8GpioDir);
@brief
Configure a specific WINC15x0 pad as a GPIO and sets its direction (input or output).
@param[in] u8GpioNum
GPIO number. Allowed values are defined in @ref tenuGpioNum.
@param[in] u8GpioDir
GPIO direction: Zero = input. Non-zero = output.
@return
The function returns @ref M2M_SUCCESS 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 WINC15x0 GPIO output level high or low.
@param[in] u8GpioNum
GPIO number. Allowed values are defined in @ref 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 WINC15x0 GPIO input level.
@param[in] u8GpioNum
GPIO number. Allowed values are defined in @ref tenuGpioNum.
@param [out] pu8GpioVal
GPIO input value. Zero = low, non-zero = high.
@return
The function returns @ref M2M_SUCCESS 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_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 @ref tenuPullupMask.
@param[in] enable
Set to 0 to disable pull-up resistor. Non-zero will enable the pull-up.
@return
The function returns @ref M2M_SUCCESS 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_ */

View File

@ -0,0 +1,248 @@
/**
*
* \file
*
* \brief WINC Application Interface Internal Types.
*
* Copyright (c) 2017-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
/** @defgroup SSLAPI SSL
@brief
Provides a description of the SSL Layer.
@{
@defgroup SSLCallbacks Callbacks
@brief
Provides detail on the available callbacks for the SSL Layer.
@defgroup SSLEnums Enumerations and Typedefs
@brief
Specifies the enums and Data Structures used by the SSL APIs.
@defgroup SSLFUNCTIONS Functions
@brief
Provides detail on the available APIs for the SSL Layer.
@}
*/
#ifndef __M2M_SSL_H__
#define __M2M_SSL_H__
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "common/include/nm_common.h"
#include "driver/include/m2m_types.h"
#include "driver/source/nmdrv.h"
#include "ecc_types.h"
#include "socket/include/socket.h"
/*!
@ingroup SSLCallbacks
@typedef void (*tpfAppSSLCb)(uint8 u8MsgType, void* pvMsg);
@brief A callback to get SSL notifications.
@param[in] u8MsgType
The type of the message received.
@param[in] pvMsg
A structure to provide notification payload.
*/
typedef void (*tpfAppSSLCb)(uint8 u8MsgType, void *pvMsg);
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb);
@brief Initializes the SSL layer.
@param[in] pfAppSSLCb
Application SSL callback function.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz);
@brief Sends ECC responses to the WINC.
@param[in] strECCResp
ECC Response struct.
@param[in] pu8RspDataBuff
Pointer of the response data to be sent.
@param[in] u16RspDataSz
Response data size.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo *strECCResp, uint8 *pu8RspDataBuff, uint16 u16RspDataSz);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8* pu8Buffer, uint32 u32BufferSz);
@brief Sends certificates to the WINC.
@param[in] pu8Buffer
Pointer to the certificates. The buffer format must match the format of @ref tstrTlsSrvSecHdr.
@param[in] u32BufferSz
Size of the certificates.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8 *pu8Buffer, uint32 u32BufferSz);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API sint8 m2m_ssl_retrieve_next_for_verifying(tenuEcNamedCurve *penuCurve, uint8 *pu8Value, uint16 *pu16ValueSz, uint8 *pu8Sig, uint16 *pu16SigSz, tstrECPoint *pstrKey);
@brief Retrieve the next set of information from the WINC for ECDSA verification.
@param[out] penuCurve
The named curve.
@param[out] pu8Value
Value retrieved for verification. This is the digest of the message, truncated/prepended to the appropriate size.
@param[inout] pu16ValueSz
in: Size of value buffer provided by caller.
out: Size of value retrieved (provided for convenience; the value size is in fact determined by the curve).
@param[out] pu8Sig
Signature retrieved for verification.
@param[inout] pu16SigSz
in: Size of signature buffer provided by caller.
out: Size of signature retrieved (provided for convenience; the signature size is in fact determined by the curve).
@param[out] pstrKey
Public key retrieved for verification.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
verification information is ready via @ref ECC_REQ_SIGN_VERIFY.
@warning If this function returns @ref M2M_ERR_FAIL, then any remaining verification info from
the WINC is lost.
*/
NMI_API sint8 m2m_ssl_retrieve_next_for_verifying(tenuEcNamedCurve *penuCurve, uint8 *pu8Value, uint16 *pu16ValueSz, uint8 *pu8Sig, uint16 *pu16SigSz, tstrECPoint *pstrKey);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API sint8 m2m_ssl_retrieve_cert(uint16* pu16Curve, uint8* pu8Value, uint8* pu8Sig, tstrECPoint* pstrKey);
@brief Retrieve the next set of information from the WINC for ECDSA verification.
@param[out] pu16Curve
The named curve, to be cast to type @ref tenuEcNamedCurve.
@param[out] pu8Value
Value retrieved for verification. This is the digest of the message, truncated/prepended to the appropriate size.
The size of the value is equal to the field size of the curve, hence is determined by pu16Curve.
@param[out] pu8Sig
Signature retrieved for verification.
The size of the signature is equal to twice the field size of the curve, hence is determined by pu16Curve.
@param[out] pstrKey
Public key retrieved for verification.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
verification information is ready via @ref ECC_REQ_SIGN_VERIFY.
@warning If this function returns @ref M2M_ERR_FAIL, then any remaining verification info from
the WINC is lost.
@warning This API has been deprecated and is kept for legacy purposes only. It is recommended
that @ref m2m_ssl_retrieve_next_for_verifying is used instead.
*/
NMI_API sint8 m2m_ssl_retrieve_cert(uint16 *pu16Curve, uint8 *pu8Value, uint8 *pu8Sig, tstrECPoint *pstrKey);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API sint8 m2m_ssl_retrieve_hash(uint8* pu8Value, uint16 u16ValueSz)
@brief Retrieve the value from the WINC for ECDSA signing.
@param[out] pu8Value
Value retrieved for signing. This is the digest of the message, truncated/prepended to the appropriate size.
@param[in] u16ValueSz
Size of value to be retrieved. (The application should obtain this information,
along with the curve, from the associated @ref ECC_REQ_SIGN_GEN notification.)
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
signing information is ready via @ref ECC_REQ_SIGN_GEN.
@warning If this function returns @ref M2M_ERR_FAIL, then the value for signing is lost.
*/
NMI_API sint8 m2m_ssl_retrieve_hash(uint8 *pu8Value, uint16 u16ValueSz);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API void m2m_ssl_stop_retrieving(void);
@brief Allow SSL driver to tidy up when the application chooses not to retrieve all available
information.
@warning The application must call this function if it has been notified (via
@ref ECC_REQ_SIGN_GEN or @ref ECC_REQ_SIGN_VERIFY) that information is available for
retrieving from the WINC, but chooses not to retrieve it all.
The application must not call this function if it has retrieved all the available
information, or if a retrieve function returned @ref M2M_ERR_FAIL indicating that any
remaining information has been lost.
@see m2m_ssl_retrieve_next_for_verifying\n
m2m_ssl_retrieve_cert\n
m2m_ssl_retrieve_hash
*/
NMI_API void m2m_ssl_stop_retrieving(void);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API void m2m_ssl_stop_processing_certs(void);
@brief Allow SSL driver to tidy up in case application does not read all available certificates.
@warning This API has been deprecated and is kept for legacy purposes only. It is recommended
that @ref m2m_ssl_stop_retrieving is used instead.
*/
NMI_API void m2m_ssl_stop_processing_certs(void);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API void m2m_ssl_ecc_process_done(void);
@brief Allow SSL driver to tidy up after application has finished processing ECC message.
@warning The application should call this function after receiving an SSL callback with message
type @ref M2M_SSL_REQ_ECC, after retrieving any related information, and before
calling @ref m2m_ssl_handshake_rsp.
*/
NMI_API void m2m_ssl_ecc_process_done(void);
/*!
@ingroup SSLFUNCTIONS
@fn NMI_API sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP);
@brief Sets the active ciphersuites.
@details Override the default Active SSL ciphers in the SSL module with a certain combination selected by
the caller in the form of a bitmap containing the required ciphers to be on.\n
There is no need to call this function if the application will not change the default ciphersuites.
@param[in] u32SslCsBMP
Bitmap containing the desired ciphers to be enabled for the SSL module. The ciphersuites are defined in
@ref SSLCipherSuiteID.
The default ciphersuites are all ciphersuites supported by the firmware with the exception of ECC ciphersuites.
The caller can override the default with any desired combination.
If u32SslCsBMP does not contain any ciphersuites supported by firmware, then the current active list will not
change.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP);
#endif /* __M2M_SSL_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,819 @@
/**
*
* \file
*
* \brief WINC1500 Peripherials Application Interface.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifdef _M2M_ATE_FW_
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "driver/include/m2m_ate_mode.h"
#include "driver/source/nmasic.h"
#include "driver/source/nmdrv.h"
#include "m2m_hif.h"
#include "driver/source/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_ATE_HIGH;
s8Ret = nm_drv_init(&u8WifiMode);
return s8Ret;
}
/*!
@fn \
sint8 m2m_ate_init(tstrM2mAteInit *pstrInit);
@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_param(tstrM2mAteInit *pstrInit)
{
sint8 s8Ret = M2M_SUCCESS;
s8Ret = nm_drv_init((void*)&pstrInit->u8RxPwrMode);
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_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_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 \
void m2m_ate_set_pa_gain(uint8 gain_db)
@brief
This function is used to set the PA gain (18/15/12/9/6/3/0 only)
@param [in] uint8 gain_db
PA gain level allowed (18/15/12/9/6/3/0 only)
*/
void m2m_ate_set_pa_gain(uint8 gain_db)
{
uint32 PA_1e9c;
uint8 aGain[] = {
/* "0 dB" */ 0x00,
/* "3 dB" */ 0x01,
/* "6 dB" */ 0x03,
/* "9 dB" */ 0x07,
/* "12 dB" */ 0x0f,
/* "15 dB" */ 0x1f,
/* "18 dB" */ 0x3f };
/* The variable PA gain is valid only for High power mode */
PA_1e9c = nm_read_reg(0x1e9c);
/* TX bank 0. */
PA_1e9c &= ~(0x3ful << 8);
PA_1e9c |= (((uint32)aGain[gain_db/3] & 0x3f) << 8);
nm_write_reg(0x1e9c, PA_1e9c);
}
/*!
@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_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,750 @@
/**
*
* \file
*
* \brief This module contains M2M host interface APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "ch.hpp"
#include "common/include/nm_common.h"
#include "driver/source/nmbus.h"
#include "bsp/include/nm_bsp.h"
#include "m2m_hif.h"
#include "driver/include/m2m_types.h"
#include "driver/source/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 WIFI_HOST_RCV_CTRL_4 (0x150400)
#define WIFI_HOST_RCV_CTRL_5 (0x1088)
typedef struct {
uint8 u8ChipMode;
uint8 u8ChipSleep;
uint8 u8HifRXDone;
uint8 u8Interrupt;
uint8 u8Yield;
uint32 u32RxAddr;
uint32 u32RxSize;
tpfHifCallBack pfWifiCb;
tpfHifCallBack pfIpCb;
tpfHifCallBack pfOtaCb;
tpfHifCallBack pfSigmaCb;
tpfHifCallBack pfHifCb;
tpfHifCallBack pfCryptoCb;
tpfHifCallBack pfSslCb;
}tstrHifContext;
static volatile tstrHifContext gstrHifCxt;
// #ifdef ETH_MODE
extern void os_hook_isr(void);
// #endif
static void isr(void)
{
chibios_rt::CriticalSectionLocker csl;
gstrHifCxt.u8Interrupt++;
#ifdef NM_LEVEL_INTERRUPT
nm_bsp_interrupt_ctrl(0);
#endif
os_hook_isr();
}
static sint8 hif_set_rx_done(void)
{
uint32 reg;
sint8 ret = M2M_SUCCESS;
gstrHifCxt.u8HifRXDone = 0;
#ifdef NM_EDGE_INTERRUPT
nm_bsp_interrupt_ctrl(1);
#endif
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0,&reg);
if(ret != M2M_SUCCESS)goto ERR1;
/* Set RX Done */
reg |= NBIT1;
ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0,reg);
if(ret != M2M_SUCCESS)goto ERR1;
#ifdef NM_LEVEL_INTERRUPT
nm_bsp_interrupt_ctrl(1);
#endif
ERR1:
return ret;
}
/**
* @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(gstrHifCxt.u8HifRXDone)
{
/*chip already wake for the rx not done no need to send wake request*/
return ret;
}
if(gstrHifCxt.u8ChipSleep == 0)
{
if(gstrHifCxt.u8ChipMode != M2M_NO_PS)
{
ret = chip_wake();
if(ret != M2M_SUCCESS)goto ERR1;
}
else
{
}
}
gstrHifCxt.u8ChipSleep++;
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)
{
gstrHifCxt.u8ChipMode = 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 gstrHifCxt.u8ChipMode;
}
/**
* @fn NMI_API sint8 hif_chip_sleep_sc(void);
* @brief To clear the chip sleep but keep the chip sleep
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
sint8 hif_chip_sleep_sc(void)
{
if(gstrHifCxt.u8ChipSleep >= 1)
{
gstrHifCxt.u8ChipSleep--;
}
return M2M_SUCCESS;
}
/**
* @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(gstrHifCxt.u8ChipSleep >= 1)
{
gstrHifCxt.u8ChipSleep--;
}
if(gstrHifCxt.u8ChipSleep == 0)
{
if(gstrHifCxt.u8ChipMode != M2M_NO_PS)
{
ret = chip_sleep();
if(ret != M2M_SUCCESS)goto ERR1;
}
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)
{
m2m_memset((uint8*)&gstrHifCxt,0,sizeof(tstrHifContext));
nm_bsp_register_isr(isr);
hif_register_cb(M2M_REQ_GROUP_HIF,m2m_hif_cb);
return M2M_SUCCESS;
}
/**
* @fn NMI_API sint8 hif_deinit(void * arg);
* @brief To De-initialize HIF layer.
* @param [in] arg
* Pointer to the arguments.
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
sint8 hif_deinit(void * arg)
{
sint8 ret = M2M_SUCCESS;
ret = hif_chip_wake();
m2m_memset((uint8*)&gstrHifCxt,0,sizeof(tstrHifContext));
return ret;
}
/**
* @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;
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;
}
if (strHif.u16Length <= M2M_HIF_MAX_PACKET_SIZE)
{
ret = hif_chip_wake();
if(ret == M2M_SUCCESS)
{
volatile uint32 reg, dma_addr = 0;
volatile uint16 cnt = 0;
//#define OPTIMIZE_BUS
/*please define in firmware also*/
#ifndef OPTIMIZE_BUS
reg = 0UL;
reg |= (uint32)u8Gid;
reg |= ((uint32)u8Opcode<<8);
reg |= ((uint32)strHif.u16Length<<16);
ret = nm_write_reg(NMI_STATE_REG,reg);
if(M2M_SUCCESS != ret) goto ERR1;
reg = 0UL;
reg |= NBIT1;
ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg);
if(M2M_SUCCESS != ret) goto ERR1;
#else
reg = 0UL;
reg |= NBIT1;
reg |= ((u8Opcode & NBIT7) ? (NBIT2):(0)); /*Data = 1 or config*/
reg |= (u8Gid == M2M_REQ_GROUP_IP) ? (NBIT3):(0); /*IP = 1 or non IP*/
reg |= ((uint32)strHif.u16Length << 4); /*length of pkt max = 4096*/
ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg);
if(M2M_SUCCESS != ret) goto ERR1;
#endif
dma_addr = 0;
for(cnt = 0; cnt < 1000; cnt ++)
{
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_2,(uint32 *)&reg);
if(ret != M2M_SUCCESS) break;
/*
* If it takes too long to get a response, the slow down to
* avoid back-to-back register read operations.
*/
if(cnt >= 500) {
if(cnt < 501) {
M2M_INFO("Slowing down...\n");
}
nm_bsp_sleep(1);
}
if (!(reg & NBIT1))
{
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_4,(uint32 *)&dma_addr);
if(ret != M2M_SUCCESS) {
/*in case of read error clear the DMA address and return error*/
dma_addr = 0;
goto ERR1;
}
/*in case of success break */
break;
}
}
if (dma_addr != 0)
{
volatile uint32 u32CurrAddr;
u32CurrAddr = dma_addr;
strHif.u16Length=NM_BSP_B_L_16(strHif.u16Length);
ret = nm_write_block(u32CurrAddr, (uint8*)&strHif, M2M_HIF_HDR_OFFSET);
if(M2M_SUCCESS != ret) goto ERR1;
u32CurrAddr += M2M_HIF_HDR_OFFSET;
if(pu8CtrlBuf != NULL)
{
ret = nm_write_block(u32CurrAddr, pu8CtrlBuf, u16CtrlBufSize);
if(M2M_SUCCESS != ret) goto ERR1;
u32CurrAddr += u16CtrlBufSize;
}
if(pu8DataBuf != NULL)
{
u32CurrAddr += (u16DataOffset - u16CtrlBufSize);
ret = nm_write_block(u32CurrAddr, pu8DataBuf, u16DataSize);
if(M2M_SUCCESS != ret) goto ERR1;
u32CurrAddr += u16DataSize;
}
reg = dma_addr << 2;
reg |= NBIT1;
ret = nm_write_reg(WIFI_HOST_RCV_CTRL_3, reg);
if(M2M_SUCCESS != ret) goto ERR1;
}
else
{
ret = hif_chip_sleep();
M2M_DBG("Failed to alloc rx size %d\r",ret);
ret = M2M_ERR_MEM_ALLOC;
goto ERR2;
}
}
else
{
M2M_ERR("(HIF)Failed to wakeup the chip\n");
goto ERR2;
}
}
else
{
M2M_ERR("HIF message length (%d) exceeds max length (%d)\n",strHif.u16Length, M2M_HIF_MAX_PACKET_SIZE);
ret = M2M_ERR_SEND;
goto ERR2;
}
/*actual sleep ret = M2M_SUCCESS*/
ret = hif_chip_sleep();
return ret;
ERR1:
/*reset the count but no actual sleep as it already bus error*/
hif_chip_sleep_sc();
ERR2:
/*logical error*/
return ret;
}
/**
* @fn hif_isr
* @brief Host interface interrupt service routine
* @author M. Abdelmawla
* @date 15 July 2012
* @return 1 in case of interrupt received else 0 will be returned
* @version 1.0
*/
static sint8 hif_isr(void)
{
sint8 ret = M2M_SUCCESS;
uint32 reg;
volatile tstrHifHdr strHif;
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, &reg);
if(M2M_SUCCESS == ret)
{
if(reg & 0x1) /* New interrupt has been received */
{
uint16 size;
/*Clearing RX interrupt*/
reg &= ~NBIT0;
ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0,reg);
if(ret != M2M_SUCCESS)goto ERR1;
gstrHifCxt.u8HifRXDone = 1;
size = (uint16)((reg >> 2) & 0xfff);
if (size > 0) {
uint32 address = 0;
/**
start bus transfer
**/
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_1, &address);
if(M2M_SUCCESS != ret)
{
M2M_ERR("(hif) WIFI_HOST_RCV_CTRL_1 bus fail\n");
goto ERR1;
}
gstrHifCxt.u32RxAddr = address;
gstrHifCxt.u32RxSize = size;
ret = nm_read_block(address, (uint8*)&strHif, sizeof(tstrHifHdr));
strHif.u16Length = NM_BSP_B_L_16(strHif.u16Length);
if(M2M_SUCCESS != ret)
{
M2M_ERR("(hif) address bus fail\n");
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);
ret = M2M_ERR_BUS_FAIL;
goto ERR1;
}
}
if(M2M_REQ_GROUP_WIFI == strHif.u8Gid)
{
if(gstrHifCxt.pfWifiCb)
{
gstrHifCxt.pfWifiCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
}
else
{
M2M_ERR("WIFI callback is not registered\n");
}
}
else if(M2M_REQ_GROUP_IP == strHif.u8Gid)
{
if(gstrHifCxt.pfIpCb)
{
gstrHifCxt.pfIpCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
}
else
{
M2M_ERR("Socket callback is not registered\n");
}
}
else if(M2M_REQ_GROUP_OTA == strHif.u8Gid)
{
if(gstrHifCxt.pfOtaCb)
{
gstrHifCxt.pfOtaCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
}
else
{
M2M_ERR("Ota callback is not registered\n");
}
}
else if(M2M_REQ_GROUP_CRYPTO == strHif.u8Gid)
{
if(gstrHifCxt.pfCryptoCb)
{
gstrHifCxt.pfCryptoCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
}
else
{
M2M_ERR("Crypto callback is not registered\n");
}
}
else if(M2M_REQ_GROUP_SIGMA == strHif.u8Gid)
{
if(gstrHifCxt.pfSigmaCb)
{
gstrHifCxt.pfSigmaCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
}
else
{
M2M_ERR("Sigma callback is not registered\n");
}
}
else if(M2M_REQ_GROUP_SSL == strHif.u8Gid)
{
if(gstrHifCxt.pfSslCb)
{
gstrHifCxt.pfSslCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
}
else
{
M2M_ERR("SSL callback is not registered\n");
}
}
else
{
M2M_ERR("(hif) invalid group ID\n");
ret = M2M_ERR_BUS_FAIL;
goto ERR1;
}
if(gstrHifCxt.u8HifRXDone)
{
M2M_ERR("(hif) host app didn't set RX Done <%u><%X>\n", strHif.u8Gid, strHif.u8Opcode);
ret = hif_set_rx_done();
if(ret != M2M_SUCCESS) goto ERR1;
}
}
else
{
M2M_ERR("(hif) Wrong Size\n");
ret = M2M_ERR_RCV;
goto ERR1;
}
}
else
{
#ifndef WIN32
M2M_ERR("(hif) False interrupt %lx",reg);
goto ERR1;
#else
#endif
}
}
else
{
M2M_ERR("(hif) Failed to Read interrupt reg\n");
goto ERR1;
}
ERR1:
return ret;
}
/**
* @fn hif_yield(void)
* @brief
Yields control from interrupt event handler.
*/
void hif_yield(void)
{
gstrHifCxt.u8Yield = 1;
}
/**
* @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;
gstrHifCxt.u8Yield = 0;
while(gstrHifCxt.u8Interrupt && !gstrHifCxt.u8Yield)
{
/* Atomic decrement u8Interrupt since it takes multiple instructions to load, decrement and store,
* during which the ISR could fire again.
* If LEVEL interrupt is used instead of EDGE then the atomicity isn't needed since the interrupt
* is turned off in the ISR and back on again only after the interrupt has been serviced in hif_isr(). */
{
chibios_rt::CriticalSectionLocker csl;
gstrHifCxt.u8Interrupt--;
}
uint8 retries = 5;
while(1)
{
ret = hif_isr();
if(ret == M2M_SUCCESS) {
/*we will try forever until we get that interrupt*/
/*Fail return errors here due to bus errors (reading expected values)*/
break;
} else {
retries--;
if(!retries)
{
M2M_ERR("(HIF) Failed to handle interrupt %d, aborting due to too many retries\n", ret);
break;
}
else
{
M2M_ERR("(HIF) Failed to handle interrupt %d try again... (%u)\n", ret, retries);
}
}
}
}
return ret;
}
/*
* @fn hif_receive
* @brief Host interface interrupt service 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)
{
sint8 ret = M2M_SUCCESS;
if((u32Addr == 0)||(pu8Buf == NULL) || (u16Sz == 0))
{
if(isDone)
{
/* set RX done */
ret = hif_set_rx_done();
}
else
{
ret = M2M_ERR_FAIL;
M2M_ERR(" hif_receive: Invalid argument\n");
}
goto ERR1;
}
if(u16Sz > gstrHifCxt.u32RxSize)
{
ret = M2M_ERR_FAIL;
M2M_ERR("APP Requested Size is larger than the received buffer size <%u><%lu>\n",u16Sz, gstrHifCxt.u32RxSize);
goto ERR1;
}
if((u32Addr < gstrHifCxt.u32RxAddr)||((u32Addr + u16Sz)>(gstrHifCxt.u32RxAddr + gstrHifCxt.u32RxSize)))
{
ret = M2M_ERR_FAIL;
M2M_ERR("APP Requested Address beyond the received buffer address and length\n");
goto ERR1;
}
/* Receive the payload */
ret = nm_read_block(u32Addr, pu8Buf, u16Sz);
if(ret != M2M_SUCCESS)goto ERR1;
/* check if this is the last packet */
if((((gstrHifCxt.u32RxAddr + gstrHifCxt.u32RxSize) - (u32Addr + u16Sz)) <= 0) || isDone)
{
/* set RX done */
ret = hif_set_rx_done();
}
ERR1:
return ret;
}
/**
* @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
* @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_GROUP_IP:
gstrHifCxt.pfIpCb = fn;
break;
case M2M_REQ_GROUP_WIFI:
gstrHifCxt.pfWifiCb = fn;
break;
case M2M_REQ_GROUP_OTA:
gstrHifCxt.pfOtaCb = fn;
break;
case M2M_REQ_GROUP_HIF:
gstrHifCxt.pfHifCb = fn;
break;
case M2M_REQ_GROUP_CRYPTO:
gstrHifCxt.pfCryptoCb = fn;
break;
case M2M_REQ_GROUP_SIGMA:
gstrHifCxt.pfSigmaCb = fn;
break;
case M2M_REQ_GROUP_SSL:
gstrHifCxt.pfSslCb = fn;
break;
default:
M2M_ERR("GRp ? %d\n",u8Grp);
ret = M2M_ERR_FAIL;
break;
}
return ret;
}
#endif

View File

@ -0,0 +1,249 @@
/**
*
* \file
*
* \brief This module contains M2M host interface APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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 service 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_sleep_sc(void);
* @brief
To clear the chip count only but keep the chip awake
* @return
The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_chip_sleep_sc(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_yield(void)
* @brief
Yields control from interrupt event handler.
*/
NMI_API void hif_yield(void);
/**
* @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,575 @@
/**
*
* \file
*
* \brief NMC1500 IoT OTA Interface.
*
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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"
#include "spi_flash/include/spi_flash.h"
#include "driver/include/m2m_wifi.h"
#include "spi_flash/include/flexible_flash.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
static tpfOtaUpdateCb gpfOtaUpdateCb = NULL;
static tpfOtaNotifCb gpfOtaNotifCb = NULL;
static tpfFileGetCb gpfHFDGetCb = NULL;
static tpfFileReadCb gpfHFDReadCb = NULL;
static tpfFileEraseCb gpfHFDEraseCb = NULL;
typedef struct {
uint32 u32Offset;
uint32 u32Size;
} FileBlockDescriptor;
static FileBlockDescriptor FileBlock;
static uint8 gu8CurrFileHandlerID = HFD_INVALID_HANDLER;
static uint8 gu8OTASSLOpts = 0;
static uint8 gu8SNIServerName[64] = {0};
/* Map OTA SSL flags to SSL socket options */
#define WIFI_OTA_SSL_FLAG_BYPASS_SERVER_AUTH NBIT1
#define WIFI_OTA_SSL_FLAG_SNI_VALIDATION NBIT6
/*=*=*=*=*=*=*=*=*=*=*=*=
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/**
@fn m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
@brief Internal OTA call back function.
@param[in] u8OpCode
HIF Opcode type.
@param[in] u16DataSize
HIF data length.
@param[in] u32Addr
HIF address.
*/
static void m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
{
sint8 s8Ret = M2M_SUCCESS;
if(u8OpCode == M2M_OTA_RESP_NOTIF_UPDATE_INFO)
{
tstrOtaUpdateInfo strOtaUpdateInfo;
m2m_memset((uint8 *)&strOtaUpdateInfo, 0, sizeof(tstrOtaUpdateInfo));
s8Ret = hif_receive(u32Addr, (uint8 *)&strOtaUpdateInfo, sizeof(tstrOtaUpdateInfo), 0);
if(s8Ret == M2M_SUCCESS)
{
if(gpfOtaNotifCb)
gpfOtaNotifCb(&strOtaUpdateInfo);
}
}
else if(u8OpCode == M2M_OTA_RESP_UPDATE_STATUS)
{
tstrOtaUpdateStatusResp strOtaUpdateStatusResp;
m2m_memset((uint8 *)&strOtaUpdateStatusResp, 0, sizeof(tstrOtaUpdateStatusResp));
s8Ret = hif_receive(u32Addr, (uint8 *) &strOtaUpdateStatusResp, sizeof(tstrOtaUpdateStatusResp), 0);
if(s8Ret == M2M_SUCCESS)
{
if(gpfOtaUpdateCb)
gpfOtaUpdateCb(strOtaUpdateStatusResp.u8OtaUpdateStatusType, strOtaUpdateStatusResp.u8OtaUpdateStatus);
}
}
else if(u8OpCode == M2M_OTA_RESP_HOST_FILE_STATUS)
{
tstrOtaHostFileGetStatusResp strOtaHostFileGetStatusResp;
s8Ret = hif_receive(u32Addr, (uint8 *)&strOtaHostFileGetStatusResp, sizeof(tstrOtaHostFileGetStatusResp), 1);
if(M2M_SUCCESS == s8Ret)
{
if(strOtaHostFileGetStatusResp.u8OtaFileGetStatus == OTA_STATUS_SUCCESS) {
gu8CurrFileHandlerID = strOtaHostFileGetStatusResp.u8CFHandler;
}
}
}
else if(u8OpCode == M2M_OTA_RESP_HOST_FILE_DOWNLOAD)
{
tstrOtaHostFileGetStatusResp strOtaHostFileGetStatusResp;
s8Ret = hif_receive(u32Addr, (uint8 *)&strOtaHostFileGetStatusResp, sizeof(tstrOtaHostFileGetStatusResp), 1);
if(M2M_SUCCESS == s8Ret)
{
if(strOtaHostFileGetStatusResp.u8OtaFileGetStatus == OTA_STATUS_SUCCESS) {
gu8CurrFileHandlerID = strOtaHostFileGetStatusResp.u8CFHandler;
M2M_INFO("Generated HostFileHandlerID is %u\n", gu8CurrFileHandlerID);
}
if(gpfHFDGetCb) {
gpfHFDGetCb(strOtaHostFileGetStatusResp.u8OtaFileGetStatus, gu8CurrFileHandlerID, strOtaHostFileGetStatusResp.u32OtaFileSize);
gpfHFDGetCb = NULL;
}
}
}
else if(u8OpCode == M2M_OTA_RESP_HOST_FILE_READ)
{
tstrOtaHostFileReadStatusResp strOtaHostFileReadStatusResp;
m2m_memset((uint8 *)&strOtaHostFileReadStatusResp, 0, sizeof(tstrOtaHostFileReadStatusResp));
s8Ret = hif_receive(u32Addr, (uint8 *)&strOtaHostFileReadStatusResp, sizeof(tstrOtaHostFileReadStatusResp), 1);
if(M2M_SUCCESS == s8Ret)
if(gpfHFDReadCb)
gpfHFDReadCb(strOtaHostFileReadStatusResp.u8OtaFileReadStatus, strOtaHostFileReadStatusResp.pFileBuf, strOtaHostFileReadStatusResp.u16FileBlockSz);
}
else if(u8OpCode == M2M_OTA_RESP_HOST_FILE_ERASE)
{
tstrOtaHostFileEraseStatusResp strOtaHostFileEraseStatusResp;
s8Ret = hif_receive(u32Addr, (uint8 *)&strOtaHostFileEraseStatusResp, sizeof(tstrOtaHostFileEraseStatusResp), 1);
if(M2M_SUCCESS == s8Ret)
{
if(gpfHFDEraseCb)
{
gpfHFDEraseCb(strOtaHostFileEraseStatusResp.u8OtaFileEraseStatus);
gpfHFDEraseCb = NULL;
}
}
}
else
{
M2M_ERR("Invalid 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 returns @ref M2M_SUCCESS 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("Invalid Ota update cb\n");
}
if(pfOtaNotifCb) {
gpfOtaNotifCb = pfOtaNotifCb;
} else {
M2M_ERR("Invalid Ota notify cb\n");
}
hif_register_cb(M2M_REQ_GROUP_OTA, m2m_ota_cb);
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_HOST_FILE_STATUS, NULL, 0, NULL, 0, 0);
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 returns @ref M2M_SUCCESS 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 higher priority
but the priority is not implemented yet in data pkt
*/
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_NOTIF_SET_URL, 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 returns @ref M2M_SUCCESS 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_GROUP_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 returns @ref M2M_SUCCESS 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_GROUP_OTA, M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE, NULL, 0, NULL, 0, 0);
return ret;
}
/*!
@fn NMI_API sint8 m2m_ota_start_update(unsigned char * pcDownloadUrl)
@brief Request OTA start update using the downloaded URL.
@param[in] pcDownloadUrl
The download firmware URL, you get it from device info.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_start_update(unsigned char *pcDownloadUrl)
{
tstrOtaStart strOtaStart;
uint16 u16UrlLen = m2m_strlen(pcDownloadUrl);
if (u16UrlLen >= 255)
{
return M2M_ERR_INVALID_ARG;
}
m2m_memset((uint8*)&strOtaStart, 0, sizeof(strOtaStart));
m2m_memcpy((uint8*)&strOtaStart.acUrl, (uint8*)pcDownloadUrl, u16UrlLen);
/* Convert SSL options to flags */
if (gu8OTASSLOpts & WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH)
strOtaStart.u8SSLFlags |= WIFI_OTA_SSL_FLAG_BYPASS_SERVER_AUTH;
if (gu8OTASSLOpts & WIFI_OTA_SSL_OPT_SNI_VALIDATION)
strOtaStart.u8SSLFlags |= WIFI_OTA_SSL_FLAG_SNI_VALIDATION;
m2m_memcpy((uint8*)&strOtaStart.acSNI, gu8SNIServerName, m2m_strlen(gu8SNIServerName));
strOtaStart.u32TotalLen = sizeof(strOtaStart);
return hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_START_FW_UPDATE_V2 | M2M_REQ_DATA_PKT, (uint8*)&strOtaStart, strOtaStart.u32TotalLen, NULL, 0, 0);
}
/*!
@fn NMI_API sint8 m2m_ota_rollback(void)
@brief Request OTA Rollback image.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_rollback(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_ROLLBACK_FW, NULL, 0, NULL, 0, 0);
return ret;
}
/*!
@fn NMI_API sint8 m2m_ota_abort(void)
@brief Request OTA Abort.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_abort(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_ABORT, 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 returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_switch_firmware(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_SWITCH_FIRMWARE, NULL, 0, NULL, 0, 0);
return ret;
}
/*!
@fn NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev)
@brief Get the OTA Firmware version.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev *pstrRev)
{
sint8 ret = M2M_SUCCESS;
ret = hif_chip_wake();
if(ret == M2M_SUCCESS)
{
ret = nm_get_ota_firmware_info(pstrRev);
hif_chip_sleep();
}
return ret;
}
/*!
@fn NMI_API m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb)
@brief Download a file from a remote location and store it in the WINC's Flash.
@param[in] pcDownloadUrl
Url pointing to the remote file. HTTP/HTTPS only.
@param[in] pfHFDGetCb
Pointer to a callback to be executed when the download finishes.
@return Status of the get operation.
@warning Providing a callback is mandatory.
*/
NMI_API sint8 m2m_ota_host_file_get(unsigned char *pcDownloadUrl, tpfFileGetCb pfHFDGetCb)
{
sint8 s8Ret = M2M_ERR_FAIL;
uint16 u16DUrlSize = m2m_strlen(pcDownloadUrl);
if((NULL == pfHFDGetCb) || (0 == u16DUrlSize))
{
M2M_ERR("Invalid parameters.\n");
goto EXIT;
}
if('\0' != pcDownloadUrl[u16DUrlSize])
pcDownloadUrl[u16DUrlSize] = '\0';
else
u16DUrlSize++;
M2M_INFO("GetHostFile - URL: %s, urlSize: %u\n", pcDownloadUrl, u16DUrlSize);
s8Ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_HOST_FILE_DOWNLOAD, pcDownloadUrl, u16DUrlSize, NULL, 0, 0);
if(s8Ret == M2M_SUCCESS)
{
gpfHFDGetCb = pfHFDGetCb;
gu8CurrFileHandlerID = HFD_INVALID_HANDLER;
}
EXIT:
return s8Ret;
}
/*!
@fn NMI_API m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb)
@brief Read a certain amount of bytes from a file in WINC's Flash using HIF transfer.
@param[in] u8Handler
ID of the file we are trying to read from. Must be valid.
@param[in] u32Offset
Offset from start of the file to read from (in bytes).
@param[in] u32Size
The amount of data to read (in bytes).
@param[in] pfHFDReadCb
Callback to be executed when the read operation completes.
@return Status of the read operation.
@warning Providing a callback is mandatory.
*/
NMI_API sint8 m2m_ota_host_file_read_hif(uint8 u8Handler, uint32 u32Offset, uint32 u32Size, tpfFileReadCb pfHFDReadCb)
{
sint8 s8Ret = M2M_ERR_INVALID_ARG;
FileBlock.u32Offset = u32Offset;
FileBlock.u32Size = u32Size;
if((u8Handler != gu8CurrFileHandlerID) || (HFD_INVALID_HANDLER == gu8CurrFileHandlerID) || (NULL == pfHFDReadCb)) goto EXIT;
s8Ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_HOST_FILE_READ, (uint8 *) &FileBlock, sizeof(FileBlockDescriptor), NULL, 0, 0);
if(M2M_SUCCESS == s8Ret)
gpfHFDReadCb = pfHFDReadCb;
EXIT:
return s8Ret;
}
/*!
@fn NMI_API m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size)
@brief Read a certain amount of bytes from a file in WINC's Flash using SPI transfer.
@param[in] u8Handler
ID of the file we are trying to read from. Must be valid.
@param[in] pu8Buff
Pointer to a buffer to store the data being read. Must be valid.
@param[in] u32Offset
Offset from start of the file to read from (in bytes).
@param[in] u32Size
The amount of data to read (in Bytes).
@return Status of the read operation.
@warning Before using m2m_ota_host_file_read_spi, the WINC needs to be put in a special
mode to allow for a safe access to the Flash. This can be done by calling
@ref m2m_wifi_download_mode or @ref m2m_wifi_reinit_hold before trying to read.
*/
NMI_API sint8 m2m_ota_host_file_read_spi(uint8 u8Handler, uint8 *pu8Buff, uint32 u32Offset, uint32 u32Size)
{
static uint32 u32FlashHFDStart = 0;
static uint32 u32FlashHFDSize = 0;
sint8 s8Ret = M2M_ERR_INVALID_ARG;
if((u8Handler == HFD_INVALID_HANDLER) || (NULL == pu8Buff)) goto EXIT;
if(WIFI_STATE_INIT != m2m_wifi_get_state())
{
s8Ret = M2M_ERR_FAIL;
M2M_ERR("WINC is not in an appropriate state for this operation!\n");
goto EXIT;
}
if((u32FlashHFDStart == 0) || (u32FlashHFDSize == 0))
{
s8Ret = spi_flexible_flash_find_section(ENTRY_ID_HOSTFILE, &u32FlashHFDStart, &u32FlashHFDSize);
if(M2M_SUCCESS != s8Ret) goto EXIT;
}
s8Ret = spi_flash_read(pu8Buff, u32FlashHFDStart, 4);
if((M2M_SUCCESS != s8Ret) || (pu8Buff[0] != u8Handler)) goto EXIT;
if((u32Offset >= u32FlashHFDSize) ||
(u32Size > u32FlashHFDSize) ||
((u32Offset + u32Size) >= u32FlashHFDSize))
{
s8Ret = M2M_ERR_FAIL;
goto EXIT;
}
s8Ret = spi_flash_read(pu8Buff, u32FlashHFDStart + FLASH_SECTOR_SZ + u32Offset, u32Size);
if(M2M_SUCCESS != s8Ret)
{
M2M_ERR("Unable to read SPI Flash\n");
}
EXIT:
return s8Ret;
}
/*!
@fn NMI_API m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb)
@brief Erase any traces of an existing file, this means from host driver and WINC firmware.
@param[in] u8Handler
ID of the file we are trying to erase. Must be valid.
@param[in] pfHFDEraseCb
Pointer to callback to execute when the file erase in the WINC completes.
@return Status of the erase operation.
@note Providing a callback is optional.
If the current handler is invalid at this point, it means one of the three:
1. The file never existed;
2. The file has already been already deleted;
3. The request to get the file hasn't fully completed.
For 1. and 2. there is no need to signal the WINC to erase the file in Flash.
For 3. the Flash can't be erased while a file download is ongoing.
*/
NMI_API sint8 m2m_ota_host_file_erase(uint8 u8Handler, tpfFileEraseCb pfHFDEraseCb)
{
sint8 s8Ret = M2M_ERR_INVALID;
if((u8Handler != gu8CurrFileHandlerID) || (HFD_INVALID_HANDLER == gu8CurrFileHandlerID)) goto EXIT;
gu8CurrFileHandlerID = HFD_INVALID_HANDLER;
gpfHFDReadCb = NULL;
gpfHFDEraseCb = pfHFDEraseCb;
s8Ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_HOST_FILE_ERASE, NULL, 0, NULL, 0, 0);
EXIT:
return s8Ret;
}
/*!
@fn NMI_API sint8 m2m_ota_set_ssl_option(tenuOTASSLOption enuOptionName, const void *pOptionValue, size_t OptionLen)
@brief Sets SSL related options for OTA via https connections
@param[in] enuOptionName
The SSL option to set, from the set defined in tenuOTASSLOption
@param[in] pOptionValue
Pointer to the option value to set. Either a pointer to a uint32 with the value of 0 or 1, or a pointer to a string for the
WIFI_OTA_SSL_OPT_SNI_SERVERNAME option.
@param[in] OptionLen
The size of the option referred to in pOptionValue
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_set_ssl_option(tenuOTASSLOption enuOptionName, const void *pOptionValue, size_t OptionLen)
{
if((pOptionValue == NULL) && (OptionLen > 0))
return M2M_ERR_INVALID_ARG;
switch(enuOptionName)
{
case WIFI_OTA_SSL_OPT_SNI_SERVERNAME:
if(OptionLen > 64)
return M2M_ERR_INVALID_ARG;
if (m2m_strlen((uint8*)pOptionValue)+1 != OptionLen)
return M2M_ERR_INVALID_ARG;
m2m_memcpy(gu8SNIServerName, (uint8*)pOptionValue, OptionLen);
break;
case WIFI_OTA_SSL_OPT_SNI_VALIDATION:
case WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH:
if(OptionLen != sizeof(int))
return M2M_ERR_INVALID_ARG;
switch(*(int*)pOptionValue)
{
case 1:
gu8OTASSLOpts |= enuOptionName;
break;
case 0:
gu8OTASSLOpts &= ~enuOptionName;
break;
default:
return M2M_ERR_INVALID_ARG;
}
break;
default:
return M2M_ERR_INVALID_ARG;
}
return M2M_SUCCESS;
}
/*!
@fn NMI_API sint8 m2m_ota_get_ssl_option(tenuOTASSLOption enuOptionName, void *pOptionValue, size_t *OptionLen)
@brief Gets the status of SSL related options for OTA via https connections
@param[in] enuOptionName
The SSL option to obtain the status of, from the set defined in tenuOTASSLOption
@param[in] pOptionValue
Pointer to the option value to be updated by the function. Either a pointer to a uint32, or a pointer to a buffer for the
WIFI_OTA_SSL_OPT_SNI_SERVERNAME option.
@param[in] OptionLen
A pointer to a size_t type variable which will be updated to contain the size of the returned option.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_get_ssl_option(tenuOTASSLOption enuOptionName, void *pOptionValue, size_t *pOptionLen)
{
if((pOptionValue == NULL) || (pOptionLen == NULL))
return M2M_ERR_INVALID_ARG;
switch(enuOptionName)
{
case WIFI_OTA_SSL_OPT_SNI_VALIDATION:
case WIFI_OTA_SSL_OPT_BYPASS_SERVER_AUTH:
if(*pOptionLen < sizeof(int))
return M2M_ERR_INVALID_ARG;
*pOptionLen = sizeof(int);
*(int*)pOptionValue = (gu8OTASSLOpts & enuOptionName) ? 1 : 0;
break;
case WIFI_OTA_SSL_OPT_SNI_SERVERNAME:
{
uint16 sni_len = m2m_strlen(gu8SNIServerName)+1;
if(*pOptionLen < sni_len)
return M2M_ERR_INVALID_ARG;
*pOptionLen = sni_len;
m2m_memcpy((uint8*)pOptionValue, gu8SNIServerName, sni_len);
}
break;
default:
return M2M_ERR_INVALID_ARG;
}
return M2M_SUCCESS;
}

View File

@ -0,0 +1,105 @@
/**
*
* \file
*
* \brief NMC1500 Peripherials Application Interface.
*
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "driver/include/m2m_periph.h"
#include "driver/source/nmasic.h"
#include "m2m_hif.h"
#ifdef CONF_PERIPH
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#define GPIO_OP_DIR 0
#define GPIO_OP_SET 1
#define GPIO_OP_GET 2
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
STATIC FUNCTIONS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*
* GPIO read/write skeleton with wakeup/sleep capability.
*/
static sint8 gpio_ioctl(uint8 op, uint8 u8GpioNum, uint8 u8InVal, uint8 * pu8OutVal)
{
sint8 s8Ret = hif_chip_wake();
if(s8Ret != M2M_SUCCESS) goto _EXIT;
if(u8GpioNum >= M2M_PERIPH_GPIO_MAX) goto _EXIT1;
if(op == GPIO_OP_DIR) {
s8Ret = set_gpio_dir(u8GpioNum, u8InVal);
} else if(op == GPIO_OP_SET) {
s8Ret = set_gpio_val(u8GpioNum, u8InVal);
} else if(op == GPIO_OP_GET) {
s8Ret = get_gpio_val(u8GpioNum, pu8OutVal);
}
_EXIT1:
s8Ret = hif_chip_sleep();
_EXIT:
return s8Ret;
}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION IMPLEMENTATION
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
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_pullup_ctrl(uint32 pinmask, uint8 enable)
{
return pullup_ctrl(pinmask, enable);
}
#endif /* CONF_PERIPH */

View File

@ -0,0 +1,498 @@
/**
*
* \file
*
* \brief This module contains M2M Wi-Fi SSL APIs implementation.
*
* Copyright (c) 2017-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "driver/include/m2m_ssl.h"
#include "driver/source/m2m_hif.h"
#include "driver/source/nmasic.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
static tpfAppSSLCb gpfAppSSLCb = NULL;
static uint32 gu32HIFAddr = 0;
static tenuTlsFlashStatus genuStatus = TLS_FLASH_ERR_UNKNOWN;
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
@fn void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
@brief Internal SSL callback function.
@param [in] u8OpCode
HIF Opcode type.
@param [in] u16DataSize
HIF data length.
@param [in] u32Addr
HIF address.
*/
static void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
{
sint8 s8tmp = M2M_SUCCESS;
switch(u8OpCode)
{
case M2M_SSL_REQ_ECC:
{
tstrEccReqInfo strEccREQ;
s8tmp = hif_receive(u32Addr, (uint8 *)&strEccREQ, sizeof(tstrEccReqInfo), 0);
if(s8tmp == M2M_SUCCESS)
{
if(gpfAppSSLCb)
{
gu32HIFAddr = u32Addr + sizeof(tstrEccReqInfo);
gpfAppSSLCb(M2M_SSL_REQ_ECC, &strEccREQ);
}
}
}
break;
case M2M_SSL_RESP_SET_CS_LIST:
{
tstrSslSetActiveCsList strCsList;
s8tmp = hif_receive(u32Addr, (uint8 *)&strCsList, sizeof(tstrSslSetActiveCsList), 0);
if(s8tmp == M2M_SUCCESS)
{
if(gpfAppSSLCb)
gpfAppSSLCb(M2M_SSL_RESP_SET_CS_LIST, &strCsList);
}
}
break;
case M2M_SSL_RESP_WRITE_OWN_CERTS:
{
tstrTlsSrvChunkHdr strTlsSrvChunkRsp;
uint8 bCallApp = 1;
s8tmp = hif_receive(u32Addr, (uint8 *)&strTlsSrvChunkRsp, sizeof(tstrTlsSrvChunkHdr), 0);
if(s8tmp == M2M_SUCCESS)
{
uint16 offset = strTlsSrvChunkRsp.u16Offset32;
uint16 chunk_size = strTlsSrvChunkRsp.u16Size32;
uint16 total_size = strTlsSrvChunkRsp.u16TotalSize32;
tenuTlsFlashStatus status = (tenuTlsFlashStatus)(strTlsSrvChunkRsp.u16Sig);
/* If first chunk, reset status. */
if(offset == 0)
genuStatus = TLS_FLASH_OK_NO_CHANGE;
/* Only send status to app when processing last chunk. */
if(offset + chunk_size != total_size)
bCallApp = 0;
switch(status)
{
case TLS_FLASH_OK:
// Good flash write. Update status if no errors yet.
if(genuStatus == TLS_FLASH_OK_NO_CHANGE)
genuStatus = status;
break;
case TLS_FLASH_OK_NO_CHANGE:
// No change, don't update status.
break;
case TLS_FLASH_ERR_CORRUPT:
// Corrupt. Always update status.
genuStatus = status;
break;
case TLS_FLASH_ERR_NO_CHANGE:
// Failed flash write. Update status if no more serious error.
if((genuStatus != TLS_FLASH_ERR_CORRUPT) && (genuStatus != TLS_FLASH_ERR_UNKNOWN))
genuStatus = status;
break;
default:
// Don't expect any other case. Ensure we don't mask a previous corrupt error.
if(genuStatus != TLS_FLASH_ERR_CORRUPT)
genuStatus = TLS_FLASH_ERR_UNKNOWN;
break;
}
}
if(bCallApp && gpfAppSSLCb)
gpfAppSSLCb(M2M_SSL_RESP_WRITE_OWN_CERTS, &genuStatus);
}
break;
}
if(s8tmp != M2M_SUCCESS)
{
M2M_ERR("Error receiving SSL from the HIF\n");
}
}
/*!
@fn NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb)
@brief Initializes the SSL layer.
@param [in] pfAppSslCb
Application SSL callback function.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb)
{
sint8 s8Ret = M2M_SUCCESS;
gpfAppSSLCb = pfAppSSLCb;
gu32HIFAddr = 0;
genuStatus = TLS_FLASH_ERR_UNKNOWN;
s8Ret = hif_register_cb(M2M_REQ_GROUP_SSL, m2m_ssl_cb);
if(s8Ret != M2M_SUCCESS)
{
M2M_ERR("hif_register_cb() failed with ret=%d", s8Ret);
}
return s8Ret;
}
/*!
@fn NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz)
@brief Sends ECC responses to the WINC.
@param[in] strECCResp
ECC Response struct.
@param[in] pu8RspDataBuff
Pointer of the response data to be sent.
@param[in] u16RspDataSz
Response data size.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo *strECCResp, uint8 *pu8RspDataBuff, uint16 u16RspDataSz)
{
sint8 s8Ret = M2M_SUCCESS;
s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_RESP_ECC | M2M_REQ_DATA_PKT), (uint8 *)strECCResp, sizeof(tstrEccReqInfo), pu8RspDataBuff, u16RspDataSz, sizeof(tstrEccReqInfo));
return s8Ret;
}
/*!
@fn NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8 *pu8Buffer, uint32 u32BufferSz)
@brief Sends certificates to the WINC
@param[in] pu8Buffer
Pointer to the certificates.
@param[in] u32BufferSz
Size of the certificates.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8 *pu8Buffer, uint32 u32BufferSz)
{
sint8 s8Ret = M2M_SUCCESS;
#define TXLIMIT (256 * 6)
if(u32BufferSz <= TXLIMIT)
{
// set chunk header for one chunk
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
tstrTlsSrvChunkHdr *pchkhdr = (tstrTlsSrvChunkHdr *)pu8Buffer;
#pragma GCC diagnostic pop
pchkhdr->u16Sig = TLS_CERTS_CHUNKED_SIG_VALUE;
pchkhdr->u16TotalSize32 = (u32BufferSz + 3) >> 2;
pchkhdr->u16Offset32 = 0;
pchkhdr->u16Size32 = (u32BufferSz + 3) >> 2;
s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, pu8Buffer, u32BufferSz, 0);
M2M_INFO("Transferred %lu bytes of cert data NON-CHUNKED\n", u32BufferSz);
}
else
{
// chunk it
// We are sneaking in a header - tstrTlsSrvChunkHdr
#define CHUNKHDRSZ (sizeof(tstrTlsSrvChunkHdr))
#define CHUNKSZ (TXLIMIT - 256) // divisible by 4
uint8 saveblob[CHUNKHDRSZ];
uint32 ofs = 0;
uint32 thischunksz = 0;
// first is special - over writing our header
m2m_memcpy(saveblob, &pu8Buffer[ofs], CHUNKHDRSZ);
thischunksz = min(CHUNKSZ, u32BufferSz-ofs); // no need to round up to quad words this time
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
tstrTlsSrvChunkHdr *pchkhdr = (tstrTlsSrvChunkHdr *)&pu8Buffer[ofs];
#pragma GCC diagnostic pop
pchkhdr->u16Sig = TLS_CERTS_CHUNKED_SIG_VALUE;
pchkhdr->u16TotalSize32 = ((u32BufferSz + 3) >> 2);
pchkhdr->u16Offset32 = ((ofs + 3) >> 2);
pchkhdr->u16Size32 = ((thischunksz + 3) >> 2);
s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, &pu8Buffer[ofs], thischunksz, 0);
M2M_INFO("Transferred %u bytes of cert data CHUNKED to offset %u total %u\n", thischunksz, ofs, u32BufferSz);
m2m_memcpy(&pu8Buffer[ofs], saveblob, CHUNKHDRSZ);
ofs += thischunksz;
while(ofs < u32BufferSz)
{
// Subsequent chunks write header before and send a little more
m2m_memcpy(saveblob, &pu8Buffer[ofs-CHUNKHDRSZ], CHUNKHDRSZ);
thischunksz = min(CHUNKSZ, u32BufferSz-ofs);
thischunksz = (thischunksz + 3) & 0xFFFFFFFC; // needs to round up to quad word length
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
pchkhdr = (tstrTlsSrvChunkHdr *)&pu8Buffer[ofs - CHUNKHDRSZ];
#pragma GCC diagnostic pop
pchkhdr->u16Sig = TLS_CERTS_CHUNKED_SIG_VALUE;
pchkhdr->u16TotalSize32 = ((u32BufferSz + 3) >> 2);
pchkhdr->u16Offset32 = ((ofs + 3) >> 2);
pchkhdr->u16Size32 = ((thischunksz + 3) >> 2);
s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_REQ_WRITE_OWN_CERTS | M2M_REQ_DATA_PKT), NULL, 0, &pu8Buffer[ofs - CHUNKHDRSZ], thischunksz + CHUNKHDRSZ, 0);
M2M_INFO("Transferred %lu bytes of cert data CHUNKED to offset %u total %u\n", thischunksz, ofs, u32BufferSz);
m2m_memcpy(&pu8Buffer[ofs - CHUNKHDRSZ], saveblob, CHUNKHDRSZ);
ofs += thischunksz;
}
}
return s8Ret;
}
/*!
@fn NMI_API sint8 m2m_ssl_retrieve_next_for_verifying(tenuEcNamedCurve *penuCurve, uint8 *pu8Value, uint16 *pu16ValueSz, uint8 *pu8Sig, uint16 *pu16SigSz, tstrECPoint *pstrKey);
@brief Retrieve the next set of information from the WINC for ECDSA verification.
@param[out] penuCurve
The named curve.
@param[out] pu8Value
Value retrieved for verification. This is the digest of the message, truncated/prepended to the appropriate size.
@param[inout] pu16ValueSz
in: Size of value buffer provided by caller.
out: Size of value retrieved (provided for convenience; the value size is in fact determined by the curve).
@param[out] pu8Sig
Signature retrieved for verification.
@param[inout] pu16SigSz
in: Size of signature buffer provided by caller.
out: Size of signature retrieved (provided for convenience; the signature size is in fact determined by the curve).
@param[out] pstrKey
Public key retrieved for verification.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
verification information is ready via @ref ECC_REQ_SIGN_VERIFY.
@warning If this function returns @ref M2M_ERR_FAIL, then any remaining verification info from
the WINC is lost.
*/
NMI_API sint8 m2m_ssl_retrieve_next_for_verifying(tenuEcNamedCurve *penuCurve, uint8 *pu8Value, uint16 *pu16ValueSz, uint8 *pu8Sig, uint16 *pu16SigSz, tstrECPoint *pstrKey)
{
sint8 s8Ret = M2M_ERR_FAIL;
uint16 u16HashSz, u16SigSz, u16KeySz;
if(gu32HIFAddr == 0) return M2M_ERR_FAIL;
if((NULL == penuCurve) || (NULL == pu8Value) || (NULL == pu16ValueSz) || (NULL == pu8Sig) || (NULL == pu16SigSz) || (NULL == pstrKey))
{
s8Ret = M2M_ERR_INVALID_ARG;
goto __ERR;
}
if(hif_receive(gu32HIFAddr, (uint8 *)&u16KeySz, 2, 0) != M2M_SUCCESS) goto __ERR;
*penuCurve = _htons(u16KeySz);
gu32HIFAddr += 2;
if(hif_receive(gu32HIFAddr, (uint8 *)&u16KeySz, 2, 0) != M2M_SUCCESS) goto __ERR;
u16KeySz = _htons(u16KeySz);
if(u16KeySz > sizeof(pstrKey->X)) goto __ERR;
pstrKey->u16Size = u16KeySz;
gu32HIFAddr += 2;
if(hif_receive(gu32HIFAddr, (uint8 *)&u16HashSz, 2, 0) != M2M_SUCCESS) goto __ERR;
u16HashSz = _htons(u16HashSz);
if(u16HashSz > *pu16ValueSz) goto __ERR;
*pu16ValueSz = u16HashSz;
gu32HIFAddr += 2;
if(hif_receive(gu32HIFAddr, (uint8 *)&u16SigSz, 2, 0) != M2M_SUCCESS) goto __ERR;
u16SigSz = _htons(u16SigSz);
if(u16SigSz > *pu16SigSz) goto __ERR;
*pu16SigSz = u16SigSz;
gu32HIFAddr += 2;
if(hif_receive(gu32HIFAddr, pstrKey->X, u16KeySz, 0) != M2M_SUCCESS) goto __ERR;
gu32HIFAddr += u16KeySz;
if(hif_receive(gu32HIFAddr, pstrKey->Y, u16KeySz, 0) != M2M_SUCCESS) goto __ERR;
gu32HIFAddr += u16KeySz;
if(hif_receive(gu32HIFAddr, pu8Value, u16HashSz, 0) != M2M_SUCCESS) goto __ERR;
gu32HIFAddr += u16HashSz;
if(hif_receive(gu32HIFAddr, pu8Sig, u16SigSz, 0) != M2M_SUCCESS) goto __ERR;
gu32HIFAddr += u16SigSz;
return M2M_SUCCESS;
__ERR:
if(hif_receive(0, NULL, 0, 1) != M2M_SUCCESS) M2M_ERR("hif rx done failed\n");
return s8Ret;
}
/*!
@fn NMI_API sint8 m2m_ssl_retrieve_cert(uint16* pu16Curve, uint8* pu8Value, uint8* pu8Sig, tstrECPoint* pstrKey);
@brief Retrieve the next set of information from the WINC for ECDSA verification.
@param[out] pu16Curve
The named curve, to be cast to type @ref tenuEcNamedCurve.
@param[out] pu8Value
Value retrieved for verification. This is the digest of the message, truncated/prepended to the appropriate size.
The size of the value is equal to the field size of the curve, hence is determined by pu16Curve.
@param[out] pu8Sig
Signature retrieved for verification.
The size of the signature is equal to twice the field size of the curve, hence is determined by pu16Curve.
@param[out] pstrKey
Public key retrieved for verification.
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
verification information is ready via @ref ECC_REQ_SIGN_VERIFY.
@warning If this function returns @ref M2M_ERR_FAIL, then any remaining verification info from
the WINC is lost.
@warning This API has been deprecated and is kept for legacy purposes only. It is recommended
that @ref m2m_ssl_retrieve_next_for_verifying is used instead.
*/
NMI_API sint8 m2m_ssl_retrieve_cert(uint16 *pu16Curve, uint8 *pu8Value, uint8 *pu8Sig, tstrECPoint *pstrKey)
{
uint16 u16ValueSz = 32, u16SigSz = 64;
return m2m_ssl_retrieve_next_for_verifying((tenuEcNamedCurve *)pu16Curve, pu8Value, &u16ValueSz, pu8Sig, &u16SigSz, pstrKey);
}
/*!
@fn NMI_API sint8 m2m_ssl_retrieve_hash(uint8* pu8Value, uint16 u16ValueSz)
@brief Retrieve the value from the WINC for ECDSA signing.
@param[out] pu8Value
Value retrieved for signing. This is the digest of the message, truncated/prepended to the appropriate size.
@param[in] u16ValueSz
Size of value to be retrieved. (The application should obtain this information,
along with the curve, from the associated @ref ECC_REQ_SIGN_GEN notification.)
@return The function returns @ref M2M_SUCCESS for success and a negative value otherwise.
@pre This function should only be called after the application has been notified that
signing information is ready via @ref ECC_REQ_SIGN_GEN.
@warning If this function returns @ref M2M_ERR_FAIL, then the value for signing is lost.
*/
NMI_API sint8 m2m_ssl_retrieve_hash(uint8 *pu8Value, uint16 u16ValueSz)
{
sint8 s8Ret = M2M_ERR_FAIL;
if(gu32HIFAddr == 0) return M2M_ERR_FAIL;
if(NULL == pu8Value)
{
s8Ret = M2M_ERR_INVALID_ARG;
goto __ERR;
}
if(hif_receive(gu32HIFAddr, pu8Value, u16ValueSz, 0) != M2M_SUCCESS) goto __ERR;
return M2M_SUCCESS;
__ERR:
if(hif_receive(0, NULL, 0, 1) != M2M_SUCCESS) M2M_ERR("hif rx done failed\n");
return s8Ret;
}
/*!
@fn NMI_API void m2m_ssl_stop_retrieving(void);
@brief Allow SSL driver to tidy up when the application chooses not to retrieve all available
information.
@return None.
@warning The application must call this function if it has been notified (via
@ref ECC_REQ_SIGN_GEN or @ref ECC_REQ_SIGN_VERIFY) that information is available for
retrieving from the WINC, but chooses not to retrieve it all.
The application must not call this function if it has retrieved all the available
information, or if a retrieve function returned @ref M2M_ERR_FAIL indicating that any
remaining information has been lost.
@see m2m_ssl_retrieve_next_for_verifying\n
m2m_ssl_retrieve_cert\n
m2m_ssl_retrieve_hash
*/
NMI_API void m2m_ssl_stop_retrieving(void)
{
if(hif_receive(0, NULL, 0, 1) != M2M_SUCCESS) M2M_ERR("hif rx done failed\n");
}
/*!
@fn NMI_API void m2m_ssl_stop_processing_certs(void);
@brief Allow SSL driver to tidy up in case application does not read all available certificates.
@return None.
@warning This API has been deprecated and is kept for legacy purposes only. It is recommended
that @ref m2m_ssl_stop_retrieving is used instead.
*/
NMI_API void m2m_ssl_stop_processing_certs(void)
{
m2m_ssl_stop_retrieving();
}
/*!
@fn NMI_API void m2m_ssl_ecc_process_done(void);
@brief Allow SSL driver to tidy up after application has finished processing ECC message.
@return None.
@warning The application should call this function after receiving an SSL callback with message
type @ref M2M_SSL_REQ_ECC, after retrieving any related information, and before
calling @ref m2m_ssl_handshake_rsp.
*/
NMI_API void m2m_ssl_ecc_process_done(void)
{
gu32HIFAddr = 0;
}
/*!
@fn NMI_API sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP)
@brief Sets the active ciphersuites.
@details Override the default Active SSL ciphers in the SSL module with a certain combination selected by the caller in the form of
a bitmap containing the required ciphers to be on.
There is no need to call this function if the application will not change the default ciphersuites.
@param [in] u32SslCsBMP
Bitmap containing the desired ciphers to be enabled for the SSL module. The ciphersuites are defined in
@ref SSLCipherSuiteID.
The default ciphersuites are all ciphersuites supported by the firmware with the exception of ECC ciphersuites.
The caller can override the default with any desired combination.
If u32SslCsBMP does not contain any ciphersuites supported by firmware, then the current active list will not
change.
@return
- @ref SOCK_ERR_NO_ERROR
- @ref SOCK_ERR_INVALID_ARG
*/
NMI_API sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP)
{
sint8 s8Ret = M2M_SUCCESS;
tstrSslSetActiveCsList strCsList;
strCsList.u32CsBMP = u32SslCsBMP;
s8Ret = hif_send(M2M_REQ_GROUP_SSL, M2M_SSL_REQ_SET_CS_LIST, (uint8 *)&strCsList, sizeof(tstrSslSetActiveCsList), NULL, 0, 0);
return s8Ret;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,663 @@
/**
*
* \file
*
* \brief This module contains NMC1500 ASIC specific internal APIs.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "common/include/nm_common.h"
#include "driver/source/nmbus.h"
#include "bsp/include/nm_bsp.h"
#include "driver/source/nmasic.h"
#include "driver/include/m2m_types.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))
/*SPI and I2C only*/
#define CORT_HOST_COMM (0x10)
#define HOST_CORT_COMM (0x0b)
#define WAKE_CLK_REG (0x1)
#define CLOCKS_EN_REG (0xf)
#define TIMEOUT (0x2000ul)
#define WAKUP_TRAILS_TIMEOUT (4)
sint8 chip_apply_conf(uint32 u32Conf)
{
sint8 ret = M2M_SUCCESS;
uint32 val32 = u32Conf;
#if (defined __ENABLE_PMU__) || (defined CONF_WINC_INT_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
#if defined CONF_WINC_XO_XTALGM2_DIS
val32 |= rHAVE_XO_XTALGM2_DIS_BIT;
#endif
val32 |= rHAVE_RESERVED1_BIT;
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;
}
void chip_idle(void)
{
uint32 reg = 0;
nm_read_reg_with_ret(WAKE_CLK_REG, &reg);
if(reg & NBIT1)
{
reg &=~ NBIT1;
nm_write_reg(WAKE_CLK_REG, reg);
}
}
sint8 enable_interrupts(void)
{
uint32 reg = 0;
sint8 ret = M2M_SUCCESS;
/**
interrupt pin mux select
**/
ret = nm_read_reg_with_ret(NMI_PIN_MUX_0, &reg);
if (M2M_SUCCESS != ret) goto ERR1;
reg |= ((uint32) 1 << 8);
ret = nm_write_reg(NMI_PIN_MUX_0, reg);
if (M2M_SUCCESS != ret) goto ERR1;
/**
interrupt enable
**/
ret = nm_read_reg_with_ret(NMI_INTR_ENABLE, &reg);
if (M2M_SUCCESS != ret) goto ERR1;
reg |= ((uint32) 1 << 16);
ret = nm_write_reg(NMI_INTR_ENABLE, reg);
if (M2M_SUCCESS != ret) goto ERR1;
ERR1:
return ret;
}
sint8 cpu_start(void) {
uint32 reg = 0;
sint8 ret;
/**
reset regs
*/
ret = nm_write_reg(BOOTROM_REG,0);
ret += nm_write_reg(NMI_STATE_REG,0);
ret += nm_write_reg(NMI_REV_REG,0);
/**
Go...
**/
ret += nm_read_reg_with_ret(0x1118, &reg);
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);
}
reg |= (1ul << 10);
ret += nm_write_reg(NMI_GLB_RESET_0, reg);
nm_bsp_sleep(1);
return ret;
}
uint32 nmi_get_chipid(void)
{
static uint32 chipid = 0;
if (chipid == 0) {
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 if(chipid == 0x1000F0) {
if((nm_read_reg_with_ret(0x3B0000, &chipid)) != M2M_SUCCESS) {
chipid = 0;
return 0;
}
}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_sleep(void)
{
uint32 reg;
sint8 ret = M2M_SUCCESS;
while(1)
{
ret = nm_read_reg_with_ret(CORT_HOST_COMM,&reg);
if(ret != M2M_SUCCESS) goto ERR1;
if((reg & NBIT0) == 0) break;
}
/* Clear bit 1 */
ret = nm_read_reg_with_ret(WAKE_CLK_REG, &reg);
if(ret != M2M_SUCCESS)goto ERR1;
if(reg & NBIT1)
{
reg &=~NBIT1;
ret = nm_write_reg(WAKE_CLK_REG, reg);
if(ret != M2M_SUCCESS)goto ERR1;
}
ret = nm_read_reg_with_ret(HOST_CORT_COMM, &reg);
if(ret != M2M_SUCCESS)goto ERR1;
if(reg & NBIT0)
{
reg &= ~NBIT0;
ret = nm_write_reg(HOST_CORT_COMM, reg);
if(ret != M2M_SUCCESS)goto ERR1;
}
ERR1:
return ret;
}
sint8 chip_wake(void)
{
sint8 ret = M2M_SUCCESS;
uint32 reg = 0, clk_status_reg = 0,trials = 0;
nm_bus_speed(LOW);
ret = nm_read_reg_with_ret(HOST_CORT_COMM, &reg);
if(ret != M2M_SUCCESS)goto _WAKE_EXIT;
if(!(reg & NBIT0))
{
/*USE bit 0 to indicate host wakeup*/
ret = nm_write_reg(HOST_CORT_COMM, reg|NBIT0);
if(ret != M2M_SUCCESS)goto _WAKE_EXIT;
}
ret = nm_read_reg_with_ret(WAKE_CLK_REG, &reg);
if(ret != M2M_SUCCESS)goto _WAKE_EXIT;
/* Set bit 1 */
if(!(reg & NBIT1))
{
ret = nm_write_reg(WAKE_CLK_REG, reg | NBIT1);
if(ret != M2M_SUCCESS) goto _WAKE_EXIT;
}
do
{
ret = nm_read_reg_with_ret(CLOCKS_EN_REG, &clk_status_reg);
if(ret != M2M_SUCCESS) {
M2M_ERR("Bus error (5).%d %lx\n",ret,clk_status_reg);
goto _WAKE_EXIT;
}
if(clk_status_reg & NBIT2) {
break;
}
nm_bsp_sleep(2);
trials++;
if(trials > WAKUP_TRAILS_TIMEOUT)
{
M2M_ERR("Failed to wake up the chip\n");
ret = M2M_ERR_TIME_OUT;
goto _WAKE_EXIT;
}
}while(1);
/*workaround sometimes spi fail to read clock regs after reading/writing clockless registers*/
nm_bus_reset();
_WAKE_EXIT:
nm_bus_speed(HIGH);
return ret;
}
sint8 cpu_halt(void)
{
sint8 ret;
uint32 reg = 0;
ret = nm_read_reg_with_ret(0x1118, &reg);
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);
}
return ret;
}
sint8 chip_reset_and_cpu_halt(void)
{
sint8 ret = M2M_SUCCESS;
/*Wakeup needed only for I2C interface*/
ret = chip_wake();
if(ret != M2M_SUCCESS) goto ERR1;
/*Reset and CPU halt need for no wait board only*/
ret = chip_reset();
if(ret != M2M_SUCCESS) goto ERR1;
ret = cpu_halt();
if(ret != M2M_SUCCESS) goto ERR1;
ERR1:
return ret;
}
sint8 chip_reset(void)
{
sint8 ret = M2M_SUCCESS;
ret = nm_write_reg(NMI_GLB_RESET_0, 0);
nm_bsp_sleep(50);
return ret;
}
sint8 wait_for_bootrom(uint8 arg)
{
sint8 ret = M2M_SUCCESS;
uint32 reg = 0, cnt = 0;
uint32 u32GpReg1 = 0;
uint32 u32DriverVerInfo = M2M_MAKE_VERSION_INFO(M2M_RELEASE_VERSION_MAJOR_NO,\
M2M_RELEASE_VERSION_MINOR_NO, M2M_RELEASE_VERSION_PATCH_NO,\
M2M_MIN_REQ_DRV_VERSION_MAJOR_NO, M2M_MIN_REQ_DRV_VERSION_MINOR_NO,\
M2M_MIN_REQ_DRV_VERSION_PATCH_NO);
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(M2M_WIFI_MODE_ATE_HIGH == arg) {
nm_write_reg(NMI_REV_REG, M2M_ATE_FW_START_VALUE);
nm_write_reg(NMI_STATE_REG, NBIT20);
}else if(M2M_WIFI_MODE_ATE_LOW == arg) {
nm_write_reg(NMI_REV_REG, M2M_ATE_FW_START_VALUE);
nm_write_reg(NMI_STATE_REG, 0);
}else if(M2M_WIFI_MODE_ETHERNET == arg){
u32GpReg1 = rHAVE_ETHERNET_MODE_BIT;
nm_write_reg(NMI_STATE_REG, u32DriverVerInfo);
} else {
/*bypass this step*/
nm_write_reg(NMI_STATE_REG, u32DriverVerInfo);
}
if(REV(nmi_get_chipid()) >= REV_3A0){
chip_apply_conf(u32GpReg1 | rHAVE_USE_PMU_BIT);
} else {
chip_apply_conf(u32GpReg1);
}
M2M_INFO("DriverVerInfo: 0x%08lx\n",u32DriverVerInfo);
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;
uint32 u32Timeout = TIMEOUT;
volatile uint32 regAddress = NMI_STATE_REG;
volatile uint32 checkValue = M2M_FINISH_INIT_STATE;
if((M2M_WIFI_MODE_ATE_HIGH == arg)||(M2M_WIFI_MODE_ATE_LOW == 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 >= u32Timeout)
{
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;
/**
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");
goto ERR1;
}
reg &= ~(1 << 10);
ret = nm_write_reg(NMI_GLB_RESET_0, reg);
if (ret != M2M_SUCCESS) {
M2M_ERR("failed to de-initialize\n");
goto ERR1;
}
ERR1:
return ret;
}
#ifdef CONF_PERIPH
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;
}
#endif /* CONF_PERIPH */
sint8 nmi_get_otp_mac_address(uint8 *pu8MacAddr, uint8 * pu8IsValid)
{
sint8 ret;
uint32 u32RegValue;
uint8 mac[6];
tstrGpRegs strgp = {};
ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &u32RegValue);
if(ret != M2M_SUCCESS) goto _EXIT_ERR;
ret = nm_read_block(u32RegValue|0x30000,(uint8*)&strgp,sizeof(tstrGpRegs));
if(ret != M2M_SUCCESS) goto _EXIT_ERR;
u32RegValue = strgp.u32Mac_efuse_mib;
if(!EFUSED_MAC(u32RegValue)) {
M2M_DBG("Default MAC\n");
m2m_memset(pu8MacAddr, 0, 6);
goto _EXIT_ERR;
}
M2M_DBG("OTP MAC\n");
u32RegValue >>=16;
ret = nm_read_block(u32RegValue|0x30000, mac, 6);
m2m_memcpy(pu8MacAddr,mac,6);
if(pu8IsValid) *pu8IsValid = 1;
return ret;
_EXIT_ERR:
if(pu8IsValid) *pu8IsValid = 0;
return ret;
}
sint8 nmi_get_mac_address(uint8 *pu8MacAddr)
{
sint8 ret;
uint32 u32RegValue;
uint8 mac[6];
tstrGpRegs strgp = {};
ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &u32RegValue);
if(ret != M2M_SUCCESS) goto _EXIT_ERR;
ret = nm_read_block(u32RegValue|0x30000,(uint8*)&strgp,sizeof(tstrGpRegs));
if(ret != M2M_SUCCESS) goto _EXIT_ERR;
u32RegValue = strgp.u32Mac_efuse_mib;
u32RegValue &=0x0000ffff;
ret = nm_read_block(u32RegValue|0x30000, mac, 6);
m2m_memcpy(pu8MacAddr, mac, 6);
return ret;
_EXIT_ERR:
return ret;
}

View File

@ -0,0 +1,210 @@
/**
*
* \file
*
* \brief This module contains NMC1500 ASIC specific internal APIs.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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_GP_REG_2 (0xc0008)
#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 NMI_REV_REG_ATE (0x1048) /*Revision info register in case of ATE FW*/
#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 ISNMC3000(id) ((((id) & 0xfff00000) == 0x300000) ? 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)
#define rHAVE_ETHERNET_MODE_BIT (NBIT7)
#define rHAVE_RESERVED1_BIT (NBIT8)
#define rHAVE_RESERVED2_BIT (NBIT9)
#define rHAVE_XO_XTALGM2_DIS_BIT (NBIT10)
typedef struct{
uint32 u32Mac_efuse_mib;
uint32 u32Firmware_Ota_rev;
}tstrGpRegs;
#ifdef __cplusplus
extern "C" {
#endif
/*
* @fn cpu_halt
* @brief
*/
sint8 cpu_halt(void);
/*
* @fn chip_sleep
* @brief
*/
sint8 chip_sleep(void);
/*
* @fn chip_wake
* @brief
*/
sint8 chip_wake(void);
/*
* @fn chip_idle
* @brief
*/
void chip_idle(void);
/*
* @fn enable_interrupts
* @brief
*/
sint8 enable_interrupts(void);
/*
* @fn cpu_start
* @brief
*/
sint8 cpu_start(void);
/*
* @fn nmi_get_chipid
* @brief
*/
uint32 nmi_get_chipid(void);
/*
* @fn nmi_get_rfrevid
* @brief
*/
uint32 nmi_get_rfrevid(void);
/*
* @fn restore_pmu_settings_after_global_reset
* @brief
*/
void restore_pmu_settings_after_global_reset(void);
/*
* @fn nmi_update_pll
* @brief
*/
void nmi_update_pll(void);
/*
* @fn nmi_set_sys_clk_src_to_xo
* @brief
*/
void nmi_set_sys_clk_src_to_xo(void);
/*
* @fn chip_reset
* @brief
*/
sint8 chip_reset(void);
/*
* @fn wait_for_bootrom
* @brief
*/
sint8 wait_for_bootrom(uint8);
/*
* @fn wait_for_firmware_start
* @brief
*/
sint8 wait_for_firmware_start(uint8);
/*
* @fn chip_deinit
* @brief
*/
sint8 chip_deinit(void);
/*
* @fn chip_reset_and_cpu_halt
* @brief
*/
sint8 chip_reset_and_cpu_halt(void);
/*
* @fn set_gpio_dir
* @brief
*/
sint8 set_gpio_dir(uint8 gpio, uint8 dir);
/*
* @fn set_gpio_val
* @brief
*/
sint8 set_gpio_val(uint8 gpio, uint8 val);
/*
* @fn get_gpio_val
* @brief
*/
sint8 get_gpio_val(uint8 gpio, uint8* val);
/*
* @fn pullup_ctrl
* @brief
*/
sint8 pullup_ctrl(uint32 pinmask, uint8 enable);
/*
* @fn nmi_get_otp_mac_address
* @brief
*/
sint8 nmi_get_otp_mac_address(uint8 *pu8MacAddr, uint8 * pu8IsValid);
/*
* @fn nmi_get_mac_address
* @brief
*/
sint8 nmi_get_mac_address(uint8 *pu8MacAddr);
/*
* @fn chip_apply_conf
* @brief
*/
sint8 chip_apply_conf(uint32 u32conf);
#ifdef __cplusplus
}
#endif
#endif /*_NMASIC_H_*/

View File

@ -0,0 +1,293 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef CORTUS_APP
#include "nmbus.h"
#include "nmi2c.h"
#include "nmspi.h"
#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_reset
* @brief reset bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @version 1.0
*/
sint8 nm_bus_reset(void)
{
sint8 ret = M2M_SUCCESS;
#ifdef CONF_WINC_USE_UART
#elif defined (CONF_WINC_USE_SPI)
return nm_spi_reset();
#elif defined (CONF_WINC_USE_I2C)
#else
#error "Please define bus usage"
#endif
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);
#else
(void)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 "Please 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 "Please 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 "Please 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 "Please 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 "Please 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

View File

@ -0,0 +1,140 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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_reset
* @brief reset bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @version 1.0
*/
sint8 nm_bus_reset(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,410 @@
/**
*
* \file
*
* \brief This module contains NMC1000 M2M driver APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "common/include/nm_common.h"
#include "driver/source/nmbus.h"
#include "bsp/include/nm_bsp.h"
#include "driver/source/nmdrv.h"
#include "driver/source/nmasic.h"
#include "driver/include/m2m_types.h"
#include "spi_flash/include/spi_flash.h"
#ifdef CONF_WINC_USE_SPI
#include "driver/source/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
* @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);
//In case the Firmware running is ATE fw
if(M2M_ATE_FW_IS_UP_VALUE == reg)
{
//Read FW info again from the register specified for ATE
ret = nm_read_reg_with_ret(NMI_REV_REG_ATE, &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();
M2mRev->u16FirmwareSvnNum = 0;
curr_firm_ver = M2M_MAKE_VERSION(M2mRev->u8FirmwareMajor, M2mRev->u8FirmwareMinor,M2mRev->u8FirmwarePatch);
curr_drv_ver = M2M_MAKE_VERSION(M2M_RELEASE_VERSION_MAJOR_NO, M2M_RELEASE_VERSION_MINOR_NO, M2M_RELEASE_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_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_full_info(tstrM2mRev* pstrRev)
{
uint16 curr_drv_ver, min_req_drv_ver,curr_firm_ver;
uint32 reg = 0;
sint8 ret = M2M_SUCCESS;
tstrGpRegs strgp = {};
if (pstrRev != NULL)
{
m2m_memset((uint8*)pstrRev,0,sizeof(tstrM2mRev));
ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &reg);
if(ret == M2M_SUCCESS)
{
if(reg != 0)
{
ret = nm_read_block(reg|0x30000,(uint8*)&strgp,sizeof(tstrGpRegs));
if(ret == M2M_SUCCESS)
{
reg = strgp.u32Firmware_Ota_rev;
reg &= 0x0000ffff;
if(reg != 0)
{
ret = nm_read_block(reg|0x30000,(uint8*)pstrRev,sizeof(tstrM2mRev));
if(ret == M2M_SUCCESS)
{
curr_firm_ver = M2M_MAKE_VERSION(pstrRev->u8FirmwareMajor, pstrRev->u8FirmwareMinor,pstrRev->u8FirmwarePatch);
curr_drv_ver = M2M_MAKE_VERSION(M2M_RELEASE_VERSION_MAJOR_NO, M2M_RELEASE_VERSION_MINOR_NO, M2M_RELEASE_VERSION_PATCH_NO);
min_req_drv_ver = M2M_MAKE_VERSION(pstrRev->u8DriverMajor, pstrRev->u8DriverMinor,pstrRev->u8DriverPatch);
if((curr_firm_ver == 0)||(min_req_drv_ver == 0)||(min_req_drv_ver == 0)){
ret = M2M_ERR_FAIL;
goto EXIT;
}
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;
goto EXIT;
}
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;
goto EXIT;
}
}
} else {
ret = M2M_ERR_FAIL;
}
}
}else{
ret = M2M_ERR_FAIL;
}
}
}
EXIT:
return ret;
}
/**
* @fn nm_get_ota_firmware_info(tstrM2mRev* pstrRev)
* @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_ota_firmware_info(tstrM2mRev* pstrRev)
{
uint16 curr_drv_ver, min_req_drv_ver,curr_firm_ver;
uint32 reg = 0;
sint8 ret;
tstrGpRegs strgp = {};
if (pstrRev != NULL)
{
m2m_memset((uint8*)pstrRev,0,sizeof(tstrM2mRev));
ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &reg);
if(ret == M2M_SUCCESS)
{
if(reg != 0)
{
ret = nm_read_block(reg|0x30000,(uint8*)&strgp,sizeof(tstrGpRegs));
if(ret == M2M_SUCCESS)
{
reg = strgp.u32Firmware_Ota_rev;
reg >>= 16;
if(reg != 0)
{
ret = nm_read_block(reg|0x30000,(uint8*)pstrRev,sizeof(tstrM2mRev));
if(ret == M2M_SUCCESS)
{
curr_firm_ver = M2M_MAKE_VERSION(pstrRev->u8FirmwareMajor, pstrRev->u8FirmwareMinor,pstrRev->u8FirmwarePatch);
curr_drv_ver = M2M_MAKE_VERSION(M2M_RELEASE_VERSION_MAJOR_NO, M2M_RELEASE_VERSION_MINOR_NO, M2M_RELEASE_VERSION_PATCH_NO);
min_req_drv_ver = M2M_MAKE_VERSION(pstrRev->u8DriverMajor, pstrRev->u8DriverMinor,pstrRev->u8DriverPatch);
if((curr_firm_ver == 0)||(min_req_drv_ver == 0)||(min_req_drv_ver == 0)){
ret = M2M_ERR_FAIL;
goto EXIT;
}
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;
}
}
}else{
ret = M2M_ERR_INVALID;
}
}
}else{
ret = M2M_ERR_FAIL;
}
}
} else {
ret = M2M_ERR_INVALID_ARG;
}
EXIT:
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(void)
{
sint8 ret = M2M_SUCCESS;
ret = nm_bus_iface_init(NULL);
if (M2M_SUCCESS != ret) {
M2M_ERR("[nmi start]: fail init bus\n");
goto ERR1;
}
/**
TODO:reset the chip and halt the cpu in case of no wait efuse is set (add the no wait effuse check)
*/
// if(!ISNMC3000(GET_CHIPID()))
// {
// /*Execute that function only for 1500A/B, no room in 3000, but it may be needed in 3400 no wait*/
// chip_reset_and_cpu_halt();
// }
#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;
}
sint8 nm_drv_init_hold(void)
{
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 BUS_ONLY
return;
#endif
#ifdef NO_HW_CHIP_EN
ret = chip_wake();
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. */
ret = nm_spi_init();
#endif
return ret;
#ifdef NO_HW_CHIP_EN
ERR2:
nm_bus_iface_deinit();
#endif
ERR1:
return ret;
}
sint8 nm_drv_init_start(void * arg)
{
sint8 ret = M2M_SUCCESS;
uint8 u8Mode = M2M_WIFI_MODE_NORMAL;
if(NULL != arg) {
u8Mode = *((uint8 *)arg);
if((u8Mode < M2M_WIFI_MODE_NORMAL)||(u8Mode >= M2M_WIFI_MODE_MAX)) {
u8Mode = M2M_WIFI_MODE_NORMAL;
}
}
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_ATE_HIGH == u8Mode)||(M2M_WIFI_MODE_ATE_LOW == u8Mode)) {
goto ERR1;
} else {
/*continue running*/
}
ret = enable_interrupts();
if (M2M_SUCCESS != ret) {
M2M_ERR("failed to enable interrupts..\n");
goto ERR2;
}
return ret;
ERR2:
nm_bus_iface_deinit();
#ifdef CONF_WINC_USE_SPI
nm_spi_deinit();
#endif
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)
{
sint8 ret = M2M_SUCCESS;
ret = nm_drv_init_hold();
if(ret == M2M_SUCCESS)
ret = nm_drv_init_start(arg);
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*)
{
sint8 ret;
ret = chip_deinit();
if (M2M_SUCCESS != ret) {
M2M_ERR("[nmi stop]: chip_deinit fail\n");
goto ERR1;
}
/* Disable SPI flash to save power when the chip is off */
ret = spi_flash_enable(0);
if (M2M_SUCCESS != ret) {
M2M_ERR("[nmi stop]: SPI flash disable 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;
}

View File

@ -0,0 +1,153 @@
/**
*
* \file
*
* \brief This module contains NMC1500 M2M driver APIs declarations.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef _NMDRV_H_
#define _NMDRV_H_
#include "common/include/nm_common.h"
/**
* @struct tstrM2mRev
* @brief Structure holding firmware version parameters and build date/time
*/
typedef struct {
uint32 u32Chipid; /* HW revision which will be basically the chip ID */
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 patch Number which represents the patches 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 patches release base */
uint8 BuildDate[sizeof(__DATE__)];
uint8 BuildTime[sizeof(__TIME__)];
uint8 _PAD8_;
uint16 u16FirmwareSvnNum;
uint16 _PAD16_[2];
} tstrM2mRev;
/**
* @struct tstrM2mBinaryHeader
* @brief Structure holding compatibility version info for firmware binaries
*/
typedef struct {
tstrM2mRev binVerInfo;
uint32 flashOffset;
uint32 payloadSize;
} tstrM2mBinaryHeader;
#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_get_firmware_full_info(tstrM2mRev* pstrRev)
* @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_full_info(tstrM2mRev* pstrRev);
/**
* @fn nm_get_ota_firmware_info(tstrM2mRev* pstrRev)
* @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_ota_firmware_info(tstrM2mRev* pstrRev);
/*
* @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_init_hold
* @brief First part of nm_drv_init, up to the point of initializing spi for flash access.
* @see nm_drv_init
* @return M2M_SUCCESS in case of success and Negative error code in case of failure
* @param [in] req_serial_number
* Parameter inherited from nm_drv_init
* @return ZERO in case of success and Negative error code in case of failure
*/
sint8 nm_drv_init_hold(void);
/*
* @fn nm_drv_init_start
* @brief Second part of nm_drv_init, continuing from where nm_drv_init_hold left off.
* @see nm_drv_init
* @return M2M_SUCCESS in case of success and Negative error code in case of failure
* @param [in] arg
* Parameter inherited from nm_drv_init
* @return ZERO in case of success and Negative error code in case of failure
*/
sint8 nm_drv_init_start(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,262 @@
/**
*
* \file
*
* \brief This module contains NMC1000 I2C protocol bus APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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 */

View File

@ -0,0 +1,97 @@
/**
*
* \file
*
* \brief This module contains NMC1000 I2C protocol bus APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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,930 @@
/**
*
* \file
*
* \brief This module contains NMC1000 SPI protocol bus APIs implementation.
*
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "common/include/nm_common.h"
#ifdef CONF_WINC_USE_SPI
#include "bus_wrapper/include/nm_bus_wrapper.h"
#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_MISC_CTRL (NMI_SPI_REG_BASE+0x48)
#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 0
#define N_FAIL -1
#define N_RESET -2
#define N_RETRY -3
#define SPI_RESP_RETRY_COUNT (10)
#define SPI_RETRY_COUNT (10)
#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 uint8 gu8Crc_off = 0;
static inline sint8 nmi_spi_read(uint8 *b, uint16 sz)
{
return nm_spi_rw(NULL, b, sz);
}
static inline sint8 nmi_spi_write(uint8 *b, uint16 sz)
{
return nm_spi_rw(b, NULL, sz);
}
static sint8 nmi_spi_writeread(uint8 *bw, uint8 *br, uint16 sz)
{
return nm_spi_rw(bw, br, sz);
}
/********************************************
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 inline uint8 crc7_byte(uint8 crc, uint8 data)
{
return crc7_syndrome_table[(crc << 1) ^ data];
}
static inline uint8 crc7(uint8 crc, const uint8 *buffer, uint32 len)
{
while (len--)
crc = crc7_byte(crc, *buffer++);
return crc;
}
/********************************************
Spi protocol Function
********************************************/
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;
#if defined(CMD_TERMINATE)
case CMD_TERMINATE: /* termination */
bc[1] = 0x00;
bc[2] = 0x00;
bc[3] = 0x00;
len = 5;
break;
#endif
#if defined(CMD_REPEAT)
case CMD_REPEAT: /* repeat */
bc[1] = 0x00;
bc[2] = 0x00;
bc[3] = 0x00;
len = 5;
break;
#endif
case CMD_RESET: /* reset */
bc[1] = 0xff;
bc[2] = 0xff;
bc[3] = 0xff;
len = 5;
break;
#if defined(CMD_DMA_WRITE) || defined(CMD_DMA_READ)
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;
#endif
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 == N_OK) {
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_data_rsp(uint8 cmd)
{
uint8 len;
uint8 rsp[3];
sint8 result = N_OK;
if (!gu8Crc_off)
len = 2;
else
len = 3;
if (M2M_SUCCESS != nmi_spi_read(&rsp[0], len)) {
M2M_ERR("[nmi spi]: Failed bus error...\n");
result = N_FAIL;
goto _fail_;
}
if((rsp[len-1] != 0)||(rsp[len-2] != 0xC3))
{
M2M_ERR("[nmi spi]: Failed data response read, %x %x %x\n",rsp[0],rsp[1],rsp[2]);
result = N_FAIL;
goto _fail_;
}
_fail_:
return result;
}
static sint8 spi_cmd_rsp(uint8 cmd)
{
uint8 rsp;
sint8 result = N_OK;
sint8 s8RetryCnt;
/**
Command/Control response
**/
#if defined(CMD_TERMINATE)
if(cmd == CMD_TERMINATE) {
if(M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
result = N_FAIL;
goto _fail_;
}
}
#endif
#if defined(CMD_REPEAT)
if(cmd == CMD_REPEAT) {
if (M2M_SUCCESS != nmi_spi_read(&rsp, 1)) {
result = N_FAIL;
goto _fail_;
}
}
#endif
/* wait for response */
s8RetryCnt = SPI_RESP_RETRY_COUNT;
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 = SPI_RESP_RETRY_COUNT;
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;
}
sint8 nm_spi_reset(void)
{
//M2M_INFO("Reset Spi\n");
spi_cmd(CMD_RESET, 0, 0, 0, 0);
if(spi_cmd_rsp(CMD_RESET) != N_OK) {
// Reset command failed, need to send repeated 1's until reset occurs
uint8 w_buf[8] = {0xFF};
uint8 r_buf[8];
M2M_ERR("[nmi spi]: Failed rst cmd response\n");
nmi_spi_writeread(w_buf, r_buf, 8);
if(r_buf[7] != 0xFF)
{
M2M_ERR("[nmi spi]: Failed repeated reset\n");
return N_FAIL;
}
}
return N_OK;
}
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 Response header
**/
retry = SPI_RESP_RETRY_COUNT;
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 & 0xf0) == 0xf0)
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 = 0;
uint16 nbytes;
sint8 result = N_OK;
uint8 cmd, order, crc[2] = {0};
//uint8 rsp;
/**
Data
**/
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
********************************************/
/**
* @fn nm_spi_write_reg
* @brief Write register
* @param[in] u32Addr
* Register address
* @param[in] u32Val
* Value to be written to the register
* @return @ref M2M_SUCCESS in case of success and @ref M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_write_reg(uint32 addr, uint32 u32data)
{
uint8 retry = SPI_RETRY_COUNT;
sint8 result = N_OK;
uint8 cmd = CMD_SINGLE_WRITE;
uint8 clockless = 0;
_RETRY_:
if (addr <= 0x30)
{
/**
NMC1000 clockless registers.
**/
cmd = CMD_INTERNAL_WRITE;
clockless = 1;
}
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);
goto _FAIL_;
}
result = spi_cmd_rsp(cmd);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed cmd response, write reg (%08x)...\n", (unsigned int)addr);
goto _FAIL_;
}
_FAIL_:
if(result != N_OK)
{
nm_bsp_sleep(1);
spi_cmd(CMD_RESET, 0, 0, 0, 0);
spi_cmd_rsp(CMD_RESET);
M2M_ERR("Reset and retry %d %x %x\n",retry,addr,u32data);
nm_bsp_sleep(1);
retry--;
if(retry) goto _RETRY_;
}
return result;
}
static sint8 nm_spi_write(uint32 addr, uint8 *buf, uint16 size)
{
sint8 result;
uint8 retry = SPI_RETRY_COUNT;
uint8 cmd = CMD_DMA_EXT_WRITE;
_RETRY_:
/**
Command
**/
//Workaround hardware problem with single byte transfers over SPI bus
if (size == 1)
size = 2;
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);
goto _FAIL_;
}
result = spi_cmd_rsp(cmd);
if (result != N_OK) {
M2M_ERR("[nmi spi ]: Failed cmd response, write block (%08x)...\n", (unsigned int)addr);
goto _FAIL_;
}
/**
Data
**/
result = spi_data_write(buf, size);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed block data write...\n");
goto _FAIL_;
}
/**
Data RESP
**/
result = spi_data_rsp(cmd);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed block data write...\n");
goto _FAIL_;
}
_FAIL_:
if(result != N_OK)
{
nm_bsp_sleep(1);
spi_cmd(CMD_RESET, 0, 0, 0, 0);
spi_cmd_rsp(CMD_RESET);
M2M_ERR("Reset and retry %d %x %d\n",retry,addr,size);
nm_bsp_sleep(1);
retry--;
if(retry) goto _RETRY_;
}
return result;
}
/**
* @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 @ref M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_read_reg_with_ret(uint32 addr, uint32 *u32data)
{
uint8 retry = SPI_RETRY_COUNT;
volatile sint8 result = N_OK;
uint8 cmd = CMD_SINGLE_READ;
uint8 tmp[4];
uint8 clockless = 0;
_RETRY_:
if (addr <= 0xff)
{
/**
NMC1000 clockless registers.
**/
cmd = CMD_INTERNAL_READ;
clockless = 1;
}
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);
goto _FAIL_;
}
result = spi_cmd_rsp(cmd);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed cmd response, read reg (%08x)...\n", (unsigned int)addr);
goto _FAIL_;
}
/* to avoid endianness issues */
result = spi_data_read(&tmp[0], 4, clockless);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed data read...\n");
goto _FAIL_;
}
*u32data = tmp[0] |
((uint32)tmp[1] << 8) |
((uint32)tmp[2] << 16) |
((uint32)tmp[3] << 24);
_FAIL_:
if(result != N_OK)
{
nm_bsp_sleep(1);
spi_cmd(CMD_RESET, 0, 0, 0, 0);
spi_cmd_rsp(CMD_RESET);
M2M_ERR("Reset and retry %d %lx\n",retry,addr);
nm_bsp_sleep(1);
retry--;
if(retry) goto _RETRY_;
}
return result;
}
static sint8 nm_spi_read(uint32 addr, uint8 *buf, uint16 size)
{
uint8 cmd = CMD_DMA_EXT_READ;
sint8 result;
uint8 retry = SPI_RETRY_COUNT;
uint8 tmp[2];
uint8 single_byte_workaround = 0;
_RETRY_:
/**
Command
**/
if (size == 1)
{
//Workaround hardware problem with single byte transfers over SPI bus
size = 2;
single_byte_workaround = 1;
}
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);
goto _FAIL_;
}
result = spi_cmd_rsp(cmd);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed cmd response, read block (%08x)...\n", (unsigned int)addr);
goto _FAIL_;
}
/**
Data
**/
if (single_byte_workaround)
{
result = spi_data_read(tmp, size,0);
buf[0] = tmp[0];
}
else
result = spi_data_read(buf, size,0);
if (result != N_OK) {
M2M_ERR("[nmi spi]: Failed block data read...\n");
goto _FAIL_;
}
_FAIL_:
if(result != N_OK)
{
nm_bsp_sleep(1);
spi_cmd(CMD_RESET, 0, 0, 0, 0);
spi_cmd_rsp(CMD_RESET);
M2M_ERR("Reset and retry %d %lx %d\n",retry,addr,size);
nm_bsp_sleep(1);
retry--;
if(retry) goto _RETRY_;
}
return result;
}
/********************************************
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 @ref M2M_SUCCESS in case of success and @ref M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_init(void)
{
uint32 chipid;
uint32 reg = 0;
/**
configure protocol
**/
gu8Crc_off = 0;
if(nm_spi_read_reg_with_ret(NMI_SPI_PROTOCOL_CONFIG, &reg) != M2M_SUCCESS) {
/* 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, retrying with CRC off...\n");
if(nm_spi_read_reg_with_ret(NMI_SPI_PROTOCOL_CONFIG, &reg) != M2M_SUCCESS) {
// Read failed with both CRC on and off, something went bad
M2M_ERR( "[nmi spi]: Failed internal read protocol...\n");
return M2M_ERR_BUS_FAIL;
}
}
if(gu8Crc_off == 0)
{
reg &= ~0xc; /* disable crc checking */
reg &= ~0x70;
reg |= (0x5 << 4);
if(nm_spi_write_reg(NMI_SPI_PROTOCOL_CONFIG, reg) != M2M_SUCCESS) {
M2M_ERR( "[nmi spi]: Failed internal write protocol reg...\n");
return M2M_ERR_BUS_FAIL;
}
gu8Crc_off = 1;
}
/**
make sure can read back chip id correctly
**/
if(nm_spi_read_reg_with_ret(0x1000, &chipid) != M2M_SUCCESS) {
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 @ref M2M_SUCCESS in case of success and @ref M2M_ERR_BUS_FAIL in case of failure
*/
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
*/
uint32 nm_spi_read_reg(uint32 u32Addr)
{
uint32 u32Val;
nm_spi_read_reg_with_ret(u32Addr, &u32Val);
return 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 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

View File

@ -0,0 +1,125 @@
/**
*
* \file
*
* \brief This module contains NMC1000 SPI protocol bus APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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_reset
* @brief reset the SPI
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_reset(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,538 @@
/**
*
* \file
*
* \brief This module contains NMC1000 UART protocol bus APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "common/include/nm_common.h"
#ifdef CONF_WINC_USE_UART
#include "driver/source/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 retries = 1;
/*read reg*/
while (retries--)
{
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;
b[0] = 0;
// Pull all chars from buffer, we only care about the last
while (M2M_SUCCESS == nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart))
{
strUart.u16Sz = rsz;
}
if (b[0] == 0x5a)
{
s8Ret = 1; // found on-chip (no bridge)
M2M_INFO("Built-in WINC1500 UART Found\n");
}
else if (b[0] == 0x5b)
{
s8Ret = 0; // found off-chip (std serial bridge)
M2M_INFO("WINC1500 Serial Bridge Found\n");
}
else if (b[0] == 0x5c)
{
s8Ret = 0; // found of-chip (at cmd app serial bridge)
M2M_INFO("WINC1500 Serial Bridge Found + AT CMD app Found\n");
}
else
{
continue;
}
break;
}
else
{
M2M_ERR("failed to send cfg bytes\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
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;
}
*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 */

View File

@ -0,0 +1,111 @@
/**
*
* \file
*
* \brief This module contains NMC1000 UART protocol bus APIs implementation.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \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,62 @@
/**
*
* \file
*
* \brief WINC Peripherals Application Interface.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef __PROGRAMMER_H__
#define __PROGRAMMER_H__
/**
* Include
*/
#include "spi_flash/include/spi_flash_map.h"
#include "spi_flash/include/spi_flash.h"
#define ROOT_CERT_SIZE M2M_TLS_ROOTCER_FLASH_SIZE
#define programmer_get_flash_size() (((spi_flash_get_size()*1024)/8)*1024)
#define programmer_write(pu8Buf, u32Offset, u32Sz) spi_flash_write(pu8Buf, u32Offset, u32Sz)
#define programmer_erase(u32Offset, u32Sz) spi_flash_erase(u32Offset, u32Sz)
#define programmer_eraseall() programmer_erase(0, programmer_get_flash_size())
#define programmer_read(pu8Buf, u32Offset, u32Sz) spi_flash_read(pu8Buf, u32Offset, u32Sz)
#define programmer_write_root_cert(buff) programmer_write((uint8*)buff, M2M_TLS_ROOTCER_FLASH_OFFSET, M2M_TLS_ROOTCER_FLASH_SIZE)
#define programmer_read_root_cert(buff) programmer_read((uint8*)buff, M2M_TLS_ROOTCER_FLASH_OFFSET, M2M_TLS_ROOTCER_FLASH_SIZE)
#define programmer_erase_root_cert() programmer_erase(M2M_TLS_ROOTCER_FLASH_OFFSET, M2M_TLS_ROOTCER_FLASH_SIZE)
#define programmer_write_tls_cert_store(buff) programmer_write((uint8*)buff, M2M_TLS_SERVER_FLASH_OFFSET, M2M_TLS_SERVER_FLASH_SIZE)
#define programmer_read_tls_cert_store(buff) programmer_read((uint8*)buff, M2M_TLS_SERVER_FLASH_OFFSET, M2M_TLS_SERVER_FLASH_SIZE)
#define programmer_erase_tls_cert_store() programmer_erase(M2M_TLS_SERVER_FLASH_OFFSET, M2M_TLS_SERVER_FLASH_SIZE)
#endif /* __PROGRAMMER_H__ */

View File

@ -0,0 +1,8 @@
Firmware generated from repo https://github.com/Microchip-MPLAB-Harmony/wireless_wifi like this:
`git clone https://github.com/Microchip-MPLAB-Harmony/wireless_wifi.git`
`cd wireless_wifi/utilities/wifi/winc`
`./winc_flash_tool.sh -i aio -d WINC1500 -v 19.7.7`
firmware image then exists in `wireless_wifi/utilities/wifi/winc/files/winc1500`
Driver is slightly modified from the one in `wireless_wifi/driver/winc/winc1500_19.7.7` (cpp-ified, mostly).

View File

@ -0,0 +1,504 @@
/**
*
* \file
*
* \brief BSD compatible socket interface internal types.
*
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef __M2M_SOCKET_HOST_IF_H__
#define __M2M_SOCKET_HOST_IF_H__
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#ifndef _BOOT_
#ifndef _FIRMWARE_
#include "socket/include/socket.h"
#else
#include "m2m_types.h"
#endif
#endif
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*
* HOSTNAME_MAX_SIZE is defined here and also in host_drv/socket/include/socket.h
* The two definitions must match.
*/
#ifdef _FIRMWARE_
#define HOSTNAME_MAX_SIZE (64)
#endif
#define SSL_MAX_OPT_LEN HOSTNAME_MAX_SIZE
#define ALPN_LIST_MIN_SIZE 4
#define ALPN_LIST_MAX_SIZE 32
/*!<
Maximum length of ALPN list that can be specified by the application.
The list is in the following format:
@verbatim
0 1 2 3 ... (bytes)
+-------+-------+-------+ ... +-------+ ... +-------+ ...
| Length L (BE) | len1 | name1... | len2 | name2... | len3 | name3...
+-------+-------+-------+ ... +-------+ ... +-------+ ...
Length fields do not include themselves.
@endverbatim
*/
#define SOCKET_CMD_INVALID 0x00
/*!<
Invalid 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 Receive command value.
*/
#define SOCKET_CMD_SENDTO 0x47
/*!<
Socket sendTo command value.
*/
#define SOCKET_CMD_RECVFROM 0x48
/*!<
Socket ReceiveFrom 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 Receive 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 SOCKET_CMD_SSL_SET_CS_LIST 0x53
/*!<
Recommend instead using @ref M2M_SSL_REQ_SET_CS_LIST and
associated response @ref M2M_SSL_RESP_SET_CS_LIST
*/
#define SOCKET_CMD_SSL_BIND 0x54
/*!<
*/
#define SOCKET_CMD_SSL_EXP_CHECK 0x55
/*!<
*/
#define SOCKET_CMD_SECURE 0x56
/*!<
Make secure a previously opened socket.
*/
#define SOCKET_CMD_SSL_CONNECT_ALPN 0x57
/*!<
SSL-Socket Connect with ALPN command value.
*/
#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 u16AppDataOffset;
/*!<
In further packet send requests the host interface should put the user application
data at this offset in the allocated shared data packet.
*/
}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;
/*!<
0 for successful connection, in which case u16AppDataOffset is valid.
Negative for failed connection, in which case u8ErrorType and u8ErrorDetail may give more info.
*/
union {
uint16 u16AppDataOffset;
/*!<
In further packet send requests the host interface should put the user application
data at this offset in the allocated shared data packet.
*/
struct {
uint8 u8ErrSource;
/*!<
0: No detail
1: TLS Alert received from peer
2: TLS Alert generated locally
*/
uint8 u8ErrCode;
/*!<
For TLS Alerts, this is the Alert ID.
*/
};
};
}tstrConnectReply;
/*!
@struct \
tstrConnectAlpnReply
@brief
Connect Reply, contains sock number, error value and index of negotiated application protocol.
*/
typedef struct{
tstrConnectReply strConnReply;
uint8 u8AppProtocolIdx;
/*!<
1-based index of application-layer protocol negotiated during TLS handshake.
*/
uint8 __PAD24__[3];
}tstrConnectAlpnReply;
/*!
@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;
uint16 u16BufLen;
}tstrRecvCmd;
/*!
@struct \
tstrRecvReply
@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;
/*!
@struct\
tstrSslCertExpSettings
@brief SSL Certificate Expiry Validation Settings
@sa tenuSslCertExpSettings
*/
typedef struct{
uint32 u32CertExpValidationOpt;
/*!<
See @tenuSslCertExpSettings for possible values.
*/
}tstrSslCertExpSettings;
#endif /* __M2M_SOCKET_HOST_IF_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,52 @@
/**
*
* \file
*
* \brief BSD compatible socket interface internal types.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef __SOCKET_INTERNAL_H__
#define __SOCKET_INTERNAL_H__
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
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);
#endif /* __SOCKET_H__ */

View File

@ -0,0 +1,87 @@
/**
*
* \file
*
* \brief WINC1500 SPI Flash.
*
* Copyright (c) 2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifndef __FLEXIBLE_FLASH_H__
#define __FLEXIBLE_FLASH_H__
typedef struct {
uint32 magic;
uint32 max_size;
}tstrFlashLUTHeader;
// NOTE: Don't use enums for id/status here,
// they need to be 16 bit but the enums end up as
// 32 bit even if the __packed__ attribute is used
typedef struct {
uint16 id;
uint8 sector;
uint8 size;
uint32 reserved;
}tstrFlashLUTEntry;
#define FLASHMAP_MAGIC_VALUE 0x1ABCDEF9
#define FLASHMAP_MAX_ENTRIES 32
// + 8 is for the number of entries value (uint32) and CRC (uint32)
// * 2 is for the new lookup table to apply
// + 48 is for the progress monitor
#define FLASHMAP_MAX_SIZE (sizeof(tstrFlashLUTHeader) + (((sizeof(tstrFlashLUTEntry) * FLASHMAP_MAX_ENTRIES) + 8) * 2) + 48)
/** @defgroup SPiFlashRead spi_flexible_flash_find_section
* @ingroup SPIFLASHAPI
*/
/**@{*/
/*!
* @fn sint8 spi_flexible_flash_find_section(uint16 u16EntryIDToLookFor, uint32 *pu32StartOffset, uint32 *pu32Size);
* @brief Read the Flash Map to extract the host file starting offset.\n
* @param [in] u16EntryIDToLookFor
* The ID of the location in Flash we are looking for. See @ref tenuFlashLUTEntryID.
* @param [in] pu32StartOffset
* Pointer to the variable where the Flash section start address should be stored.
* @param [in] pu32Size
* Pointer to the variable where the Flash section size should be stored.
* @warning
* In case there is a running WINC firmware, it is required to pause the firmware
* first before any trial to access SPI flash to avoid any racing between host and
* running firmware on bus. @ref m2m_wifi_download_mode can be used to pause the firmware.
* @sa m2m_wifi_download_mode
* m2m_wifi_init_hold
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
sint8 spi_flexible_flash_find_section(uint16 u16EntryIDToLookFor, uint32 *pu32StartOffset, uint32 *pu32Size);
/**@}*/
#endif /* __FLEXIBLE_FLASH_H__ */

View File

@ -0,0 +1,220 @@
/**
*
* \file
*
* \brief WINC1500 SPI Flash.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
/** \defgroup SPIFLASH Spi Flash
* @file spi_flash.h
* @brief This file describe SPI flash APIs, how to use it and limitations with each one.
* @section Example
* This example illustrates a complete guide of how to use these APIs.
* @code{.c}
#include "spi_flash.h"
#define DATA_TO_REPLACE "THIS IS A NEW SECTOR IN FLASH"
int main()
{
uint8 au8FlashContent[FLASH_SECTOR_SZ] = {0};
uint32 u32FlashTotalSize = 0;
uint32 u32FlashOffset = 0;
ret = m2m_wifi_download_mode();
if(M2M_SUCCESS != ret)
{
printf("Unable to enter download mode\r\n");
}
else
{
u32FlashTotalSize = spi_flash_get_size();
}
while((u32FlashTotalSize > u32FlashOffset) && (M2M_SUCCESS == ret))
{
ret = spi_flash_read(au8FlashContent, u32FlashOffset, FLASH_SECTOR_SZ);
if(M2M_SUCCESS != ret)
{
printf("Unable to read SPI sector\r\n");
break;
}
memcpy(au8FlashContent, DATA_TO_REPLACE, strlen(DATA_TO_REPLACE));
ret = spi_flash_erase(u32FlashOffset, FLASH_SECTOR_SZ);
if(M2M_SUCCESS != ret)
{
printf("Unable to erase SPI sector\r\n");
break;
}
ret = spi_flash_write(au8FlashContent, u32FlashOffset, FLASH_SECTOR_SZ);
if(M2M_SUCCESS != ret)
{
printf("Unable to write SPI sector\r\n");
break;
}
u32FlashOffset += FLASH_SECTOR_SZ;
}
if(M2M_SUCCESS == ret)
{
printf("Successful operations\r\n");
}
else
{
printf("Failed operations\r\n");
}
while(1);
return M2M_SUCCESS;
}
* @endcode
*/
#ifndef __SPI_FLASH_H__
#define __SPI_FLASH_H__
#include "common/include/nm_common.h"
#include "bus_wrapper/include/nm_bus_wrapper.h"
#include "driver/source/nmbus.h"
#include "driver/source/nmasic.h"
#define FLASH_SECTOR_SZ (4 * 1024UL)
/*!<Sector Size in Flash Memory
*/
/**
* @fn spi_flash_enable
* @brief Enable spi flash operations
* @version 1.0
*/
sint8 spi_flash_enable(uint8 enable);
/** \defgroup SPIFLASHAPI Function
* @ingroup SPIFLASH
*/
/** @defgroup SPiFlashGetFn spi_flash_get_size
* @ingroup SPIFLASHAPI
*/
/**@{*/
/*!
* @fn uint32 spi_flash_get_size(void);
* @brief Returns with \ref uint32 value which is total flash size\n
* @note Returned value in Mb (Mega Bit).
* @return SPI flash size in case of success and a ZERO value in case of failure.
*/
uint32 spi_flash_get_size(void);
/**@}*/
/** @defgroup SPiFlashRead spi_flash_read
* @ingroup SPIFLASHAPI
*/
/**@{*/
/*!
* @fn sint8 spi_flash_read(uint8 *, uint32, uint32);
* @brief Read a specified portion of data from SPI Flash.\n
* @param [out] pu8Buf
* Pointer to data buffer which will fill in with data in case of successful operation.
* @param [in] u32Addr
* Address (Offset) to read from at the SPI flash.
* @param [in] u32Sz
* Total size of data to be read in bytes
* @warning
* - Address (offset) plus size of data must not exceed flash size.\n
* - No firmware is required for reading from SPI flash.\n
* - In case of there is a running firmware, it is required to pause your firmware first
* before any trial to access SPI flash to avoid any racing between host and running firmware on bus using
* @ref m2m_wifi_download_mode
* @note
* - It is blocking function\n
* @sa m2m_wifi_download_mode, spi_flash_get_size
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
sint8 spi_flash_read(uint8 *pu8Buf, uint32 u32Addr, uint32 u32Sz);
/**@}*/
/** @defgroup SPiFlashWrite spi_flash_write
* @ingroup SPIFLASHAPI
*/
/**@{*/
/*!
* @fn sint8 spi_flash_write(uint8 *, uint32, uint32);
* @brief Write a specified portion of data to SPI Flash.\n
* @param [in] pu8Buf
* Pointer to data buffer which contains the required to be written.
* @param [in] u32Offset
* Address (Offset) to write at the SPI flash.
* @param [in] u32Sz
* Total number of size of data bytes
* @note
* - It is blocking function\n
* - It is user's responsibility to verify that data has been written successfully
* by reading data again and compare it with the original.
* @warning
* - Address (offset) plus size of data must not exceed flash size.\n
* - No firmware is required for writing to SPI flash.\n
* - In case of there is a running firmware, it is required to pause your firmware first
* before any trial to access SPI flash to avoid any racing between host and running firmware on bus using
* @ref m2m_wifi_download_mode.
* - Before writing to any section, it is required to erase it first.
* @sa m2m_wifi_download_mode, spi_flash_get_size, spi_flash_erase
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
sint8 spi_flash_write(uint8* pu8Buf, uint32 u32Offset, uint32 u32Sz);
/**@}*/
/** @defgroup SPiFlashErase spi_flash_erase
* @ingroup SPIFLASHAPI
*/
/**@{*/
/*!
* @fn sint8 spi_flash_erase(uint32, uint32);
* @brief Erase a specified portion of SPI Flash.\n
* @param [in] u32Offset
* Address (Offset) to erase from the SPI flash.
* @param [in] u32Sz
* Size of SPI flash required to be erased.
* @note It is blocking function \n
* @warning
* - Address (offset) plus size of data must not exceed flash size.\n
* - No firmware is required for writing to SPI flash.\n
* - In case of there is a running firmware, it is required to pause your firmware first
* before any trial to access SPI flash to avoid any racing between host and running firmware on bus using
* @ref m2m_wifi_download_mode
* - It is blocking function\n
* @sa m2m_wifi_download_mode, spi_flash_get_size
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
sint8 spi_flash_erase(uint32 u32Offset, uint32 u32Sz);
/**@}*/
#endif //__SPI_FLASH_H__

View File

@ -0,0 +1,253 @@
/**
*
* \file
*
* \brief WINC1500 SPI Flash.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
/**
* @file spi_flash_map.h
* @brief This module contains spi flash CONTENT
* @author M.S.M
* @date 17 SEPT 2013
* @version 1.0
*/
#ifndef __SPI_FLASH_MAP_H__
#define __SPI_FLASH_MAP_H__
#define FLASH_MAP_VER_0 (0)
#define FLASH_MAP_VER_1 (1)
#define FLASH_MAP_VER_2 (2)
#define FLASH_MAP_VER_3 (3)
#define FLASH_MAP_VER_4 (4)
#define FLASH_MAP_VERSION FLASH_MAP_VER_4
//#define DOWNLOAD_ROLLBACK
//#define OTA_GEN
#define _PROGRAM_POWER_SAVE_
/* =======*=======*=======*=======*=======
* General Sizes for Flash Memory
* =======*=======*=======*=======*=======
*/
#define FLASH_START_ADDR (0UL)
/*!<Starting Address of Flash Memory
*
*/
#define FLASH_BLOCK_SIZE (32 * 1024UL)
/*!<Block Size in Flash Memory
*/
#define FLASH_SECTOR_SZ (4 * 1024UL)
/*!<Sector Size in Flash Memory
*/
#define FLASH_PAGE_SZ (256)
/*!<Page Size in Flash Memory
*/
#define FLASH_2M_TOTAL_SZ (256 * 1024UL)
/*!<Total Size of 2M Flash Memory
*/
#define FLASH_4M_TOTAL_SZ (512 * 1024UL)
/*!<Total Size of 4M Flash Memory
*/
#define FLASH_8M_TOTAL_SZ (1024 * 1024UL)
/*!<Total Size of 8M Flash Memory
*/
/*
* Detailed Sizes and locations for Flash Memory:
* ____________________ ___________ ____________________________________________________________________________
* | Starting Address | Size | Location's Name | Description |
* |____________________|___________|___________________________|_______________________________________________|
* | 0 K | 4 K | Boot Firmware | Firmware to select which version to run |
* | 4 K | 8 K | Control Section | Structured data used by Boot firmware |
* | 12 K | 4 K | PLL+GAIN : | LookUp Table for PLL and Gain calculations |
* | | | PLL Size = 1K | PLL |
* | | | GAIN Size = 3K | Gain configuration |
* | 16 K | 4 K | CERTIFICATE | X.509 Certificate storage |
* | 20 K | 8 K | TLS Server | TLS Server Private Key and certificates |
* | 28 K | 8 K | HTTP Files | Files used with Provisioning Mode |
* | 36 K | 4 K | Connection Parameters | Parameters for success connection to AP |
* | 40 K | 236 K | Main Firmware/program | Main Firmware to run WiFi Chip |
* | 276 K | 236 K | OTA Firmware | OTA firmware |
* | 512 K | 512 K | Host File Storage | WINC1510 (8Mb of Flash) only |
* |------------------------------------------------------------------------------------------------------------|
* | Total flash size is 512 K for WINC1500 and 1024 K for WINC1510 |
* |____________________________________________________________________________________________________________|
*
*
* *Keys for Comments with each MACRO:
* "L:xxxK" -means-> location :xxxK
* "S:xxxK" -means-> Size is :xxxK
*/
/*
* Boot Firmware: which used to select which firmware to run
*
*/
#define M2M_BOOT_FIRMWARE_STARTING_ADDR (FLASH_START_ADDR)
#define M2M_BOOT_FIRMWARE_FLASH_SZ (FLASH_SECTOR_SZ)
/*
* Control Section: which used by Boot firmware
*
*/
#define M2M_CONTROL_FLASH_OFFSET (M2M_BOOT_FIRMWARE_STARTING_ADDR + M2M_BOOT_FIRMWARE_FLASH_SZ)
#define M2M_CONTROL_FLASH_BKP_OFFSET (M2M_CONTROL_FLASH_OFFSET + FLASH_SECTOR_SZ)
#define M2M_CONTROL_FLASH_SEC_SZ (FLASH_SECTOR_SZ)
#define M2M_CONTROL_FLASH_TOTAL_SZ (FLASH_SECTOR_SZ * 2)
/*
* LUT for PLL and TX Gain settings:
*
*/
#define M2M_PLL_FLASH_OFFSET (M2M_CONTROL_FLASH_OFFSET + M2M_CONTROL_FLASH_TOTAL_SZ)
#define M2M_PLL_FLASH_SZ (1024 * 1)
#define M2M_GAIN_FLASH_OFFSET (M2M_PLL_FLASH_OFFSET + M2M_PLL_FLASH_SZ)
#define M2M_GAIN_FLASH_SZ (M2M_CONFIG_SECT_TOTAL_SZ - M2M_PLL_FLASH_SZ)
#define M2M_CONFIG_SECT_TOTAL_SZ (FLASH_SECTOR_SZ)
/*
* Certificate:
*
*/
#define M2M_TLS_ROOTCER_FLASH_OFFSET (M2M_PLL_FLASH_OFFSET + M2M_CONFIG_SECT_TOTAL_SZ)
#define M2M_TLS_ROOTCER_FLASH_SIZE (FLASH_SECTOR_SZ * 1)
/*
* TLS Server Key Files
*
*/
#define M2M_TLS_SERVER_FLASH_OFFSET (M2M_TLS_ROOTCER_FLASH_OFFSET + M2M_TLS_ROOTCER_FLASH_SIZE)
#define M2M_TLS_SERVER_FLASH_SIZE (FLASH_SECTOR_SZ * 2)
/*
* HTTP Files
*
*/
#define M2M_HTTP_MEM_FLASH_OFFSET (M2M_TLS_SERVER_FLASH_OFFSET + M2M_TLS_SERVER_FLASH_SIZE)
#define M2M_HTTP_MEM_FLASH_SZ (FLASH_SECTOR_SZ * 2)
/*
* Saved Connection Parameters:
*
*/
#define M2M_CACHED_CONNS_FLASH_OFFSET (M2M_HTTP_MEM_FLASH_OFFSET + M2M_HTTP_MEM_FLASH_SZ)
#define M2M_CACHED_CONNS_FLASH_SZ (FLASH_SECTOR_SZ * 1)
/*
*
* Common section size
*/
#define M2M_COMMON_DATA_SEC \
(\
M2M_BOOT_FIRMWARE_FLASH_SZ + \
M2M_CONTROL_FLASH_TOTAL_SZ + \
M2M_CONFIG_SECT_TOTAL_SZ + \
M2M_TLS_ROOTCER_FLASH_SIZE + \
M2M_TLS_SERVER_FLASH_SIZE + \
M2M_HTTP_MEM_FLASH_SZ + \
M2M_CACHED_CONNS_FLASH_SZ \
)
/*
*
* OTA image1 Offset
*/
#define M2M_OTA_IMAGE1_OFFSET (M2M_CACHED_CONNS_FLASH_OFFSET + M2M_CACHED_CONNS_FLASH_SZ)
/*
* Firmware Offset
*
*/
#if (defined _FIRMWARE_)||(defined OTA_GEN)
#define M2M_FIRMWARE_FLASH_OFFSET (0UL)
#else
#if (defined DOWNLOAD_ROLLBACK)
#define M2M_FIRMWARE_FLASH_OFFSET (M2M_OTA_IMAGE2_OFFSET)
#else
#define M2M_FIRMWARE_FLASH_OFFSET (M2M_OTA_IMAGE1_OFFSET)
#endif
#endif
/*
*
* Firmware
*/
#define M2M_FIRMWARE_FLASH_SZ (236 * 1024UL)
/**
*
* OTA image Size
*/
#define OTA_IMAGE_SIZE (M2M_FIRMWARE_FLASH_SZ)
/**
*
* Flash Total size
*/
#define FLASH_IMAGE1_CONTENT_SZ (M2M_COMMON_DATA_SEC + OTA_IMAGE_SIZE)
/**
*
* OTA image 2 offset
*/
#define M2M_OTA_IMAGE2_OFFSET (FLASH_IMAGE1_CONTENT_SZ)
/*
* App(Cortus App 4M): App. which runs over firmware
*
*/
#ifdef CORTUS_APP
#define M2M_APP_4M_MEM_FLASH_SZ (FLASH_SECTOR_SZ * 16)
#define M2M_APP_4M_MEM_FLASH_OFFSET (FLASH_4M_TOTAL_SZ - M2M_APP_4M_MEM_FLASH_SZ)
#define M2M_APP_8M_MEM_FLASH_OFFSET (M2M_OTA_IMAGE2_OFFSET + OTA_IMAGE_SIZE)
#define M2M_APP_8M_MEM_FLASH_SZ (FLASH_SECTOR_SZ * 32)
#define M2M_APP_OTA_MEM_FLASH_OFFSET (M2M_APP_8M_MEM_FLASH_OFFSET + M2M_APP_8M_MEM_FLASH_SZ)
#define M2M_HFD_8M_MEM_FLASH_OFFSET (M2M_APP_8M_MEM_FLASH_OFFSET + M2M_APP_8M_MEM_FLASH_SZ)
#else
#define M2M_HFD_8M_MEM_FLASH_OFFSET (M2M_OTA_IMAGE2_OFFSET + OTA_IMAGE_SIZE)
#endif
/* Check if total size of content
* don't exceed total size of memory allowed
**/
#if (M2M_COMMON_DATA_SEC + (OTA_IMAGE_SIZE *2)> FLASH_4M_TOTAL_SZ)
#error "Exceeds 4M Flash Size"
#endif /* (FLASH_CONTENT_SZ > FLASH_TOTAL_SZ) */
/**
* Magic value to differentiate between old HTTP flash section format and newer formats.
* The lowest byte is ignored when checking the value as it contains the
* version number (it should always be 00 here, image_builder will set this value in flash).
**/
#define HTTP_FLASH_SECTION_MAGIC 0xB00B1500
#define HTTP_FLASH_SECTION_VERSION 2
#endif /* __SPI_FLASH_MAP_H__ */

View File

@ -0,0 +1,72 @@
/**
*
* \file
*
* \brief WINC1500 SPI Flash.
*
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#include "driver/include/m2m_types.h"
#include "spi_flash/include/spi_flash.h"
#include "spi_flash/include/flexible_flash.h"
#define FLASH_MAP_TABLE_ADDR (FLASH_SECTOR_SZ+sizeof(tstrOtaControlSec)+8)
#define N_ENTRIES_MAX 32
sint8 spi_flexible_flash_find_section(uint16 u16EntryIDToLookFor, uint32 *pu32StartOffset, uint32 *pu32Size)
{
sint8 s8Ret = M2M_ERR_INVALID_ARG;
if((NULL == pu32StartOffset) || (NULL == pu32Size)) goto EXIT;
uint8 au8buff[8];
uint8 u8CurrEntry = 0;
s8Ret = spi_flash_read(&au8buff[0], FLASH_MAP_TABLE_ADDR, 4);
if(M2M_SUCCESS != s8Ret) goto EXIT;
uint8 u8nEntries = au8buff[0]; // Max number is 32, reading one byte will suffice
if(u8nEntries > N_ENTRIES_MAX)
{
s8Ret = M2M_ERR_FAIL;
goto EXIT;
}
while(u8nEntries > u8CurrEntry)
{
s8Ret = spi_flash_read(&au8buff[0], FLASH_MAP_TABLE_ADDR + 4 + (u8CurrEntry*8), 8);
u8CurrEntry++;
if(M2M_SUCCESS != s8Ret) break;
uint16 u16EntryID = (au8buff[1] << 8) | au8buff[0];
if(u16EntryID != u16EntryIDToLookFor) continue;
*pu32StartOffset = au8buff[2] * FLASH_SECTOR_SZ;
*pu32Size = au8buff[3] * FLASH_SECTOR_SZ;
break;
}
EXIT:
return s8Ret;
}

View File

@ -0,0 +1,742 @@
/**
*
* \file
*
* \brief WINC1500 SPI Flash.
*
* Copyright (c) 2016-2021 Microchip Technology Inc. and its subsidiaries.
*
* \asf_license_start
*
* \page License
*
* Subject to your compliance with these terms, you may use Microchip
* software and any derivatives exclusively with Microchip products.
* It is your responsibility to comply with third party license terms applicable
* to your use of third party software (including open source software) that
* may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*
* \asf_license_stop
*
*/
#ifdef PROFILING
#include "windows.h"
#endif
#include "spi_flash/include/spi_flash.h"
#define DUMMY_REGISTER (0x1084)
#define TIMEOUT (-1) /*MS*/
//#define DISABLE_UNSED_FLASH_FUNCTIONS
#define FLASH_BLOCK_SIZE (32UL * 1024)
/*!<Block Size in Flash Memory
*/
#define FLASH_PAGE_SZ (256)
/*!<Page Size in Flash Memory */
#define HOST_SHARE_MEM_BASE (0xd0000UL)
#define CORTUS_SHARE_MEM_BASE (0x60000000UL)
#define NMI_SPI_FLASH_ADDR (0x111c)
/***********************************************************
SPI Flash DMA
***********************************************************/
#define GET_UINT32(X,Y) (X[0+Y] + ((uint32)X[1+Y]<<8) + ((uint32)X[2+Y]<<16) +((uint32)X[3+Y]<<24))
#define SPI_FLASH_BASE (0x10200)
#define SPI_FLASH_MODE (SPI_FLASH_BASE + 0x00)
#define SPI_FLASH_CMD_CNT (SPI_FLASH_BASE + 0x04)
#define SPI_FLASH_DATA_CNT (SPI_FLASH_BASE + 0x08)
#define SPI_FLASH_BUF1 (SPI_FLASH_BASE + 0x0c)
#define SPI_FLASH_BUF2 (SPI_FLASH_BASE + 0x10)
#define SPI_FLASH_BUF_DIR (SPI_FLASH_BASE + 0x14)
#define SPI_FLASH_TR_DONE (SPI_FLASH_BASE + 0x18)
#define SPI_FLASH_DMA_ADDR (SPI_FLASH_BASE + 0x1c)
#define SPI_FLASH_MSB_CTL (SPI_FLASH_BASE + 0x20)
#define SPI_FLASH_TX_CTL (SPI_FLASH_BASE + 0x24)
/*********************************************/
/* STATIC FUNCTIONS */
/*********************************************/
/**
* @fn spi_flash_read_status_reg
* @brief Read status register
* @param[OUT] val
value of status reg
* @return Status of execution
* @note Compatible with MX25L6465E
* @author M. Abdelmawla
* @version 1.0
*/
static sint8 spi_flash_read_status_reg(uint8 * val)
{
sint8 ret = M2M_SUCCESS;
uint8 cmd[1];
uint32 reg;
cmd[0] = 0x05;
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 4);
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER);
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
do
{
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&reg);
if(M2M_SUCCESS != ret) break;
}
while(reg != 1);
reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0);
*val = (uint8)(reg & 0xff);
return ret;
}
#ifdef DISABLE_UNSED_FLASH_FUNCTIONS
/**
* @fn spi_flash_read_security_reg
* @brief Read security register
* @return Security register value
* @note Compatible with MX25L6465E
* @author M. Abdelmawla
* @version 1.0
*/
static uint8 spi_flash_read_security_reg(void)
{
uint8 cmd[1];
uint32 reg;
sint8 ret = M2M_SUCCESS;
cmd[0] = 0x2b;
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 1);
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER);
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
do
{
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&reg);
if(M2M_SUCCESS != ret) break;
}
while(reg != 1);
reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0);
return (sint8)reg & 0xff;
}
/**
* @fn spi_flash_gang_unblock
* @brief Unblock all flash area
* @note Compatible with MX25L6465E
* @author M. Abdelmawla
* @version 1.0
*/
static sint8 spi_flash_gang_unblock(void)
{
uint8 cmd[1];
uint32 val = 0;
sint8 ret = M2M_SUCCESS;
cmd[0] = 0x98;
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
do
{
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val);
if(M2M_SUCCESS != ret) break;
}
while(val != 1);
return ret;
}
/**
* @fn spi_flash_clear_security_flags
* @brief Clear all security flags
* @note Compatible with MX25L6465E
* @author M. Abdelmawla
* @version 1.0
*/
static sint8 spi_flash_clear_security_flags(void)
{
uint8 cmd[1];
uint32 val = 0;
sint8 ret = M2M_SUCCESS;
cmd[0] = 0x30;
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
do
{
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val);
if(M2M_SUCCESS != ret) break;
}
while(val != 1);
return ret;
}
#endif
/**
* @fn spi_flash_load_to_cortus_mem
* @brief Load data from SPI flash into cortus memory
* @param[IN] u32MemAdr
* Cortus load address. It must be set to its AHB access address
* @param[IN] u32FlashAdr
* Address to read from at the SPI flash
* @param[IN] u32Sz
* Data size
* @return Status of execution
* @note Compatible with MX25L6465E and should be working with other types
* @author M. Abdelmawla
* @version 1.0
*/
static sint8 spi_flash_load_to_cortus_mem(uint32 u32MemAdr, uint32 u32FlashAdr, uint32 u32Sz)
{
uint8 cmd[5];
uint32 val = 0;
sint8 ret = M2M_SUCCESS;
cmd[0] = 0x0b;
cmd[1] = (uint8)(u32FlashAdr >> 16);
cmd[2] = (uint8)(u32FlashAdr >> 8);
cmd[3] = (uint8)(u32FlashAdr);
cmd[4] = 0xA5;
ret += nm_write_reg(SPI_FLASH_DATA_CNT, u32Sz);
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]|(((uint32)cmd[1])<<8)|(((uint32)cmd[2])<<16)|(((uint32)cmd[3])<<24));
ret += nm_write_reg(SPI_FLASH_BUF2, cmd[4]);
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x1f);
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, u32MemAdr);
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 5 | (1<<7));
do
{
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val);
if(M2M_SUCCESS != ret) break;
}
while(val != 1);
return ret;
}
/**
* @fn spi_flash_sector_erase
* @brief Erase sector (4KB)
* @param[IN] u32FlashAdr
* Any memory address within the sector
* @return Status of execution
* @note Compatible with MX25L6465E and should be working with other types
* @author M. Abdelmawla
* @version 1.0
*/
static sint8 spi_flash_sector_erase(uint32 u32FlashAdr)
{
uint8 cmd[4];
uint32 val = 0;
sint8 ret = M2M_SUCCESS;
cmd[0] = 0x20;
cmd[1] = (uint8)(u32FlashAdr >> 16);
cmd[2] = (uint8)(u32FlashAdr >> 8);
cmd[3] = (uint8)(u32FlashAdr);
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]|(((uint32)cmd[1])<<8)|(((uint32)cmd[2])<<16)|(((uint32)cmd[3])<<24));
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x0f);
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 4 | (1<<7));
do
{
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val);
if(M2M_SUCCESS != ret) break;
}
while(val != 1);
return ret;
}
/**
* @fn spi_flash_write_enable
* @brief Send write enable command to SPI flash
* @return Status of execution
* @note Compatible with MX25L6465E and should be working with other types
* @author M. Abdelmawla
* @version 1.0
*/
static sint8 spi_flash_write_enable(void)
{
uint8 cmd[1];
uint32 val = 0;
sint8 ret = M2M_SUCCESS;
cmd[0] = 0x06;
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
do
{
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val);
if(M2M_SUCCESS != ret) break;
}
while(val != 1);
return ret;
}
/**
* @fn spi_flash_write_disable
* @brief Send write disable command to SPI flash
* @note Compatible with MX25L6465E and should be working with other types
* @author M. Abdelmawla
* @version 1.0
*/
static sint8 spi_flash_write_disable(void)
{
uint8 cmd[1];
uint32 val = 0;
sint8 ret = M2M_SUCCESS;
cmd[0] = 0x04;
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
do
{
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val);
if(M2M_SUCCESS != ret) break;
}
while(val != 1);
return ret;
}
/**
* @fn spi_flash_page_program
* @brief Write data (less than page size) from cortus memory to SPI flash
* @param[IN] u32MemAdr
* Cortus data address. It must be set to its AHB access address
* @param[IN] u32FlashAdr
* Address to write to at the SPI flash
* @param[IN] u32Sz
* Data size
* @note Compatible with MX25L6465E and should be working with other types
* @author M. Abdelmawla
* @version 1.0
*/
static sint8 spi_flash_page_program(uint32 u32MemAdr, uint32 u32FlashAdr, uint32 u32Sz)
{
uint8 cmd[4];
uint32 val = 0;
sint8 ret = M2M_SUCCESS;
cmd[0] = 0x02;
cmd[1] = (uint8)(u32FlashAdr >> 16);
cmd[2] = (uint8)(u32FlashAdr >> 8);
cmd[3] = (uint8)(u32FlashAdr);
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]|(((uint32)cmd[1])<<8)|(((uint32)cmd[2])<<16)|(((uint32)cmd[3])<<24));
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x0f);
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, u32MemAdr);
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 4 | (1<<7) | ((u32Sz & 0xfffff) << 8));
do
{
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val);
if(M2M_SUCCESS != ret) break;
}
while(val != 1);
return ret;
}
/**
* @fn spi_flash_read_internal
* @brief Read from data from SPI flash
* @param[OUT] pu8Buf
* Pointer to data buffer
* @param[IN] u32Addr
* Address to read from at the SPI flash
* @param[IN] u32Sz
* Data size
* @note Data size must be < 64KB (limitation imposed by the bus wrapper)
* @author M. Abdelmawla
* @version 1.0
*/
static sint8 spi_flash_read_internal(uint8 *pu8Buf, uint32 u32Addr, uint32 u32Sz)
{
sint8 ret = M2M_SUCCESS;
/* read size must be < 64KB */
ret = spi_flash_load_to_cortus_mem(HOST_SHARE_MEM_BASE, u32Addr, u32Sz);
if(M2M_SUCCESS != ret) goto ERR;
ret = nm_read_block(HOST_SHARE_MEM_BASE, pu8Buf, u32Sz);
ERR:
return ret;
}
/**
* @fn spi_flash_pp
* @brief Program data of size less than a page (256 bytes) at the SPI flash
* @param[IN] u32Offset
* Address to write to at the SPI flash
* @param[IN] pu8Buf
* Pointer to data buffer
* @param[IN] u32Sz
* Data size
* @return Status of execution
* @author M. Abdelmawla
* @version 1.0
*/
static sint8 spi_flash_pp(uint32 u32Offset, uint8 *pu8Buf, uint16 u16Sz)
{
sint8 ret = M2M_SUCCESS;
uint8 tmp;
spi_flash_write_enable();
/* use shared packet memory as temp mem */
ret += nm_write_block(HOST_SHARE_MEM_BASE, pu8Buf, u16Sz);
ret += spi_flash_page_program(HOST_SHARE_MEM_BASE, u32Offset, u16Sz);
ret += spi_flash_read_status_reg(&tmp);
do
{
if(ret != M2M_SUCCESS) goto ERR;
ret += spi_flash_read_status_reg(&tmp);
}while(tmp & 0x01);
ret += spi_flash_write_disable();
ERR:
return ret;
}
/**
* @fn spi_flash_rdid
* @brief Read SPI Flash ID
* @return SPI FLash ID
* @author M.S.M
* @version 1.0
*/
static uint32 spi_flash_rdid(void)
{
unsigned char cmd[1];
uint32 reg = 0;
uint32 cnt = 0;
sint8 ret = M2M_SUCCESS;
cmd[0] = 0x9f;
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 4);
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x1);
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER);
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
do
{
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&reg);
if(M2M_SUCCESS != ret) break;
if(++cnt > 500)
{
ret = M2M_ERR_INIT;
break;
}
}
while(reg != 1);
reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0);
M2M_PRINT("Flash ID %x \n",(unsigned int)reg);
return reg;
}
/**
* @fn spi_flash_unlock
* @brief Unlock SPI Flash
* @author M.S.M
* @version 1.0
*/
#if 0
static void spi_flash_unlock(void)
{
uint8 tmp;
tmp = spi_flash_read_security_reg();
spi_flash_clear_security_flags();
if(tmp & 0x80)
{
spi_flash_write_enable();
spi_flash_gang_unblock();
}
}
#endif
static void spi_flash_enter_low_power_mode(void) {
volatile unsigned long tmp;
unsigned char* cmd = (unsigned char*) &tmp;
cmd[0] = 0xb9;
nm_write_reg(SPI_FLASH_DATA_CNT, 0);
nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
nm_write_reg(SPI_FLASH_BUF_DIR, 0x1);
nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1 << 7));
while(nm_read_reg(SPI_FLASH_TR_DONE) != 1);
}
static void spi_flash_leave_low_power_mode(void) {
volatile unsigned long tmp;
unsigned char* cmd = (unsigned char*) &tmp;
cmd[0] = 0xab;
nm_write_reg(SPI_FLASH_DATA_CNT, 0);
nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
nm_write_reg(SPI_FLASH_BUF_DIR, 0x1);
nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1 << 7));
while(nm_read_reg(SPI_FLASH_TR_DONE) != 1);
}
/*********************************************/
/* GLOBAL FUNCTIONS */
/*********************************************/
/**
* @fn spi_flash_enable
* @brief Enable spi flash operations
* @author M. Abdelmawla
* @version 1.0
*/
sint8 spi_flash_enable(uint8 enable)
{
sint8 s8Ret = M2M_SUCCESS;
if(REV(nmi_get_chipid()) >= REV_3A0) {
uint32 u32Val;
/* Enable pinmux to SPI flash. */
s8Ret = nm_read_reg_with_ret(0x1410, &u32Val);
if(s8Ret != M2M_SUCCESS) {
goto ERR1;
}
/* GPIO15/16/17/18 */
u32Val &= ~((0x7777ul) << 12);
if(enable) {
u32Val |= ((0x1111ul) << 12);
nm_write_reg(0x1410, u32Val);
spi_flash_leave_low_power_mode();
} else {
spi_flash_enter_low_power_mode();
/* Disable pinmux to SPI flash to minimize leakage. */
u32Val |= ((0x0010ul) << 12);
nm_write_reg(0x1410, u32Val);
}
}
ERR1:
return s8Ret;
}
/**
* @fn spi_flash_read
* @brief Read from data from SPI flash
* @param[OUT] pu8Buf
* Pointer to data buffer
* @param[IN] u32offset
* Address to read from at the SPI flash
* @param[IN] u32Sz
* Data size
* @return Status of execution
* @note Data size is limited by the SPI flash size only
* @author M. Abdelmawla
* @version 1.0
*/
sint8 spi_flash_read(uint8 *pu8Buf, uint32 u32offset, uint32 u32Sz)
{
sint8 ret = M2M_SUCCESS;
if(u32Sz > FLASH_BLOCK_SIZE)
{
do
{
ret = spi_flash_read_internal(pu8Buf, u32offset, FLASH_BLOCK_SIZE);
if(M2M_SUCCESS != ret) goto ERR;
u32Sz -= FLASH_BLOCK_SIZE;
u32offset += FLASH_BLOCK_SIZE;
pu8Buf += FLASH_BLOCK_SIZE;
} while(u32Sz > FLASH_BLOCK_SIZE);
}
ret = spi_flash_read_internal(pu8Buf, u32offset, u32Sz);
ERR:
return ret;
}
/**
* @fn spi_flash_write
* @brief Program SPI flash
* @param[IN] pu8Buf
* Pointer to data buffer
* @param[IN] u32Offset
* Address to write to at the SPI flash
* @param[IN] u32Sz
* Data size
* @return Status of execution
* @author M. Abdelmawla
* @version 1.0
*/
sint8 spi_flash_write(uint8* pu8Buf, uint32 u32Offset, uint32 u32Sz)
{
#ifdef PROFILING
uint32 t1 = 0;
uint32 percent =0;
uint32 tpercent =0;
#endif
sint8 ret = M2M_SUCCESS;
uint32 u32wsz;
uint32 u32off;
uint32 u32Blksz;
u32Blksz = FLASH_PAGE_SZ;
u32off = u32Offset % u32Blksz;
#ifdef PROFILING
tpercent = (u32Sz/u32Blksz)+((u32Sz%u32Blksz)>0);
t1 = GetTickCount();
M2M_PRINT(">Start programming...\r\n");
#endif
if(u32Sz<=0)
{
M2M_ERR("Data size = %d",(int)u32Sz);
ret = M2M_ERR_FAIL;
goto ERR;
}
if (u32off)/*first part of data in the address page*/
{
u32wsz = u32Blksz - u32off;
if(spi_flash_pp(u32Offset, pu8Buf, (uint16)BSP_MIN(u32Sz, u32wsz))!=M2M_SUCCESS)
{
ret = M2M_ERR_FAIL;
goto ERR;
}
if (u32Sz < u32wsz) goto EXIT;
pu8Buf += u32wsz;
u32Offset += u32wsz;
u32Sz -= u32wsz;
}
while (u32Sz > 0)
{
u32wsz = BSP_MIN(u32Sz, u32Blksz);
/*write complete page or the remaining data*/
if(spi_flash_pp(u32Offset, pu8Buf, (uint16)u32wsz)!=M2M_SUCCESS)
{
ret = M2M_ERR_FAIL;
goto ERR;
}
pu8Buf += u32wsz;
u32Offset += u32wsz;
u32Sz -= u32wsz;
#ifdef PROFILING
percent++;
printf("\r>Complete Percentage = %d%%.\r",((percent*100)/tpercent));
#endif
}
EXIT:
#ifdef PROFILING
M2M_PRINT("\rDone\t\t\t\t\t\t");
M2M_PRINT("\n#Programming time = %f sec\n\r",(GetTickCount() - t1)/1000.0);
#endif
ERR:
return ret;
}
/**
* @fn spi_flash_erase
* @brief Erase from data from SPI flash
* @param[IN] u32Offset
* Address to write to at the SPI flash
* @param[IN] u32Sz
* Data size
* @return Status of execution
* @note Data size is limited by the SPI flash size only
* @author M. Abdelmawla
* @version 1.0
*/
sint8 spi_flash_erase(uint32 u32Offset, uint32 u32Sz)
{
uint32 i = 0;
sint8 ret = M2M_SUCCESS;
uint8 tmp = 0;
#ifdef PROFILING
uint32 t;
t = GetTickCount();
#endif
M2M_PRINT("\r\n>Start erasing...\r\n");
for(i = u32Offset; i < (u32Sz +u32Offset); i += (16*FLASH_PAGE_SZ))
{
ret += spi_flash_write_enable();
ret += spi_flash_read_status_reg(&tmp);
ret += spi_flash_sector_erase(i + 10);
ret += spi_flash_read_status_reg(&tmp);
do
{
if(ret != M2M_SUCCESS) goto ERR;
ret += spi_flash_read_status_reg(&tmp);
}while(tmp & 0x01);
}
M2M_PRINT("Done\r\n");
#ifdef PROFILING
M2M_PRINT("#Erase time = %f sec\n", (GetTickCount()-t)/1000.0);
#endif
ERR:
return ret;
}
/**
* @fn spi_flash_get_size
* @brief Get size of SPI Flash
* @return Size of Flash
* @author M.S.M
* @version 1.0
*/
uint32 spi_flash_get_size(void)
{
uint32 u32FlashId = 0, u32FlashPwr = 0;
static uint32 gu32InternalFlashSize= 0;
if(!gu32InternalFlashSize)
{
u32FlashId = spi_flash_rdid();
if((u32FlashId != 0xffffffff) && (u32FlashId !=0))
{
/*flash size is the third byte from the FLASH RDID*/
u32FlashPwr = ((u32FlashId>>16)&0xff) - 0x11; /*2MBIT is the min*/
/*That number power 2 to get the flash size*/
gu32InternalFlashSize = 1<<u32FlashPwr;
M2M_INFO("Flash Size %lu Mb\n",gu32InternalFlashSize);
}
else
{
M2M_ERR("Can't detect Flash size\n");
}
}
return gu32InternalFlashSize;
}

Binary file not shown.