IP Configuration

This commit is contained in:
Gašper Dobrovoljc
2023-03-11 15:11:03 +01:00
commit ec125f27db
662 changed files with 103738 additions and 0 deletions

View File

@@ -0,0 +1,233 @@
/**
*
* \file
*
* \brief WINC1500 SPI Flash.
*
* Copyright (c) 2016-2017 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/** \defgroup 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"
#ifdef ARDUINO
#ifdef __cplusplus
extern "C" {
#endif
#endif
/**
* @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);
/**@}*/
#ifdef ARDUINO
#ifdef __cplusplus
}
#endif
#endif
#endif //__SPI_FLASH_H__

View File

@@ -0,0 +1,245 @@
/**
*
* \file
*
* \brief WINC1500 SPI Flash.
*
* Copyright (c) 2016-2017 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/**
* @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_VERSION FLASH_MAP_VER_3
//#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 Total flash size |
* |____________________|___________|___________________________|_______________________________________________|
*
*
* *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
*
*/
#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)
/* 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 "Excced 4M Flash Size"
#endif /* (FLASH_CONTENT_SZ > FLASH_TOTAL_SZ) */
#endif /* __SPI_FLASH_MAP_H__ */

View File

@@ -0,0 +1,770 @@
/**
*
* \file
*
* \brief WINC1500 SPI Flash.
*
* Copyright (c) 2016-2017 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifdef PROFILING
#include "windows.h"
#endif
#include "spi_flash/include/spi_flash.h"
#define DUMMY_REGISTER (0x1084)
#ifdef ARDUINO
#define u32(x) ((uint32)x)
#endif
#define TIMEOUT (-1) /*MS*/
//#define DISABLE_UNSED_FLASH_FUNCTIONS
#define FLASH_BLOCK_SIZE (32UL * 1024)
/*!<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 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);
#ifdef ARDUINO
ret += nm_write_reg(SPI_FLASH_BUF1, u32(cmd[0])|u32(cmd[1]<<8)|u32(cmd[2]<<16)|u32(cmd[3]<<24));
#else
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]|(cmd[1]<<8)|(cmd[2]<<16)|(cmd[3]<<24));
#endif
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);
#ifdef ARDUINO
ret += nm_write_reg(SPI_FLASH_BUF1, u32(cmd[0])|u32(cmd[1]<<8)|u32(cmd[2]<<16)|u32(cmd[3]<<24));
#else
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]|(cmd[1]<<8)|(cmd[2]<<16)|(cmd[3]<<24));
#endif
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);
#ifdef ARDUINO
ret += nm_write_reg(SPI_FLASH_BUF1, u32(cmd[0])|u32(cmd[1]<<8)|u32(cmd[2]<<16)|u32(cmd[3]<<24));
#else
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]|(cmd[1]<<8)|(cmd[2]<<16)|(cmd[3]<<24));
#endif
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);
u32Val |= ((0x1111ul) << 12);
nm_write_reg(0x1410, u32Val);
if(enable) {
spi_flash_leave_low_power_mode();
} else {
spi_flash_enter_low_power_mode();
}
/* Disable pinmux to SPI flash to minimize leakage. */
u32Val &= ~((0x7777ul) << 12);
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 Proram 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 gu32InernalFlashSize= 0;
if(!gu32InernalFlashSize)
{
u32FlashId = spi_flash_rdid();//spi_flash_probe();
if(u32FlashId != 0xffffffff)
{
/*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*/
gu32InernalFlashSize = 1<<u32FlashPwr;
M2M_INFO("Flash Size %lu Mb\n",gu32InernalFlashSize);
}
else
{
M2M_ERR("Cann't Detect Flash size\n");
}
}
return gu32InernalFlashSize;
}