add more atmel studio framework code

This commit is contained in:
Joey Castillo 2021-09-20 17:37:55 -04:00
parent 63322a3b7f
commit 24e160611e
23 changed files with 3722 additions and 0 deletions

View file

@ -0,0 +1,38 @@
/* Auto-generated config file hpl_nvmctrl_config.h */
#ifndef HPL_NVMCTRL_CONFIG_H
#define HPL_NVMCTRL_CONFIG_H
// <<< Use Configuration Wizard in Context Menu >>>
// <h> Basic Settings
// <o> Read Mode Selection
// <0x00=> No Miss Penalty
// <0x01=> Low Power
// <0x02=> Deterministic
// <id> nvm_arch_read_mode
#ifndef CONF_NVM_READ_MODE
#define CONF_NVM_READ_MODE 1
#endif
// <o> Power Reduction Mode During Sleep
// <0x00=> Wake On Access
// <0x01=> Wake Up Instant
// <0x03=> Disabled
// <id> nvm_arch_sleepprm
#ifndef CONF_NVM_SLEEPPRM
#define CONF_NVM_SLEEPPRM 0
#endif
// <q> Cache Disable
// <i> Indicate whether cache is disable or not
// <id> nvm_arch_cache
#ifndef CONF_NVM_CACHE
#define CONF_NVM_CACHE 0
#endif
// </h>
// <<< end of configuration section >>>
#endif // HPL_NVMCTRL_CONFIG_H

View file

@ -139,6 +139,165 @@
#endif
#endif
#include <peripheral_clk_config.h>
// Enable configuration of module
#ifndef CONF_SERCOM_3_SPI_ENABLE
#define CONF_SERCOM_3_SPI_ENABLE 0
#endif
// Set module in SPI Master mode
#ifndef CONF_SERCOM_3_SPI_MODE
#define CONF_SERCOM_3_SPI_MODE 0x03
#endif
// <h> Basic Configuration
// <q> Receive buffer enable
// <i> Enable receive buffer to receive data from slave (RXEN)
// <id> spi_master_rx_enable
#ifndef CONF_SERCOM_3_SPI_RXEN
#define CONF_SERCOM_3_SPI_RXEN 0x1
#endif
// <o> Character Size
// <i> Bit size for all characters sent over the SPI bus (CHSIZE)
// <0x0=>8 bits
// <0x1=>9 bits
// <id> spi_master_character_size
#ifndef CONF_SERCOM_3_SPI_CHSIZE
#define CONF_SERCOM_3_SPI_CHSIZE 0x0
#endif
// <o> Baud rate <1-12000000>
// <i> The SPI data transfer rate
// <id> spi_master_baud_rate
#ifndef CONF_SERCOM_3_SPI_BAUD
#define CONF_SERCOM_3_SPI_BAUD 50000
#endif
// </h>
// <e> Advanced Configuration
// <id> spi_master_advanced
#ifndef CONF_SERCOM_3_SPI_ADVANCED
#define CONF_SERCOM_3_SPI_ADVANCED 0
#endif
// <o> Dummy byte <0x00-0x1ff>
// <id> spi_master_dummybyte
// <i> Dummy byte used when reading data from the slave without sending any data
#ifndef CONF_SERCOM_3_SPI_DUMMYBYTE
#define CONF_SERCOM_3_SPI_DUMMYBYTE 0x1ff
#endif
// <o> Data Order
// <0=>MSB first
// <1=>LSB first
// <i> I least significant or most significant bit is shifted out first (DORD)
// <id> spi_master_arch_dord
#ifndef CONF_SERCOM_3_SPI_DORD
#define CONF_SERCOM_3_SPI_DORD 0x0
#endif
// <o> Clock Polarity
// <0=>SCK is low when idle
// <1=>SCK is high when idle
// <i> Determines if the leading edge is rising or falling with a corresponding opposite edge at the trailing edge. (CPOL)
// <id> spi_master_arch_cpol
#ifndef CONF_SERCOM_3_SPI_CPOL
#define CONF_SERCOM_3_SPI_CPOL 0x0
#endif
// <o> Clock Phase
// <0x0=>Sample input on leading edge
// <0x1=>Sample input on trailing edge
// <i> Determines if input data is sampled on leading or trailing SCK edge. (CPHA)
// <id> spi_master_arch_cpha
#ifndef CONF_SERCOM_3_SPI_CPHA
#define CONF_SERCOM_3_SPI_CPHA 0x0
#endif
// <o> Immediate Buffer Overflow Notification
// <i> Controls when OVF is asserted (IBON)
// <0x0=>In data stream
// <0x1=>On buffer overflow
// <id> spi_master_arch_ibon
#ifndef CONF_SERCOM_3_SPI_IBON
#define CONF_SERCOM_3_SPI_IBON 0x0
#endif
// <q> Run in stand-by
// <i> Module stays active in stand-by sleep mode. (RUNSTDBY)
// <id> spi_master_arch_runstdby
#ifndef CONF_SERCOM_3_SPI_RUNSTDBY
#define CONF_SERCOM_3_SPI_RUNSTDBY 0x0
#endif
// <o> Debug Stop Mode
// <i> Behavior of the baud-rate generator when CPU is halted by external debugger. (DBGSTOP)
// <0=>Keep running
// <1=>Halt
// <id> spi_master_arch_dbgstop
#ifndef CONF_SERCOM_3_SPI_DBGSTOP
#define CONF_SERCOM_3_SPI_DBGSTOP 0
#endif
// </e>
// Address mode disabled in master mode
#ifndef CONF_SERCOM_3_SPI_AMODE_EN
#define CONF_SERCOM_3_SPI_AMODE_EN 0
#endif
#ifndef CONF_SERCOM_3_SPI_AMODE
#define CONF_SERCOM_3_SPI_AMODE 0
#endif
#ifndef CONF_SERCOM_3_SPI_ADDR
#define CONF_SERCOM_3_SPI_ADDR 0
#endif
#ifndef CONF_SERCOM_3_SPI_ADDRMASK
#define CONF_SERCOM_3_SPI_ADDRMASK 0
#endif
#ifndef CONF_SERCOM_3_SPI_SSDE
#define CONF_SERCOM_3_SPI_SSDE 0
#endif
#ifndef CONF_SERCOM_3_SPI_MSSEN
#define CONF_SERCOM_3_SPI_MSSEN 0x0
#endif
#ifndef CONF_SERCOM_3_SPI_PLOADEN
#define CONF_SERCOM_3_SPI_PLOADEN 0
#endif
// <o> Receive Data Pinout
// <0x0=>PAD[0]
// <0x1=>PAD[1]
// <0x2=>PAD[2]
// <0x3=>PAD[3]
// <id> spi_master_rxpo
#ifndef CONF_SERCOM_3_SPI_RXPO
#define CONF_SERCOM_3_SPI_RXPO 2
#endif
// <o> Transmit Data Pinout
// <0x0=>PAD[0,1]_DO_SCK
// <0x1=>PAD[2,3]_DO_SCK
// <0x2=>PAD[3,1]_DO_SCK
// <0x3=>PAD[0,3]_DO_SCK
// <id> spi_master_txpo
#ifndef CONF_SERCOM_3_SPI_TXPO
#define CONF_SERCOM_3_SPI_TXPO 3
#endif
// Calculate baud register value from requested baudrate value
#ifndef CONF_SERCOM_3_SPI_BAUD_RATE
#define CONF_SERCOM_3_SPI_BAUD_RATE ((float)CONF_GCLK_SERCOM3_CORE_FREQUENCY / (float)(2 * CONF_SERCOM_3_SPI_BAUD)) - 1
#endif
// <<< end of configuration section >>>
#endif // HPL_SERCOM_CONFIG_H

View file

@ -0,0 +1,27 @@
/* Auto-generated config file hpl_trng_config.h */
#ifndef HPL_TRNG_CONFIG_H
#define HPL_TRNG_CONFIG_H
// <<< Use Configuration Wizard in Context Menu >>>
// <h> Advanced configurations
// <q> Run In Standby
// <i> Indicates whether the TRNG works in standby mode
// <id> trng_runstdby
#ifndef CONF_TRNG_RUNSTDBY
#define CONF_TRNG_RUNSTDBY 0
#endif
// <q> Data Ready Event Output Enable
// <i> Indicates whether the TRNG generates event on Data Ready
// <id> trng_datardyeo
#ifndef CONF_TRNG_DATARDYEO
#define CONF_TRNG_DATARDYEO 0
#endif
// </h>
// <<< end of configuration section >>>
#endif // HPL_TRNG_CONFIG_H

View file

@ -0,0 +1,51 @@
/* Auto-generated config file nv_storage_config.h */
#ifndef NV_STORAGE_CONFIG_H
#define NV_STORAGE_CONFIG_H
// <<< Use Configuration Wizard in Context Menu >>>
//<o> Storage start address <0x00000000-0xFFFFFFFF>
//<i> This defines the start address of device flash for storage.
//<i> The start address should be in device flash area.
//<i> The start address and (start address + Item Number * Sector size) cannot beyond device flash area.
//<id> conf_storage_memory_start
#ifndef CONF_STORAGE_MEMORY_START
#define CONF_STORAGE_MEMORY_START 0x10000
#endif
//<o> Item number <0-65535>
//<i> This defines the maximum number of elements stored in persistent storage
//<id> conf_max_item_number
#ifndef CONF_MAX_ITEM_NUMBER
#define CONF_MAX_ITEM_NUMBER 10
#endif
//<o> Sector size <0-65535>
//<i> This defines the size of one storage sector in bytes
//<id> conf_sector_size
#ifndef CONF_SECTOR_SIZE
#define CONF_SECTOR_SIZE 4096
#endif
/**
* Check If the Storage configuration out of the flash area.
*/
#ifdef FLASH_SIZE
#if (CONF_STORAGE_MEMORY_START + (SECTOR_AMOUNT * CONF_SECTOR_SIZE)) > FLASH_SIZE
#error Invalidate storage configuration, make sure the configuration with \
the sector start address (CONF_STORAGE_MEMORY_START) and sector size (CONF_SECTOR_SIZE) \
are located within the device flash size.
#endif
#endif
#ifdef IFLASH_SIZE
#if (CONF_STORAGE_MEMORY_START + (SECTOR_AMOUNT * CONF_SECTOR_SIZE)) > IFLASH_SIZE
#error Invalidate storage configuration, make sure the configuration with \
the sector start address (CONF_STORAGE_MEMORY_START) and sector size (CONF_SECTOR_SIZE) \
are located within the device flash size.
#endif
#endif
// <<< end of configuration section >>>
#endif // NV_STORAGE_CONFIG_H

View file

@ -132,6 +132,58 @@
#define CONF_GCLK_SERCOM1_SLOW_FREQUENCY 32768
#endif
// <y> Core Clock Source
// <id> core_gclk_selection
// <GCLK_PCHCTRL_GEN_GCLK0_Val"> Generic clock generator 0
// <GCLK_PCHCTRL_GEN_GCLK1_Val"> Generic clock generator 1
// <GCLK_PCHCTRL_GEN_GCLK2_Val"> Generic clock generator 2
// <GCLK_PCHCTRL_GEN_GCLK3_Val"> Generic clock generator 3
// <GCLK_PCHCTRL_GEN_GCLK4_Val"> Generic clock generator 4
// <i> Select the clock source for CORE.
#ifndef CONF_GCLK_SERCOM3_CORE_SRC
#define CONF_GCLK_SERCOM3_CORE_SRC GCLK_PCHCTRL_GEN_GCLK0_Val
#endif
// <y> Slow Clock Source
// <id> slow_gclk_selection
// <GCLK_PCHCTRL_GEN_GCLK0_Val"> Generic clock generator 0
// <GCLK_PCHCTRL_GEN_GCLK1_Val"> Generic clock generator 1
// <GCLK_PCHCTRL_GEN_GCLK2_Val"> Generic clock generator 2
// <GCLK_PCHCTRL_GEN_GCLK3_Val"> Generic clock generator 3
// <GCLK_PCHCTRL_GEN_GCLK4_Val"> Generic clock generator 4
// <i> Select the slow clock source.
#ifndef CONF_GCLK_SERCOM3_SLOW_SRC
#define CONF_GCLK_SERCOM3_SLOW_SRC GCLK_PCHCTRL_GEN_GCLK3_Val
#endif
/**
* \def CONF_GCLK_SERCOM3_CORE_FREQUENCY
* \brief SERCOM3's Core Clock frequency
*/
#ifndef CONF_GCLK_SERCOM3_CORE_FREQUENCY
#define CONF_GCLK_SERCOM3_CORE_FREQUENCY 4000000
#endif
/**
* \def CONF_GCLK_SERCOM3_SLOW_FREQUENCY
* \brief SERCOM3's Slow Clock frequency
*/
#ifndef CONF_GCLK_SERCOM3_SLOW_FREQUENCY
#define CONF_GCLK_SERCOM3_SLOW_FREQUENCY 32768
#endif
// <y> TC Clock Source
// <id> tc_gclk_selection

View file

@ -0,0 +1,52 @@
The Flash Driver
================
Flash is a re-programmable memory that retains program and data
storage even with power off.
User can write or read several bytes from any valid address in a flash.
As to the erase/lock/unlock command, the input parameter of address should
be a bytes address aligned with the page start, otherwise, the command will fail
to be executed. At the meantime, the number of pages that can be locked or unlocked
at once depends on region size of the flash. User can get the real number
from the function return value which could be different for the different devices.
Features
--------
* Initialization/de-initialization
* Writing/Reading bytes
* Locking/Unlocking/Erasing pages
* Notifications about errors or being ready for a new command
Applications
------------
* Mini disk which can retain program and data storage
* Boot loader
* Non volatile storage
Dependencies
------------
The peripheral which controls a re-programmable flash memory.
Concurrency
-----------
N/A
Limitations
-----------
User should pay attention to set a proper stack size in their application,
since the driver manages a temporary buffer in stack to cache unchanged data
when calling flash write and erase function.
Due to flash memory architecture of SAMD21/D20/L21/L22/C20/C21/D09/D10/D11/R21,
write operation erazes row content before each write.
Known issues and workarounds
----------------------------
N/A

View file

@ -0,0 +1,43 @@
==========================================
Random Number Generator Synchronous driver
==========================================
Random Number Generator (RAND) generates a sequence of numbers that can not
be reasonably predicted better than by a random chance.
In some implementation cases, seed is required for the Random Number Generator
to generate random numbers. rand_sync_set_seed is used to update the seed.
If it's actually not required by the generator implementation, the function just
returns ERR_UNSUPPORTED_OP.
Features
--------
* Initialization and de-initialization
* Enabling and Disabling
* Setting seed
* 8-bit and 32-bit random data/data array generation
Applications
------------
* Generate random keys for data encryption
Dependencies
------------
* Random number generation hardware/software
Concurrency
-----------
N/A
Limitations
-----------
N/A
Known issues and workarounds
----------------------------
N/A

View file

@ -0,0 +1,51 @@
The SPI Master Synchronous Driver
=================================
The serial peripheral interface (SPI) is a synchronous serial communication
interface.
SPI devices communicate in full duplex mode using a master-slave
architecture with a single master. The master device originates the frame for
reading and writing. Multiple slave devices are supported through selection
with individual slave select (SS) lines.
Features
--------
* Initialization/de-initialization
* Enabling/disabling
* Control of the following settings:
* Baudrate
* SPI mode
* Character size
* Data order
* Data transfer: transmission, reception and full-duplex
Applications
------------
Send/receive/exchange data with a SPI slave device. E.g., serial flash, SD card,
LCD controller, etc.
Dependencies
------------
SPI master capable hardware
Concurrency
-----------
N/A
Limitations
-----------
The slave select (SS) is not automatically inserted during read/write/transfer,
user must use I/O to control the devices' SS.
Known issues and workarounds
----------------------------
N/A

View file

@ -0,0 +1,58 @@
The USART Synchronous Driver
============================
The universal synchronous and asynchronous receiver and transmitter
(USART) is usually used to transfer data from one device to the other.
User can set action for flow control pins by function usart_set_flow_control,
if the flow control is enabled. All the available states are defined in union
usart_flow_control_state.
Note that user can set state of flow control pins only if automatic support of
the flow control is not supported by the hardware.
Features
--------
* Initialization/de-initialization
* Enabling/disabling
* Control of the following settings:
* Baudrate
* UART or USRT communication mode
* Character size
* Data order
* Flow control
* Data transfer: transmission, reception
Applications
------------
They are commonly used in a terminal application or low-speed communication
between devices.
Dependencies
------------
USART capable hardware.
Concurrency
-----------
Write buffer should not be changed while data is being sent.
Limitations
-----------
* The driver does not support 9-bit character size.
* The "USART with ISO7816" mode can be only used in ISO7816 capable devices.
And the SCK pin can't be set directly. Application can use a GCLK output PIN
to generate SCK. For example to communicate with a SMARTCARD with ISO7816
(F = 372 ; D = 1), and baudrate=9600, the SCK pin output frequency should be
config as 372*9600=3571200Hz. More information can be refer to ISO7816 Specification.
Known issues and workarounds
----------------------------
N/A

View file

@ -0,0 +1,209 @@
/**
* \file
*
* \brief Flash related functionality declaration.
*
* Copyright (c) 2015-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 _HAL_FLASH_H_INCLUDED
#define _HAL_FLASH_H_INCLUDED
#include <hpl_flash.h>
/**
* \addtogroup doc_driver_hal_flash
*
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declaration of flash_descriptor. */
struct flash_descriptor;
/** The callback types */
enum flash_cb_type {
/** Callback type for ready to accept a new command */
FLASH_CB_READY,
/** Callback type for error */
FLASH_CB_ERROR,
FLASH_CB_N
};
/** \brief Prototype of callback on FLASH
*
*/
typedef void (*flash_cb_t)(struct flash_descriptor *const descr);
/** \brief FLASH HAL callbacks
*
*/
struct flash_callbacks {
/** Callback invoked when ready to accept a new command */
flash_cb_t cb_ready;
/** Callback invoked when error occurs */
flash_cb_t cb_error;
};
/** \brief FLASH HAL driver struct for asynchronous access
*/
struct flash_descriptor {
/** Pointer to FLASH device instance */
struct _flash_device dev;
/** Callbacks for asynchronous transfer */
struct flash_callbacks callbacks;
};
/** \brief Initialize the FLASH HAL instance and hardware for callback mode
*
* Initialize FLASH HAL with interrupt mode (uses callbacks).
*
* \param[in, out] flash Pointer to the HAL FLASH instance.
* \param[in] hw Pointer to the hardware base.
* \return Initialize status.
*/
int32_t flash_init(struct flash_descriptor *flash, void *const hw);
/** \brief Deinitialize the FLASH HAL instance
*
* Abort transfer, disable and reset FLASH, and deinitialize software.
*
* \param[in, out] flash Pointer to the HAL FLASH instance.
* \return Deinitialze status.
*/
int32_t flash_deinit(struct flash_descriptor *flash);
/** \brief Writes a number of bytes to a page in the internal Flash
*
* \param[in, out] flash Pointer to the HAL FLASH instance.
* \param[in] dst_addr Destination bytes address to write into flash
* \param[in] buffer Pointer to a buffer where the content
* will be written to the flash
* \param[in] length Number of bytes to write
* \return Write status.
*/
int32_t flash_write(struct flash_descriptor *flash, uint32_t dst_addr, uint8_t *buffer, uint32_t length);
/** \brief Appends a number of bytes to a page in the internal Flash
*
* This functions never erases the flash before writing.
*
* \param[in, out] flash Pointer to the HAL FLASH instance.
* \param[in] dst_addr Destination bytes address to write to flash
* \param[in] buffer Pointer to a buffer with data to write to flash
* \param[in] length Number of bytes to append
* \return Append status.
*/
int32_t flash_append(struct flash_descriptor *flash, uint32_t dst_addr, uint8_t *buffer, uint32_t length);
/** \brief Reads a number of bytes to a page in the internal Flash
*
* \param[in, out] flash Pointer to the HAL FLASH instance.
* \param[in] src_addr Source bytes address to read from flash
* \param[out] buffer Pointer to a buffer where the content
* of the read pages will be stored
* \param[in] length Number of bytes to read
* \return Read status.
*/
int32_t flash_read(struct flash_descriptor *flash, uint32_t src_addr, uint8_t *buffer, uint32_t length);
/** \brief Register a function as FLASH transfer completion callback
*
* \param[in, out] flash Pointer to the HAL FLASH instance.
* \param[in] type Callback type (\ref flash_cb_type).
* \param[in] func Pointer to callback function.
* \retval 0 Success
* \retval -1 Error
*/
int32_t flash_register_callback(struct flash_descriptor *flash, const enum flash_cb_type type, flash_cb_t func);
/** \brief Execute lock in the internal flash
*
* \param[in, out] flash Pointer to the HAL FLASH instance.
* \param[in] dst_addr Destination bytes address aligned with page
* start to be locked
* \param[in] page_nums Number of pages to be locked
*
* \return Real locked numbers of pages.
*/
int32_t flash_lock(struct flash_descriptor *flash, const uint32_t dst_addr, const uint32_t page_nums);
/** \brief Execute unlock in the internal flash
*
* \param[in, out] flash Pointer to the HAL FLASH instance.
* \param[in] dst_addr Destination bytes address aligned with page
* start to be unlocked
* \param[in] page_nums Number of pages to be unlocked
*
* \return Real unlocked numbers of pages.
*/
int32_t flash_unlock(struct flash_descriptor *flash, const uint32_t dst_addr, const uint32_t page_nums);
/** \brief Execute erase in the internal flash
*
* \param[in, out] flash Pointer to the HAL FLASH instance.
* \param[in] dst_addr Destination bytes address aligned with page
* start to be erased
* \param[in] page_nums Number of pages to be erased
* \retval 0 Success
* \retval -1 Error
*/
int32_t flash_erase(struct flash_descriptor *flash, const uint32_t dst_addr, const uint32_t page_nums);
/**
* \brief Get the flash page size
*
* \param[in, out] flash Pointer to the HAL FLASH instance
*
* \return The flash page size
*/
uint32_t flash_get_page_size(struct flash_descriptor *flash);
/**
* \brief Get the number of flash page
*
* \param[in, out] flash Pointer to the HAL FLASH instance.
*
* \return The flash total page numbers
*/
uint32_t flash_get_total_pages(struct flash_descriptor *flash);
/** \brief Retrieve the current driver version
*
* \return Current driver version.
*/
uint32_t flash_get_version(void);
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* ifndef _HAL_FLASH_H_INCLUDED */

View file

@ -0,0 +1,134 @@
/**
* \file
*
* \brief Generic Random Number Generator (RAND) functionality declaration.
*
* Copyright (c) 2015-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 _HAL_RAND_SYNC_H_INCLUDED
#define _HAL_RAND_SYNC_H_INCLUDED
#include <hpl_rand_sync.h>
#include <utils_assert.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \addtogroup doc_driver_hal_rand_sync
*
*@{
*/
/** Random Number Generator polling device. */
struct rand_sync_desc {
struct _rand_sync_dev dev;
};
/**
* \brief Initialize the Random Number Generator Driver
* \param[out] desc Pointer to the device descriptor instance struct
* \param[in, out] hw Pointer to the hardware for device instance
* \return Initialization operation result status, ERR_NONE (0) for OK.
*/
int32_t rand_sync_init(struct rand_sync_desc *const desc, void *const hw);
/**
* \brief Deinitialize the Random Number Generator Driver
* \param[out] desc Pointer to the device descriptor instance struct
*/
void rand_sync_deinit(struct rand_sync_desc *const desc);
/**
* \brief Enable the Random Number Generator Driver
* \param[out] desc Pointer to the device descriptor instance struct
* \return Enable operation result status, ERR_NONE (0) for OK.
*/
int32_t rand_sync_enable(struct rand_sync_desc *const desc);
/**
* \brief Disable the Random Number Generator Driver
* \param[out] desc Pointer to the device descriptor instance struct
*/
void rand_sync_disable(struct rand_sync_desc *const desc);
/**
* \brief Set seed for the Random Number Generator Driver
* \param[out] desc Pointer to the device descriptor instance struct
*/
int32_t rand_sync_set_seed(struct rand_sync_desc *const desc, const uint32_t seed);
/**
* \brief Read the 8-bit Random Number
* \param[in] desc Pointer to the device descriptor instance struct
* \return The random number generated
*/
uint8_t rand_sync_read8(const struct rand_sync_desc *const desc);
/**
* \brief Read the 32-bit Random Number
* \param[in] desc Pointer to the device descriptor instance struct
* \return The random number generated
*/
uint32_t rand_sync_read32(const struct rand_sync_desc *const desc);
/**
* \brief Read the 8-bit Random Number Sequence into a buffer
* \param[in] desc Pointer to the device descriptor instance struct
* \param[out] buf Pointer to the buffer to fill an array of generated numbers
* \param[in] len Number of random numbers to read
*/
void rand_sync_read_buf8(const struct rand_sync_desc *const desc, uint8_t *buf, uint32_t len);
/**
* \brief Read the 32-bit Random Number Sequence into a buffer
* \param[in] desc Pointer to the device descriptor instance struct
* \param[out] buf Pointer to the buffer to fill an array of generated numbers
* \param[in] len Number of random numbers to read
*/
void rand_sync_read_buf32(const struct rand_sync_desc *const desc, uint32_t *buf, uint32_t len);
/**
* \brief Retrieve the current driver version
*
* \return Current driver version.
*/
uint32_t rand_sync_get_version(void);
/* I/O read will be used to get random data. */
/**@}*/
#ifdef __cplusplus
}
#endif
#endif /* _HAL_RAND_SYNC_H_INCLUDED */

View file

@ -0,0 +1,221 @@
/**
* \file
*
* \brief SPI related functionality declaration.
*
* Copyright (c) 2014-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 _HAL_SPI_M_SYNC_H_INCLUDED
#define _HAL_SPI_M_SYNC_H_INCLUDED
#include <hal_io.h>
#include <hpl_spi_m_sync.h>
/**
* \addtogroup doc_driver_hal_spi_master_sync
*
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
/** \brief SPI HAL driver struct for polling mode
*
*/
struct spi_m_sync_descriptor {
struct _spi_m_sync_hpl_interface *func;
/** SPI device instance */
struct _spi_sync_dev dev;
/** I/O read/write */
struct io_descriptor io;
/** Flags for HAL driver */
uint16_t flags;
};
/** \brief Set the SPI HAL instance function pointer for HPL APIs.
*
* Set SPI HAL instance function pointer for HPL APIs.
*
* \param[in] spi Pointer to the HAL SPI instance.
* \param[in] func Pointer to the HPL api structure.
*
*/
void spi_m_sync_set_func_ptr(struct spi_m_sync_descriptor *spi, void *const func);
/** \brief Initialize SPI HAL instance and hardware for polling mode
*
* Initialize SPI HAL with polling mode.
*
* \param[in] spi Pointer to the HAL SPI instance.
* \param[in] hw Pointer to the hardware base.
*
* \return Operation status.
* \retval ERR_NONE Success.
* \retval ERR_INVALID_DATA Error, initialized.
*/
int32_t spi_m_sync_init(struct spi_m_sync_descriptor *spi, void *const hw);
/** \brief Deinitialize the SPI HAL instance and hardware
*
* Abort transfer, disable and reset SPI, deinit software.
*
* \param[in] spi Pointer to the HAL SPI instance.
*
* \return Operation status.
* \retval ERR_NONE Success.
* \retval <0 Error code.
*/
void spi_m_sync_deinit(struct spi_m_sync_descriptor *spi);
/** \brief Enable SPI
*
* \param[in] spi Pointer to the HAL SPI instance.
*
* \return Operation status.
* \retval ERR_NONE Success.
* \retval <0 Error code.
*/
void spi_m_sync_enable(struct spi_m_sync_descriptor *spi);
/** \brief Disable SPI
*
* \param[in] spi Pointer to the HAL SPI instance.
*
* \return Operation status.
* \retval ERR_NONE Success.
* \retval <0 Error code.
*/
void spi_m_sync_disable(struct spi_m_sync_descriptor *spi);
/** \brief Set SPI baudrate
*
* Works if SPI is initialized as master, it sets the baudrate.
*
* \param[in] spi Pointer to the HAL SPI instance.
* \param[in] baud_val The target baudrate value
* (see "baudrate calculation" for calculating the value).
*
* \return Operation status.
* \retval ERR_NONE Success.
* \retval ERR_BUSY Busy
* \retval ERR_INVALID_ARG The baudrate is not supported.
*/
int32_t spi_m_sync_set_baudrate(struct spi_m_sync_descriptor *spi, const uint32_t baud_val);
/** \brief Set SPI mode
*
* Set the SPI transfer mode (\ref spi_transfer_mode),
* which controls the clock polarity and clock phase:
* - Mode 0: leading edge is rising edge, data sample on leading edge.
* - Mode 1: leading edge is rising edge, data sample on trailing edge.
* - Mode 2: leading edge is falling edge, data sample on leading edge.
* - Mode 3: leading edge is falling edge, data sample on trailing edge.
*
* \param[in] spi Pointer to the HAL SPI instance.
* \param[in] mode The mode (0~3).
*
* \return Operation status.
* \retval ERR_NONE Success.
* \retval ERR_BUSY Busy
* \retval ERR_INVALID_ARG The mode is not supported.
*/
int32_t spi_m_sync_set_mode(struct spi_m_sync_descriptor *spi, const enum spi_transfer_mode mode);
/** \brief Set SPI transfer character size in number of bits
*
* The character size (\ref spi_char_size) influence the way the data is
* sent/received.
* For char size <= 8-bit, data is stored byte by byte.
* For char size between 9-bit ~ 16-bit, data is stored in 2-byte length.
* Note that the default and recommended char size is 8-bit since it's
* supported by all system.
*
* \param[in] spi Pointer to the HAL SPI instance.
* \param[in] char_size The char size (~16, recommended 8).
*
* \return Operation status.
* \retval ERR_NONE Success.
* \retval ERR_BUSY Busy
* \retval ERR_INVALID_ARG The char size is not supported.
*/
int32_t spi_m_sync_set_char_size(struct spi_m_sync_descriptor *spi, const enum spi_char_size char_size);
/** \brief Set SPI transfer data order
*
* \param[in] spi Pointer to the HAL SPI instance.
* \param[in] dord The data order: send LSB/MSB first.
*
* \return Operation status.
* \retval ERR_NONE Success.
* \retval ERR_BUSY Busy
* \retval ERR_INVALID_ARG The data order is not supported.
*/
int32_t spi_m_sync_set_data_order(struct spi_m_sync_descriptor *spi, const enum spi_data_order dord);
/** \brief Perform the SPI data transfer (TX and RX) in polling way
*
* Activate CS, do TX and RX and deactivate CS. It blocks.
*
* \param[in, out] spi Pointer to the HAL SPI instance.
* \param[in] xfer Pointer to the transfer information (\ref spi_xfer).
*
* \retval size Success.
* \retval >=0 Timeout, with number of characters transferred.
* \retval ERR_BUSY SPI is busy
*/
int32_t spi_m_sync_transfer(struct spi_m_sync_descriptor *spi, const struct spi_xfer *xfer);
/**
* \brief Return the I/O descriptor for this SPI instance
*
* This function will return an I/O instance for this SPI driver instance.
*
* \param[in] spi An SPI master descriptor, which is used to communicate through
* SPI
* \param[in, out] io A pointer to an I/O descriptor pointer type
*
* \retval ERR_NONE
*/
int32_t spi_m_sync_get_io_descriptor(struct spi_m_sync_descriptor *const spi, struct io_descriptor **io);
/** \brief Retrieve the current driver version
*
* \return Current driver version.
*/
uint32_t spi_m_sync_get_version(void);
/**@}*/
#ifdef __cplusplus
}
#endif
#endif /* ifndef _HAL_SPI_M_SYNC_H_INCLUDED */

View file

@ -0,0 +1,247 @@
/**
* \file
*
* \brief USART related functionality declaration.
*
* Copyright (c) 2014-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 _HAL_SYNC_USART_H_INCLUDED
#define _HAL_SYNC_USART_H_INCLUDED
#include "hal_io.h"
#include <hpl_usart_sync.h>
/**
* \addtogroup doc_driver_hal_usart_sync
*
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Synchronous USART descriptor
*/
struct usart_sync_descriptor {
struct io_descriptor io;
struct _usart_sync_device device;
};
/**
* \brief Initialize USART interface
*
* This function initializes the given I/O descriptor to be used
* as USART interface descriptor.
* It checks if the given hardware is not initialized and
* if the given hardware is permitted to be initialized.
*
* \param[out] descr A USART descriptor which is used to communicate via USART
* \param[in] hw The pointer to hardware instance
* \param[in] func The pointer to as set of functions pointers
*
* \return Initialization status.
*/
int32_t usart_sync_init(struct usart_sync_descriptor *const descr, void *const hw, void *const func);
/**
* \brief Deinitialize USART interface
*
* This function deinitializes the given I/O descriptor.
* It checks if the given hardware is initialized and
* if the given hardware is permitted to be deinitialized.
*
* \param[in] descr A USART descriptor which is used to communicate via USART
*
* \return De-initialization status.
*/
int32_t usart_sync_deinit(struct usart_sync_descriptor *const descr);
/**
* \brief Enable USART interface
*
* Enables the USART interface
*
* \param[in] descr A USART descriptor which is used to communicate via USART
*
* \return Enabling status.
*/
int32_t usart_sync_enable(struct usart_sync_descriptor *const descr);
/**
* \brief Disable USART interface
*
* Disables the USART interface
*
* \param[in] descr A USART descriptor which is used to communicate via USART
*
* \return Disabling status.
*/
int32_t usart_sync_disable(struct usart_sync_descriptor *const descr);
/**
* \brief Retrieve I/O descriptor
*
* This function retrieves the I/O descriptor of the given USART descriptor.
*
* \param[in] descr A USART descriptor which is used to communicate via USART
* \param[out] io An I/O descriptor to retrieve
*
* \return The status of the I/O descriptor retrieving.
*/
int32_t usart_sync_get_io_descriptor(struct usart_sync_descriptor *const descr, struct io_descriptor **io);
/**
* \brief Specify action for flow control pins
*
* This function sets the action (or state) for the flow control pins
* if the flow control is enabled.
* It sets the state of flow control pins only if the automatic support of
* the flow control is not supported by the hardware.
*
* \param[in] descr A USART descriptor which is used to communicate via USART
* \param[in] state A state to set the flow control pins
*
* \return The status of flow control action setup.
*/
int32_t usart_sync_set_flow_control(struct usart_sync_descriptor *const descr,
const union usart_flow_control_state state);
/**
* \brief Set USART baud rate
*
* \param[in] descr A USART descriptor which is used to communicate via USART
* \param[in] baud_rate A baud rate to set
*
* \return The status of baud rate setting.
*/
int32_t usart_sync_set_baud_rate(struct usart_sync_descriptor *const descr, const uint32_t baud_rate);
/**
* \brief Set USART data order
*
* \param[in] descr A USART descriptor which is used to communicate via USART
* \param[in] data_order A data order to set
*
* \return The status of data order setting.
*/
int32_t usart_sync_set_data_order(struct usart_sync_descriptor *const descr, const enum usart_data_order data_order);
/**
* \brief Set USART mode
*
* \param[in] descr A USART descriptor which is used to communicate via USART
* \param[in] mode A mode to set
*
* \return The status of mode setting.
*/
int32_t usart_sync_set_mode(struct usart_sync_descriptor *const descr, const enum usart_mode mode);
/**
* \brief Set USART parity
*
* \param[in] descr A USART descriptor which is used to communicate via USART
* \param[in] parity A parity to set
*
* \return The status of parity setting.
*/
int32_t usart_sync_set_parity(struct usart_sync_descriptor *const descr, const enum usart_parity parity);
/**
* \brief Set USART stop bits
*
* \param[in] descr A USART descriptor which is used to communicate via USART
* \param[in] stop_bits Stop bits to set
*
* \return The status of stop bits setting.
*/
int32_t usart_sync_set_stopbits(struct usart_sync_descriptor *const descr, const enum usart_stop_bits stop_bits);
/**
* \brief Set USART character size
*
* \param[in] descr A USART descriptor which is used to communicate via USART
* \param[in] size A character size to set
*
* \return The status of character size setting.
*/
int32_t usart_sync_set_character_size(struct usart_sync_descriptor *const descr, const enum usart_character_size size);
/**
* \brief Retrieve the state of flow control pins
*
* This function retrieves the of flow control pins
* if the flow control is enabled.
* Function can return USART_FLOW_CONTROL_STATE_UNAVAILABLE in case
* if the flow control is done by the hardware
* and the pins state cannot be read out.
*
* \param[in] descr A USART descriptor which is used to communicate via USART
* \param[out] state The state of flow control pins
*
* \return The status of flow control state reading.
*/
int32_t usart_sync_flow_control_status(const struct usart_sync_descriptor *const descr,
union usart_flow_control_state *const state);
/**
* \brief Check if the USART transmitter is empty
*
* \param[in] descr A USART descriptor which is used to communicate via USART
*
* \return The status of USART TX empty checking.
* \retval 0 The USART transmitter is not empty
* \retval 1 The USART transmitter is empty
*/
int32_t usart_sync_is_tx_empty(const struct usart_sync_descriptor *const descr);
/**
* \brief Check if the USART receiver is not empty
*
* \param[in] descr A USART descriptor which is used to communicate via USART
*
* \return The status of USART RX empty checking.
* \retval 1 The USART receiver is not empty
* \retval 0 The USART receiver is empty
*/
int32_t usart_sync_is_rx_not_empty(const struct usart_sync_descriptor *const descr);
/**
* \brief Retrieve the current driver version
*
* \return Current driver version.
*/
uint32_t usart_sync_get_version(void);
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* _HAL_SYNC_USART_H_INCLUDED */

View file

@ -0,0 +1,265 @@
/**
* \file
*
* \brief FLASH related functionality declaration.
*
* Copyright (c) 2015-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 _HPL_FLASH_H_INCLUDED
#define _HPL_FLASH_H_INCLUDED
/**
* \addtogroup hpl__flash__group FLASH HPL APIs
*
*/
/**@{*/
#include <compiler.h>
#include "hpl_irq.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief FLASH device structure
*
* The FLASH device structure forward declaration.
*/
struct _flash_device;
/** The callback types */
enum _flash_cb_type { FLASH_DEVICE_CB_READY, FLASH_DEVICE_CB_ERROR, FLASH_DEVICE_CB_N };
/**
* \brief FLASH interrupt handlers structure
*/
struct _flash_callback {
/** Ready to accept new command handler */
void (*ready_cb)(struct _flash_device *device);
/** Error handler */
void (*error_cb)(struct _flash_device *device);
};
/**
* \brief FLASH descriptor device structure.
*/
struct _flash_device {
struct _flash_callback flash_cb; /*!< Interrupt handers */
struct _irq_descriptor irq; /*!< Interrupt descriptor */
void * hw; /*!< Hardware module instance handler */
};
/**
* \brief Initialize FLASH.
*
* This function does low level FLASH configuration.
*
* \param[in] device The pointer to FLASH device instance
* \param[in] hw The pointer to hardware instance
*
* \return Initialize status.
*/
int32_t _flash_init(struct _flash_device *const device, void *const hw);
/**
* \brief Deinitialize FLASH.
*
* \param[in] device The pointer to FLASH device instance
*/
void _flash_deinit(struct _flash_device *const device);
/**
* \brief Reads a number of bytes in the internal Flash.
*
* \param[in] device The pointer to FLASH device instance
* \param[in] src_addr Source bytes address to read from flash
* \param[out] buffer Pointer to a buffer where the content
* of the read page will be stored
* \param[in] length Number of bytes to read
*/
void _flash_read(struct _flash_device *const device, const uint32_t src_addr, uint8_t *buffer, uint32_t length);
/**
* \brief Writes a number of bytes in the internal Flash.
*
* \param[in] device The pointer to FLASH device instance
* \param[in] dst_addr Destination bytes address to write into flash
* \param[in] buffer Pointer to buffer where the data to
* write is stored
* \param[in] length Number of bytes to write
*/
void _flash_write(struct _flash_device *const device, const uint32_t dst_addr, uint8_t *buffer, uint32_t length);
/**
* \brief Appends a number of bytes in the internal Flash.
*
* \param[in] device The pointer to FLASH device instance
* \param[in] dst_addr Destination bytes address to write into flash
* \param[in] buffer Pointer to buffer with data to write to flash
* \param[in] length Number of bytes to write
*/
void _flash_append(struct _flash_device *const device, const uint32_t dst_addr, uint8_t *buffer, uint32_t length);
/** \brief Execute lock in the internal flash
* \param[in] device The pointer to FLASH device instance
* \param[in] dst_addr Destination bytes address aligned with page
* start to be locked
* \param[in] page_nums Number of pages to be locked
*
* \return Real locked numbers of pages.
*/
int32_t _flash_lock(struct _flash_device *const device, const uint32_t dst_addr, uint32_t page_nums);
/** \brief Execute unlock in the internal flash
* \param[in] device The pointer to FLASH device instance
* \param[in] dst_addr Destination bytes address aligned with page
* start to be unlocked
* \param[in] page_nums Number of pages to be unlocked
*
* \return Real unlocked numbers of pages.
*/
int32_t _flash_unlock(struct _flash_device *const device, const uint32_t dst_addr, uint32_t page_nums);
/** \brief check whether the region which is pointed by address
* is locked
* \param[in] device The pointer to FLASH device instance
* \param[in] dst_addr Destination bytes address to check
*
* \return The lock status of assigned address.
*/
bool _flash_is_locked(struct _flash_device *const device, const uint32_t dst_addr);
/** \brief Execute erase in the internal flash
* \param[in] device The pointer to FLASH device instance
* \param[in] dst_addr Destination bytes address aligned with page
* start to be erased
* \param[in] page_nums Number of pages to be erased
*/
void _flash_erase(struct _flash_device *const device, const uint32_t dst_addr, uint32_t page_nums);
/**
* \brief Get the flash page size.
*
* \param[in] device The pointer to FLASH device instance
*
* \return The flash page size
*/
uint32_t _flash_get_page_size(struct _flash_device *const device);
/**
* \brief Get the numbers of flash page.
*
* \param[in] device The pointer to FLASH device instance
*
* \return The flash total page numbers
*/
uint32_t _flash_get_total_pages(struct _flash_device *const device);
/**
* \brief Get the number of wait states for read and write operations.
*
* \param[in] device The pointer to FLASH device instance
*
* \return The number of wait states for read and write operations
*/
uint8_t _flash_get_wait_state(struct _flash_device *const device);
/**
* \brief Set the number of wait states for read and write operations.
*
* \param[in] device The pointer to FLASH device instance
* \param[in] state The number of wait states
*
*/
void _flash_set_wait_state(struct _flash_device *const device, uint8_t state);
/**
* \brief Enable/disable Flash interrupt
*
* param[in] device The pointer to Flash device instance
* param[in] type The type of interrupt to disable/enable if applicable
* param[in] state Enable or disable
*/
void _flash_set_irq_state(struct _flash_device *const device, const enum _flash_cb_type type, const bool state);
/*
* Below RWW flash APIs are only available for device which has RWWEE
* flash array, such as SAM C20/C21/D21/L21/L22/R30/DA1/HA1 etc.
*/
/**
* \brief Get the RWWEE flash page size.
*
* \param[in] device The pointer to FLASH device instance
*
* \return The flash page size
*/
uint32_t _rww_flash_get_page_size(struct _flash_device *const device);
/**
* \brief Get the total page numbers of RWWEE flash.
*
* \param[in] device The pointer to FLASH device instance
*
* \return The flash total page numbers
*/
uint32_t _rww_flash_get_total_pages(struct _flash_device *const device);
/**
* \brief Reads a number of bytes in the internal RWWEE Flash.
*
* \param[in] device The pointer to FLASH device instance
* \param[in] src_addr Source bytes address to read from flash
* \param[out] buffer Pointer to a buffer where the content
* of the read page will be stored
* \param[in] length Number of bytes to read
*
* \return Read status, ERR_NONE for successful read.
*/
int32_t _rww_flash_read(struct _flash_device *const device, const uint32_t src_addr, uint8_t *buffer, uint32_t length);
/**
* \brief Writes a number of bytes in the internal RWWEE Flash.
*
* \param[in] device The pointer to FLASH device instance
* \param[in] dst_addr Destination bytes address to write into flash
* \param[in] buffer Pointer to buffer where the data to
* write is stored
* \param[in] length Number of bytes to write
*
* \return Write status, ERR_NONE for successful write.
*/
int32_t _rww_flash_write(struct _flash_device *const device, const uint32_t dst_addr, uint8_t *buffer, uint32_t length);
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* _HPL_FLASH_H_INCLUDED */

View file

@ -0,0 +1,99 @@
/**
* \file
*
* \brief Random Number Generator (RAND) related functionality declaration.
*
* Copyright (c) 2015-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 _HPL_RAND_SYNC_H_INCLUDED
#define _HPL_RAND_SYNC_H_INCLUDED
#include <compiler.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Random Number Generator polling device. */
struct _rand_sync_dev {
/** Pointer to private data or hardware base */
void *prvt;
/** Number of bits generated for each read operation */
uint8_t n_bits;
};
/**
* \brief Initialize the Random Number Generator Driver
* \param[out] dev Pointer to the device instance struct
* \param[in, out] hw Pointer to the hardware for device instance
* \return Initialization operation result status, 0 for OK.
*/
int32_t _rand_sync_init(struct _rand_sync_dev *const dev, void *const hw);
/**
* \brief Deinitialize the Random Number Generator Driver
* \param[in, out] dev Pointer to the device instance struct
*/
void _rand_sync_deinit(struct _rand_sync_dev *const dev);
/**
* \brief Enable the Random Number Generator Driver
* \param[out] dev Pointer to the device instance struct
* \return Enable operation result status, 0 for OK.
*/
int32_t _rand_sync_enable(struct _rand_sync_dev *const dev);
/**
* \brief Disable the Random Number Generator Driver
* \param[out] dev Pointer to the device instance struct
*/
void _rand_sync_disable(struct _rand_sync_dev *const dev);
/**
* \brief Set seed for the Random Number Generator Driver
* \param[out] dev Pointer to the device instance struct
* \param[in] seed The seed to set
* \return Operation result
* \retval ERR_NONE Operation complete success
* \retval ERR_UNSUPPORTED_OP Seed not supported
*/
int32_t _rand_sync_set_seed(struct _rand_sync_dev *const dev, const uint32_t seed);
/**
* \brief Polling random number until it's read back
* \param[in] dev Pointer to the device instance struct
* \return The random number value
*/
uint32_t _rand_sync_read_one(const struct _rand_sync_dev *const dev);
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* _HPL_RAND_SYNC_H_INCLUDED */

View file

@ -0,0 +1,88 @@
/**
* \file
*
* \brief Common SPI DMA related functionality declaration.
*
* 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 _HPL_SPI_DMA_H_INCLUDED
#define _HPL_SPI_DMA_H_INCLUDED
#include <hpl_irq.h>
#include <hpl_dma.h>
#ifdef __cplusplus
extern "C" {
#endif
/** The callback types */
enum _spi_dma_dev_cb_type {
/** Callback type for DMA transmit. */
SPI_DEV_CB_DMA_TX,
/** Callback type for DMA receive. */
SPI_DEV_CB_DMA_RX,
/** Callback type for DMA error. */
SPI_DEV_CB_DMA_ERROR,
/** Number of callbacks. */
SPI_DEV_CB_DMA_N
};
struct _spi_dma_dev;
/**
* \brief The prototype for callback on SPI DMA.
*/
typedef void (*_spi_dma_cb_t)(struct _dma_resource *resource);
/**
* \brief The callbacks offered by SPI driver
*/
struct _spi_dma_dev_callbacks {
_spi_dma_cb_t tx;
_spi_dma_cb_t rx;
_spi_dma_cb_t error;
};
/** SPI driver to support DMA HAL */
struct _spi_dma_dev {
/** Pointer to the hardware base or private data for special device. */
void *prvt;
/** Pointer to callback functions */
struct _spi_dma_dev_callbacks callbacks;
/** IRQ instance for SPI device. */
struct _irq_descriptor irq;
/** DMA resource */
struct _dma_resource *resource;
};
#ifdef __cplusplus
}
#endif
#endif /* ifndef _HPL_SPI_DMA_H_INCLUDED */

View file

@ -0,0 +1,123 @@
/**
* \file
*
* \brief Special user data area access
*
* 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 _HPL_USER_DATA_H_INCLUDED
#define _HPL_USER_DATA_H_INCLUDED
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Read data from user data area
*
* The user data area could be the area that stores user data that is not erased
* with the flash contents, e.g.,
* - NVM Software Calibration Area of SAM D/L/C family
* - User Signature of SAM E/S/V 70
*
* \param[in] base The base address of the user area
* \param[in] offset The byte offset of the data to be read inside the area
* \param[out] buf Pointer to buffer to place the read data
* \param[in] size Size of data in number of bytes
*
* \return Operation status or bytes read.
* \retval ERR_NONE Data read successfully
* \retval ERR_UNSUPPORTED_OP base address not in any supported user area
* \retval ERR_BAD_ADDRESS offset not in right area
* \retval ERR_INVALID_ARG offset and size exceeds the right area
*/
int32_t _user_area_read(const void *base, const uint32_t offset, uint8_t *buf, const uint32_t size);
/**
* \brief Read no more than 32 bits data from user data area
*
* When reading bits, the bitfield can cross 32-bis boundaries.
*
* \param[in] base The base address of the user area
* \param[in] bit_offset Offset in number of bits
* \param[in] n_bits Number of bits to read
* \return data read, assert if anything wrong (address not in user area
* offset, size error, etc.).
*/
uint32_t _user_area_read_bits(const void *base, const uint32_t bit_offset, const uint8_t n_bits);
/**
* \brief Write data to user data area
*
* The user data area could be the area that stores user data that is not erased
* with the flash contents, e.g.,
* - NVM Software Calibration Area of SAM D/L/C family
* - User Signature of SAM E/S/V 70
*
* When assigned offset and size exceeds the data area, error is reported.
*
* \param[out] base The base address of the user area
* \param[in] offset The offset of the data to be written inside the area
* \param[in] buf Pointer to buffer to place the written data
* \param[in] size Size of data in number of bytes
*
* \return Operation status or bytes writting.
* \retval ERR_NONE Data written successfully
* \retval ERR_UNSUPPORTED_OP base address not in any supported user area
* \retval ERR_DENIED Security bit is set
* \retval ERR_BAD_ADDRESS offset not in right area
* \retval ERR_INVALID_ARG offset and size exceeds the right area
*/
int32_t _user_area_write(void *base, const uint32_t offset, const uint8_t *buf, const uint32_t size);
/**
* \brief Write no more than 32 bits data to user data area
*
* When writting bits, the bitfield can cross 32-bis boundaries.
*
* \param[out] base The base address of the user area
* \param[in] bit_offset Offset in number of bits
* \param[in] bits The data content
* \param[in] n_bits Number of bits to write
* \return Operation result
* \retval ERR_NONE Data written successfully
* \retval ERR_UNSUPPORTED_OP base address not in any supported user area
* \retval ERR_DENIED Security bit is set
* \retval ERR_BAD_ADDRESS offset not in right area
* \retval ERR_INVALID_ARG offset and size exceeds the right area
*/
int32_t _user_area_write_bits(void *base, const uint32_t bit_offset, const uint32_t bits, const uint8_t n_bits);
#ifdef __cplusplus
}
#endif
#endif /* _HPL_USER_DATA_H_INCLUDED */

314
watch-library/hal/src/hal_flash.c Executable file
View file

@ -0,0 +1,314 @@
/**
* \file
*
* \brief Flash functionality implementation.
*
* Copyright (c) 2015-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 "hal_flash.h"
#include <utils_assert.h>
#include <utils.h>
#include <hal_atomic.h>
/**
* \brief Driver version
*/
#define DRIVER_VERSION 0x00000001u
static void flash_ready(struct _flash_device *device);
static void flash_error(struct _flash_device *device);
static int32_t flash_is_address_aligned(struct flash_descriptor *flash, const uint32_t flash_addr);
/**
* \brief Initialize the FLASH HAL instance and hardware for callback mode.
*/
int32_t flash_init(struct flash_descriptor *flash, void *const hw)
{
int32_t rc;
ASSERT(flash && hw);
rc = _flash_init(&flash->dev, hw);
if (rc) {
return rc;
}
flash->dev.flash_cb.ready_cb = flash_ready;
flash->dev.flash_cb.error_cb = flash_error;
return ERR_NONE;
}
/**
* \brief Deinitialize the FLASH HAL instance.
*/
int32_t flash_deinit(struct flash_descriptor *flash)
{
ASSERT(flash);
_flash_deinit(&flash->dev);
return ERR_NONE;
}
/**
* \brief Reads a number of bytes to a page in the internal Flash
*/
int32_t flash_read(struct flash_descriptor *flash, uint32_t src_addr, uint8_t *buffer, uint32_t length)
{
ASSERT(flash && buffer && length);
uint32_t page_size = _flash_get_page_size(&flash->dev);
uint32_t total_pages = _flash_get_total_pages(&flash->dev);
/* Check if the address is valid */
if ((src_addr > page_size * total_pages) || (src_addr + length > page_size * total_pages)) {
return ERR_BAD_ADDRESS;
}
_flash_read(&flash->dev, src_addr, buffer, length);
return ERR_NONE;
}
/**
* \brief Updates several bytes to the internal Flash
*/
int32_t flash_write(struct flash_descriptor *flash, uint32_t dst_addr, uint8_t *buffer, uint32_t length)
{
ASSERT(flash && buffer && length);
uint32_t page_size = _flash_get_page_size(&flash->dev);
uint32_t total_pages = _flash_get_total_pages(&flash->dev);
/* Check if the address is valid */
if ((dst_addr > page_size * total_pages) || (dst_addr + length > page_size * total_pages)) {
return ERR_BAD_ADDRESS;
}
if (_flash_is_locked(&flash->dev, dst_addr)) {
return ERR_DENIED;
}
_flash_write(&flash->dev, dst_addr, buffer, length);
return ERR_NONE;
}
/**
* \brief Appends a number of bytes to a page in the internal Flash
*/
int32_t flash_append(struct flash_descriptor *flash, uint32_t dst_addr, uint8_t *buffer, uint32_t length)
{
ASSERT(flash && buffer && length);
uint32_t page_size = _flash_get_page_size(&flash->dev);
uint32_t total_pages = _flash_get_total_pages(&flash->dev);
/* Check if the address is valid */
if ((dst_addr > page_size * total_pages) || (dst_addr + length > page_size * total_pages)) {
return ERR_BAD_ADDRESS;
}
if (_flash_is_locked(&flash->dev, dst_addr)) {
return ERR_DENIED;
}
_flash_append(&flash->dev, dst_addr, buffer, length);
return ERR_NONE;
}
/**
* \brief Execute erase in the internal flash
*/
int32_t flash_erase(struct flash_descriptor *flash, const uint32_t dst_addr, const uint32_t page_nums)
{
ASSERT(flash && page_nums);
uint32_t page_size = _flash_get_page_size(&flash->dev);
uint32_t total_pages = _flash_get_total_pages(&flash->dev);
int32_t rc;
rc = flash_is_address_aligned(flash, dst_addr);
if (rc) {
return rc;
}
if ((page_nums > total_pages) || (dst_addr / page_size + page_nums > total_pages)) {
return ERR_INVALID_ARG;
}
_flash_erase(&flash->dev, dst_addr, page_nums);
return ERR_NONE;
}
/**
* \brief Register a function as FLASH transfer completion callback
*/
int32_t flash_register_callback(struct flash_descriptor *flash, const enum flash_cb_type type, flash_cb_t func)
{
ASSERT(flash);
switch (type) {
case FLASH_CB_READY:
flash->callbacks.cb_ready = func;
break;
case FLASH_CB_ERROR:
flash->callbacks.cb_error = func;
break;
default:
return ERR_INVALID_ARG;
}
_flash_set_irq_state(&flash->dev, (enum _flash_cb_type)type, NULL != func);
return ERR_NONE;
}
/**
* \brief Execute lock in the internal flash
*/
int32_t flash_lock(struct flash_descriptor *flash, const uint32_t dst_addr, const uint32_t page_nums)
{
ASSERT(flash && page_nums);
uint32_t page_size = _flash_get_page_size(&flash->dev);
uint32_t total_pages = _flash_get_total_pages(&flash->dev);
int32_t rc;
rc = flash_is_address_aligned(flash, dst_addr);
if (rc) {
return rc;
}
if ((page_nums > total_pages) || (dst_addr / page_size + page_nums > total_pages)) {
return ERR_INVALID_ARG;
}
return _flash_lock(&flash->dev, dst_addr, page_nums);
}
/**
* \brief Execute unlock in the internal flash
*/
int32_t flash_unlock(struct flash_descriptor *flash, const uint32_t dst_addr, const uint32_t page_nums)
{
ASSERT(flash && page_nums);
uint32_t page_size = _flash_get_page_size(&flash->dev);
uint32_t total_pages = _flash_get_total_pages(&flash->dev);
int32_t rc;
rc = flash_is_address_aligned(flash, dst_addr);
if (rc) {
return rc;
}
if ((page_nums > total_pages) || (dst_addr / page_size + page_nums > total_pages)) {
return ERR_INVALID_ARG;
}
return _flash_unlock(&flash->dev, dst_addr, page_nums);
}
/**
* \brief Get the flash page size.
*/
uint32_t flash_get_page_size(struct flash_descriptor *flash)
{
ASSERT(flash);
return _flash_get_page_size(&flash->dev);
}
/**
* \brief Get the numbers of flash page.
*/
uint32_t flash_get_total_pages(struct flash_descriptor *flash)
{
ASSERT(flash);
return _flash_get_total_pages(&flash->dev);
}
/**
* \brief Retrieve the current driver version
*/
uint32_t flash_get_version(void)
{
return DRIVER_VERSION;
}
/**
* \internal check the address whether it is aligned
* \param[in, out] flash Pointer to the HAL FLASH instance.
* \param[in] flash_addr address to be check in flash
*
* \return whether it is valid
* \retval 0 Valid.
* \retval -1 Error, invalid.
*/
static int32_t flash_is_address_aligned(struct flash_descriptor *flash, const uint32_t flash_addr)
{
ASSERT(flash);
uint32_t page_size = _flash_get_page_size(&flash->dev);
/* Check if the read address not aligned to the start of a page */
if (flash_addr & (page_size - 1)) {
return ERR_BAD_ADDRESS;
}
return ERR_NONE;
}
/**
* \internal Ready for a new flash command
*
* \param[in] device The pointer to flash device structure
*/
static void flash_ready(struct _flash_device *device)
{
struct flash_descriptor *const descr = CONTAINER_OF(device, struct flash_descriptor, dev);
if (descr->callbacks.cb_ready) {
descr->callbacks.cb_ready(descr);
}
}
/**
* \internal Error occurs in flash command
*
* \param[in] device The pointer to flash device structure
*/
static void flash_error(struct _flash_device *device)
{
struct flash_descriptor *const descr = CONTAINER_OF(device, struct flash_descriptor, dev);
if (descr->callbacks.cb_error) {
descr->callbacks.cb_error(descr);
}
}

View file

@ -0,0 +1,122 @@
/**
* \file
*
* \brief Generic Random Number Generator (RNG) functionality declaration.
*
* Copyright (c) 2015-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 <utils.h>
#include "hal_rand_sync.h"
#define HAL_RNG_SYNC_VERSION 0x00000001u
int32_t rand_sync_init(struct rand_sync_desc *const desc, void *const hw)
{
ASSERT(desc);
return _rand_sync_init(&desc->dev, hw);
}
void rand_sync_deinit(struct rand_sync_desc *const desc)
{
ASSERT(desc);
_rand_sync_deinit(&desc->dev);
}
int32_t rand_sync_enable(struct rand_sync_desc *const desc)
{
ASSERT(desc);
return _rand_sync_enable(&desc->dev);
}
void rand_sync_disable(struct rand_sync_desc *const desc)
{
ASSERT(desc);
_rand_sync_disable(&desc->dev);
}
int32_t rand_sync_set_seed(struct rand_sync_desc *const desc, const uint32_t seed)
{
ASSERT(desc);
return _rand_sync_set_seed(&desc->dev, seed);
}
/**
* \brief Read data bits
*/
static uint32_t _rand_sync_read_data(const struct _rand_sync_dev *dev, const uint8_t n_bits)
{
uint8_t r_bits = (dev->n_bits < 1) ? 32 : dev->n_bits;
if (r_bits < n_bits) {
uint8_t i;
uint32_t d = 0;
/* Join read bits */
for (i = 0; i < n_bits; i += r_bits) {
d |= (uint32_t)(_rand_sync_read_one(dev) << i);
}
return d;
} else {
return _rand_sync_read_one(dev);
}
}
uint8_t rand_sync_read8(const struct rand_sync_desc *const desc)
{
ASSERT(desc);
return (uint8_t)_rand_sync_read_data(&desc->dev, 8);
}
uint32_t rand_sync_read32(const struct rand_sync_desc *const desc)
{
ASSERT(desc);
return (uint32_t)_rand_sync_read_data(&desc->dev, 32);
}
void rand_sync_read_buf8(const struct rand_sync_desc *const desc, uint8_t *buf, uint32_t len)
{
uint32_t i;
ASSERT(desc && (buf && len));
for (i = 0; i < len; i++) {
buf[i] = (uint8_t)_rand_sync_read_data(&desc->dev, 8);
}
}
void rand_sync_read_buf32(const struct rand_sync_desc *const desc, uint32_t *buf, uint32_t len)
{
uint32_t i;
ASSERT(desc && (buf && len));
for (i = 0; i < len; i++) {
buf[i] = (uint32_t)_rand_sync_read_data(&desc->dev, 32);
}
}
uint32_t rand_sync_get_version(void)
{
return HAL_RNG_SYNC_VERSION;
}

View file

@ -0,0 +1,201 @@
/**
* \file
*
* \brief I/O SPI related functionality implementation.
*
* Copyright (c) 2014-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 "hal_spi_m_sync.h"
#include <utils_assert.h>
#include <utils.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Driver version
*/
#define SPI_M_SYNC_DRIVER_VERSION 0x00000001u
#define SPI_DEACTIVATE_NEXT 0x8000
static int32_t _spi_m_sync_io_write(struct io_descriptor *const io, const uint8_t *const buf, const uint16_t length);
static int32_t _spi_m_sync_io_read(struct io_descriptor *const io, uint8_t *const buf, const uint16_t length);
/**
* \brief Initialize the SPI HAL instance function pointer for HPL APIs.
*/
void spi_m_sync_set_func_ptr(struct spi_m_sync_descriptor *spi, void *const func)
{
ASSERT(spi);
spi->func = (struct _spi_m_sync_hpl_interface *)func;
}
int32_t spi_m_sync_init(struct spi_m_sync_descriptor *spi, void *const hw)
{
int32_t rc = 0;
ASSERT(spi && hw);
spi->dev.prvt = (void *)hw;
rc = _spi_m_sync_init(&spi->dev, hw);
if (rc < 0) {
return rc;
}
spi->flags = SPI_DEACTIVATE_NEXT;
spi->io.read = _spi_m_sync_io_read;
spi->io.write = _spi_m_sync_io_write;
return ERR_NONE;
}
void spi_m_sync_deinit(struct spi_m_sync_descriptor *spi)
{
ASSERT(spi);
_spi_m_sync_deinit(&spi->dev);
}
void spi_m_sync_enable(struct spi_m_sync_descriptor *spi)
{
ASSERT(spi);
_spi_m_sync_enable(&spi->dev);
}
void spi_m_sync_disable(struct spi_m_sync_descriptor *spi)
{
ASSERT(spi);
_spi_m_sync_disable(&spi->dev);
}
int32_t spi_m_sync_set_baudrate(struct spi_m_sync_descriptor *spi, const uint32_t baud_val)
{
ASSERT(spi);
return _spi_m_sync_set_baudrate(&spi->dev, baud_val);
}
int32_t spi_m_sync_set_mode(struct spi_m_sync_descriptor *spi, const enum spi_transfer_mode mode)
{
ASSERT(spi);
return _spi_m_sync_set_mode(&spi->dev, mode);
}
int32_t spi_m_sync_set_char_size(struct spi_m_sync_descriptor *spi, const enum spi_char_size char_size)
{
ASSERT(spi);
return _spi_m_sync_set_char_size(&spi->dev, char_size);
}
int32_t spi_m_sync_set_data_order(struct spi_m_sync_descriptor *spi, const enum spi_data_order dord)
{
ASSERT(spi);
return _spi_m_sync_set_data_order(&spi->dev, dord);
}
/** \brief Do SPI read in polling way
* For SPI master, activate CS, do send 0xFFs and read data, deactivate CS.
*
* It blocks until all data read or error.
*
* \param[in, out] spi Pointer to the HAL SPI instance.
* \param[out] buf Pointer to the buffer to store read data.
* \param[in] size Size of the data in number of characters.
* \return Operation status.
* \retval size Success.
* \retval >=0 Time out, with number of characters read.
*/
static int32_t _spi_m_sync_io_read(struct io_descriptor *io, uint8_t *buf, const uint16_t length)
{
ASSERT(io);
struct spi_m_sync_descriptor *spi = CONTAINER_OF(io, struct spi_m_sync_descriptor, io);
struct spi_xfer xfer;
xfer.rxbuf = buf;
xfer.txbuf = 0;
xfer.size = length;
return spi_m_sync_transfer(spi, &xfer);
}
/** \brief Do SPI data write in polling way
* For SPI master, activate CS, do buffer send and deactivate CS. The data back
* is discarded.
*
* The data read back is discarded.
*
* It blocks until all data sent or error.
*
* \param[in, out] spi Pointer to the HAL SPI instance.
* \param[in] p_xfer Pointer to the transfer information (\ref spi_transfer).
* \return Operation status.
* \retval size Success.
* \retval >=0 Timeout, with number of characters transferred.
*/
static int32_t _spi_m_sync_io_write(struct io_descriptor *const io, const uint8_t *const buf, const uint16_t length)
{
ASSERT(io);
struct spi_m_sync_descriptor *spi = CONTAINER_OF(io, struct spi_m_sync_descriptor, io);
struct spi_xfer xfer;
xfer.rxbuf = 0;
xfer.txbuf = (uint8_t *)buf;
xfer.size = length;
return spi_m_sync_transfer(spi, &xfer);
}
int32_t spi_m_sync_transfer(struct spi_m_sync_descriptor *spi, const struct spi_xfer *p_xfer)
{
struct spi_msg msg;
ASSERT(spi && p_xfer);
msg.txbuf = p_xfer->txbuf;
msg.rxbuf = p_xfer->rxbuf;
msg.size = p_xfer->size;
return _spi_m_sync_trans(&spi->dev, &msg);
}
int32_t spi_m_sync_get_io_descriptor(struct spi_m_sync_descriptor *const spi, struct io_descriptor **io)
{
ASSERT(spi && io);
*io = &spi->io;
return 0;
}
uint32_t spi_m_sync_get_version(void)
{
return SPI_M_SYNC_DRIVER_VERSION;
}
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,276 @@
/**
* \file
*
* \brief I/O USART related functionality implementation.
*
* Copyright (c) 2014-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 "hal_usart_sync.h"
#include <utils_assert.h>
#include <utils.h>
/**
* \brief Driver version
*/
#define DRIVER_VERSION 0x00000001u
static int32_t usart_sync_write(struct io_descriptor *const io_descr, const uint8_t *const buf, const uint16_t length);
static int32_t usart_sync_read(struct io_descriptor *const io_descr, uint8_t *const buf, const uint16_t length);
/**
* \brief Initialize usart interface
*/
int32_t usart_sync_init(struct usart_sync_descriptor *const descr, void *const hw, void *const func)
{
int32_t init_status;
ASSERT(descr && hw);
init_status = _usart_sync_init(&descr->device, hw);
if (init_status) {
return init_status;
}
descr->io.read = usart_sync_read;
descr->io.write = usart_sync_write;
return ERR_NONE;
}
/**
* \brief Uninitialize usart interface
*/
int32_t usart_sync_deinit(struct usart_sync_descriptor *const descr)
{
ASSERT(descr);
_usart_sync_deinit(&descr->device);
descr->io.read = NULL;
descr->io.write = NULL;
return ERR_NONE;
}
/**
* \brief Enable usart interface
*/
int32_t usart_sync_enable(struct usart_sync_descriptor *const descr)
{
ASSERT(descr);
_usart_sync_enable(&descr->device);
return ERR_NONE;
}
/**
* \brief Disable usart interface
*/
int32_t usart_sync_disable(struct usart_sync_descriptor *const descr)
{
ASSERT(descr);
_usart_sync_disable(&descr->device);
return ERR_NONE;
}
/**
* \brief Retrieve I/O descriptor
*/
int32_t usart_sync_get_io_descriptor(struct usart_sync_descriptor *const descr, struct io_descriptor **io)
{
ASSERT(descr && io);
*io = &descr->io;
return ERR_NONE;
}
/**
* \brief Specify action for flow control pins
*/
int32_t usart_sync_set_flow_control(struct usart_sync_descriptor *const descr,
const union usart_flow_control_state state)
{
ASSERT(descr);
_usart_sync_set_flow_control_state(&descr->device, state);
return ERR_NONE;
}
/**
* \brief Set usart baud rate
*/
int32_t usart_sync_set_baud_rate(struct usart_sync_descriptor *const descr, const uint32_t baud_rate)
{
ASSERT(descr);
_usart_sync_set_baud_rate(&descr->device, baud_rate);
return ERR_NONE;
}
/**
* \brief Set usart data order
*/
int32_t usart_sync_set_data_order(struct usart_sync_descriptor *const descr, const enum usart_data_order data_order)
{
ASSERT(descr);
_usart_sync_set_data_order(&descr->device, data_order);
return ERR_NONE;
}
/**
* \brief Set usart mode
*/
int32_t usart_sync_set_mode(struct usart_sync_descriptor *const descr, const enum usart_mode mode)
{
ASSERT(descr);
_usart_sync_set_mode(&descr->device, mode);
return ERR_NONE;
}
/**
* \brief Set usart parity
*/
int32_t usart_sync_set_parity(struct usart_sync_descriptor *const descr, const enum usart_parity parity)
{
ASSERT(descr);
_usart_sync_set_parity(&descr->device, parity);
return ERR_NONE;
}
/**
* \brief Set usart stop bits
*/
int32_t usart_sync_set_stopbits(struct usart_sync_descriptor *const descr, const enum usart_stop_bits stop_bits)
{
ASSERT(descr);
_usart_sync_set_stop_bits(&descr->device, stop_bits);
return ERR_NONE;
}
/**
* \brief Set usart character size
*/
int32_t usart_sync_set_character_size(struct usart_sync_descriptor *const descr, const enum usart_character_size size)
{
ASSERT(descr);
_usart_sync_set_character_size(&descr->device, size);
return ERR_NONE;
}
/**
* \brief Retrieve the state of flow control pins
*/
int32_t usart_sync_flow_control_status(const struct usart_sync_descriptor *const descr,
union usart_flow_control_state *const state)
{
ASSERT(descr && state);
*state = _usart_sync_get_flow_control_state(&descr->device);
return ERR_NONE;
}
/**
* \brief Check if the usart transmitter is empty
*/
int32_t usart_sync_is_tx_empty(const struct usart_sync_descriptor *const descr)
{
ASSERT(descr);
return _usart_sync_is_ready_to_send(&descr->device);
}
/**
* \brief Check if the usart receiver is not empty
*/
int32_t usart_sync_is_rx_not_empty(const struct usart_sync_descriptor *const descr)
{
ASSERT(descr);
return _usart_sync_is_byte_received(&descr->device);
}
/**
* \brief Retrieve the current driver version
*/
uint32_t usart_sync_get_version(void)
{
return DRIVER_VERSION;
}
/*
* \internal Write the given data to usart interface
*
* \param[in] descr The pointer to an io descriptor
* \param[in] buf Data to write to usart
* \param[in] length The number of bytes to write
*
* \return The number of bytes written.
*/
static int32_t usart_sync_write(struct io_descriptor *const io_descr, const uint8_t *const buf, const uint16_t length)
{
uint32_t offset = 0;
struct usart_sync_descriptor *descr = CONTAINER_OF(io_descr, struct usart_sync_descriptor, io);
ASSERT(io_descr && buf && length);
while (!_usart_sync_is_ready_to_send(&descr->device))
;
do {
_usart_sync_write_byte(&descr->device, buf[offset]);
while (!_usart_sync_is_ready_to_send(&descr->device))
;
} while (++offset < length);
while (!_usart_sync_is_transmit_done(&descr->device))
;
return (int32_t)offset;
}
/*
* \internal Read data from usart interface
*
* \param[in] descr The pointer to an io descriptor
* \param[in] buf A buffer to read data to
* \param[in] length The size of a buffer
*
* \return The number of bytes read.
*/
static int32_t usart_sync_read(struct io_descriptor *const io_descr, uint8_t *const buf, const uint16_t length)
{
uint32_t offset = 0;
struct usart_sync_descriptor *descr = CONTAINER_OF(io_descr, struct usart_sync_descriptor, io);
ASSERT(io_descr && buf && length);
do {
while (!_usart_sync_is_byte_received(&descr->device))
;
buf[offset] = _usart_sync_read_byte(&descr->device);
} while (++offset < length);
return (int32_t)offset;
}

View file

@ -0,0 +1,782 @@
/**
* \file
*
* \brief Non-Volatile Memory Controller
*
* Copyright (c) 2015-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 <hpl_flash.h>
#include <hpl_user_area.h>
#include <string.h>
#include <utils_assert.h>
#include <utils.h>
#include <hpl_nvmctrl_config.h>
#define NVM_MEMORY ((volatile uint16_t *)FLASH_ADDR)
/**
* \brief NVM configuration type
*/
struct nvm_configuration {
hri_nvmctrl_ctrlb_reg_t ctrlb; /*!< Control B Register */
};
/**
* \brief Array of NVM configurations
*/
static struct nvm_configuration _nvm
= {(CONF_NVM_CACHE << NVMCTRL_CTRLB_CACHEDIS_Pos) | (CONF_NVM_READ_MODE << NVMCTRL_CTRLB_READMODE_Pos)
| (CONF_NVM_SLEEPPRM << NVMCTRL_CTRLB_SLEEPPRM_Pos)};
/*!< Pointer to hpl device */
static struct _flash_device *_nvm_dev = NULL;
static void _flash_erase_row(void *const hw, const uint32_t dst_addr, uint32_t nvmctrl_cmd);
static void _flash_program(void *const hw, const uint32_t dst_addr, const uint8_t *buffer, const uint16_t size,
uint32_t nvmctrl_cmd);
/**
* \brief Initialize NVM
*/
int32_t _flash_init(struct _flash_device *const device, void *const hw)
{
ASSERT(device && (hw == NVMCTRL));
uint32_t ctrlb;
device->hw = hw;
ctrlb = _nvm.ctrlb & ~(NVMCTRL_CTRLB_RWS_Msk | NVMCTRL_CTRLB_MANW);
ctrlb |= hri_nvmctrl_get_CTRLB_reg(device->hw, NVMCTRL_CTRLB_RWS_Msk | NVMCTRL_CTRLB_MANW);
hri_nvmctrl_write_CTRLB_reg(device->hw, ctrlb);
_nvm_dev = device;
NVIC_DisableIRQ(NVMCTRL_IRQn);
NVIC_ClearPendingIRQ(NVMCTRL_IRQn);
NVIC_EnableIRQ(NVMCTRL_IRQn);
return ERR_NONE;
}
/**
* \brief De-initialize NVM
*/
void _flash_deinit(struct _flash_device *const device)
{
device->hw = NULL;
NVIC_DisableIRQ(NVMCTRL_IRQn);
}
/**
* \brief Get the flash page size.
*/
uint32_t _flash_get_page_size(struct _flash_device *const device)
{
(void)device;
return (uint32_t)NVMCTRL_PAGE_SIZE;
}
/**
* \brief Get the numbers of flash page.
*/
uint32_t _flash_get_total_pages(struct _flash_device *const device)
{
(void)device;
return (uint32_t)FLASH_NB_OF_PAGES;
}
/**
* \brief Get the number of wait states for read and write operations.
*/
uint8_t _flash_get_wait_state(struct _flash_device *const device)
{
return hri_nvmctrl_get_CTRLB_reg(device->hw, NVMCTRL_CTRLB_RWS_Msk);
}
/**
* \brief Set the number of wait states for read and write operations.
*/
void _flash_set_wait_state(struct _flash_device *const device, uint8_t state)
{
hri_nvmctrl_write_CTRLB_RWS_bf(device->hw, state);
}
/**
* \brief Reads a number of bytes to a page in the internal Flash.
*/
void _flash_read(struct _flash_device *const device, const uint32_t src_addr, uint8_t *buffer, uint32_t length)
{
uint32_t nvm_address = src_addr / 2;
uint32_t i;
uint16_t data;
/* Check if the module is busy */
while (!hri_nvmctrl_get_interrupt_READY_bit(device->hw)) {
/* Wait until this module isn't busy */
}
/* Clear flags */
hri_nvmctrl_clear_STATUS_reg(device->hw, NVMCTRL_STATUS_MASK);
/* Check whether byte address is word-aligned*/
if (src_addr % 2) {
data = NVM_MEMORY[nvm_address++];
buffer[0] = data >> 8;
i = 1;
} else {
i = 0;
}
/* NVM _must_ be accessed as a series of 16-bit words, perform manual copy
* to ensure alignment */
while (i < length) {
data = NVM_MEMORY[nvm_address++];
buffer[i] = (data & 0xFF);
if (i < (length - 1)) {
buffer[i + 1] = (data >> 8);
}
i += 2;
}
}
/**
* \brief Writes a number of bytes to a page in the internal Flash.
*/
void _flash_write(struct _flash_device *const device, const uint32_t dst_addr, uint8_t *buffer, uint32_t length)
{
uint8_t tmp_buffer[NVMCTRL_ROW_PAGES][NVMCTRL_PAGE_SIZE];
uint32_t row_start_addr, row_end_addr;
uint32_t i, j, k;
uint32_t wr_start_addr = dst_addr;
do {
row_start_addr = wr_start_addr & ~((NVMCTRL_PAGE_SIZE * NVMCTRL_ROW_PAGES) - 1);
row_end_addr = row_start_addr + NVMCTRL_ROW_PAGES * NVMCTRL_PAGE_SIZE - 1;
/* store the erase data into temp buffer before write */
for (i = 0; i < NVMCTRL_ROW_PAGES; i++) {
_flash_read(device, row_start_addr + i * NVMCTRL_PAGE_SIZE, tmp_buffer[i], NVMCTRL_PAGE_SIZE);
}
/* temp buffer update */
j = (wr_start_addr - row_start_addr) / NVMCTRL_PAGE_SIZE;
k = wr_start_addr - row_start_addr - j * NVMCTRL_PAGE_SIZE;
while ((wr_start_addr <= row_end_addr) && (length > 0)) {
tmp_buffer[j][k] = *buffer;
k = (k + 1) % NVMCTRL_PAGE_SIZE;
if (0 == k) {
j++;
}
wr_start_addr++;
buffer++;
length--;
}
/* erase row before write */
_flash_erase_row(device->hw, row_start_addr, NVMCTRL_CTRLA_CMD_ER);
/* write buffer to flash */
for (i = 0; i < NVMCTRL_ROW_PAGES; i++) {
_flash_program(device->hw,
row_start_addr + i * NVMCTRL_PAGE_SIZE,
tmp_buffer[i],
NVMCTRL_PAGE_SIZE,
NVMCTRL_CTRLA_CMD_WP);
}
} while (row_end_addr < (wr_start_addr + length - 1));
}
/**
* \brief Appends a number of bytes in the internal Flash.
*/
void _flash_append(struct _flash_device *const device, const uint32_t dst_addr, uint8_t *buffer, uint32_t length)
{
uint32_t page_start_addr = dst_addr & ~(NVMCTRL_PAGE_SIZE - 1);
uint32_t size;
uint32_t offset = 0;
if (dst_addr != page_start_addr) {
/* Need to write some data to the end of a page */
size = min(length, NVMCTRL_PAGE_SIZE - (dst_addr - page_start_addr));
_flash_program(device->hw, dst_addr, buffer, size, NVMCTRL_CTRLA_CMD_WP);
page_start_addr += NVMCTRL_PAGE_SIZE;
offset += size;
}
while (offset < length) {
size = min(length - offset, NVMCTRL_PAGE_SIZE);
_flash_program(device->hw, page_start_addr, buffer + offset, size, NVMCTRL_CTRLA_CMD_WP);
page_start_addr += NVMCTRL_PAGE_SIZE;
offset += size;
}
}
/**
* \brief Execute erase in the internal flash
*/
void _flash_erase(struct _flash_device *const device, uint32_t dst_addr, uint32_t page_nums)
{
uint8_t tmp_buffer[NVMCTRL_PAGE_SIZE];
uint32_t row_start_addr;
uint32_t i;
row_start_addr = dst_addr & ~((NVMCTRL_PAGE_SIZE * NVMCTRL_ROW_PAGES) - 1);
memset(tmp_buffer, 0xFF, NVMCTRL_PAGE_SIZE);
/* when address is not aligned with row start address */
if (dst_addr != row_start_addr) {
row_start_addr += NVMCTRL_ROW_PAGES * NVMCTRL_PAGE_SIZE;
for (i = 0; i < NVMCTRL_ROW_PAGES - 1; i++) {
_flash_write(device, dst_addr, tmp_buffer, NVMCTRL_PAGE_SIZE);
if (--page_nums == 0) {
return;
}
dst_addr += NVMCTRL_PAGE_SIZE;
if (dst_addr == row_start_addr) {
break;
}
}
}
while (page_nums >= NVMCTRL_ROW_PAGES) {
_flash_erase_row(device->hw, row_start_addr, NVMCTRL_CTRLA_CMD_ER);
row_start_addr += NVMCTRL_ROW_PAGES * NVMCTRL_PAGE_SIZE;
page_nums -= NVMCTRL_ROW_PAGES;
}
if (page_nums != 0) {
for (i = 0; i < page_nums; i++) {
_flash_write(device, row_start_addr, tmp_buffer, NVMCTRL_PAGE_SIZE);
row_start_addr += NVMCTRL_PAGE_SIZE;
}
}
}
/**
* \brief Execute lock in the internal flash
*/
int32_t _flash_lock(struct _flash_device *const device, const uint32_t dst_addr, uint32_t page_nums)
{
uint32_t region_pages;
uint32_t row_start_addr;
region_pages = (uint32_t)NVMCTRL_FLASH_SIZE / (16 * NVMCTRL_PAGE_SIZE);
row_start_addr = dst_addr & ~((NVMCTRL_PAGE_SIZE * NVMCTRL_ROW_PAGES) - 1);
if ((page_nums != region_pages) || (dst_addr != row_start_addr)) {
return ERR_INVALID_ARG;
}
while (!hri_nvmctrl_get_interrupt_READY_bit(device->hw)) {
/* Wait until this module isn't busy */
}
/* Clear flags */
hri_nvmctrl_clear_STATUS_reg(device->hw, NVMCTRL_STATUS_MASK);
hri_nvmctrl_write_ADDR_reg(device->hw, dst_addr / 2);
hri_nvmctrl_write_CTRLA_reg(device->hw, NVMCTRL_CTRLA_CMD_LR | NVMCTRL_CTRLA_CMDEX_KEY);
return (int32_t)NVMCTRL_FLASH_SIZE / (16 * NVMCTRL_PAGE_SIZE);
}
/**
* \brief Execute unlock in the internal flash
*/
int32_t _flash_unlock(struct _flash_device *const device, const uint32_t dst_addr, uint32_t page_nums)
{
uint32_t region_pages;
uint32_t row_start_addr;
region_pages = (uint32_t)NVMCTRL_FLASH_SIZE / (16 * NVMCTRL_PAGE_SIZE);
row_start_addr = dst_addr & ~((NVMCTRL_PAGE_SIZE * NVMCTRL_ROW_PAGES) - 1);
if ((page_nums != region_pages) || (dst_addr != row_start_addr)) {
return ERR_INVALID_ARG;
}
while (!hri_nvmctrl_get_interrupt_READY_bit(device->hw)) {
/* Wait until this module isn't busy */
}
/* Clear flags */
hri_nvmctrl_clear_STATUS_reg(device->hw, NVMCTRL_STATUS_MASK);
hri_nvmctrl_write_ADDR_reg(device->hw, dst_addr / 2);
hri_nvmctrl_write_CTRLA_reg(device->hw, NVMCTRL_CTRLA_CMD_UR | NVMCTRL_CTRLA_CMDEX_KEY);
return (int32_t)NVMCTRL_FLASH_SIZE / (16 * NVMCTRL_PAGE_SIZE);
}
/**
* \brief check whether the region which is pointed by address
*/
bool _flash_is_locked(struct _flash_device *const device, const uint32_t dst_addr)
{
uint16_t region_id;
/* Get region for given page */
region_id = dst_addr / (NVMCTRL_FLASH_SIZE / 16);
return !(hri_nvmctrl_get_LOCK_reg(device->hw, 1 << region_id));
}
/**
* \brief Enable/disable Flash interrupt
*/
void _flash_set_irq_state(struct _flash_device *const device, const enum _flash_cb_type type, const bool state)
{
ASSERT(device);
if (FLASH_DEVICE_CB_READY == type) {
hri_nvmctrl_write_INTEN_READY_bit(device->hw, state);
} else if (FLASH_DEVICE_CB_ERROR == type) {
hri_nvmctrl_write_INTEN_ERROR_bit(device->hw, state);
}
}
/**
* \internal erase a row in flash
* \param[in] hw The pointer to hardware instance
* \param[in] dst_addr Destination page address to erase
*/
static void _flash_erase_row(void *const hw, const uint32_t dst_addr, uint32_t nvmctrl_cmd)
{
while (!hri_nvmctrl_get_interrupt_READY_bit(hw)) {
/* Wait until this module isn't busy */
}
/* Clear flags */
hri_nvmctrl_clear_STATUS_reg(hw, NVMCTRL_STATUS_MASK);
/* Set address and command */
hri_nvmctrl_write_ADDR_reg(hw, dst_addr / 2);
hri_nvmctrl_write_CTRLA_reg(hw, nvmctrl_cmd | NVMCTRL_CTRLA_CMDEX_KEY);
}
/**
* \internal write a page in flash
* \param[in] hw The pointer to hardware instance
* \param[in] dst_addr Destination page address to write
* \param[in] buffer Pointer to buffer where the data to
* write is stored
* \param[in] size The size of data to write to a page
*/
static void _flash_program(void *const hw, const uint32_t dst_addr, const uint8_t *buffer, const uint16_t size,
uint32_t nvmctrl_cmd)
{
ASSERT(!(dst_addr % 2));
uint32_t nvm_address = dst_addr / 2;
uint16_t i, data;
while (!hri_nvmctrl_get_interrupt_READY_bit(hw)) {
/* Wait until this module isn't busy */
}
hri_nvmctrl_write_CTRLA_reg(hw, NVMCTRL_CTRLA_CMD_PBC | NVMCTRL_CTRLA_CMDEX_KEY);
while (!hri_nvmctrl_get_interrupt_READY_bit(hw)) {
/* Wait until this module isn't busy */
}
/* Clear flags */
hri_nvmctrl_clear_STATUS_reg(hw, NVMCTRL_STATUS_MASK);
for (i = 0; i < size; i += 2) {
data = buffer[i];
if (i < NVMCTRL_PAGE_SIZE - 1) {
data |= (buffer[i + 1] << 8);
}
NVM_MEMORY[nvm_address++] = data;
}
while (!hri_nvmctrl_get_interrupt_READY_bit(hw)) {
/* Wait until this module isn't busy */
}
hri_nvmctrl_write_ADDR_reg(hw, dst_addr / 2);
hri_nvmctrl_write_CTRLA_reg(hw, nvmctrl_cmd | NVMCTRL_CTRLA_CMDEX_KEY);
}
/**
* \internal NVM interrupt handler
*/
void NVMCTRL_Handler(void)
{
void *const hw = _nvm_dev->hw;
if (hri_nvmctrl_get_interrupt_READY_bit(hw)) {
if (NULL != _nvm_dev->flash_cb.ready_cb) {
_nvm_dev->flash_cb.ready_cb(_nvm_dev);
}
} else if (hri_nvmctrl_get_interrupt_ERROR_bit(hw)) {
hri_nvmctrl_clear_interrupt_ERROR_bit(hw);
if (NULL != _nvm_dev->flash_cb.error_cb) {
_nvm_dev->flash_cb.error_cb(_nvm_dev);
}
}
}
/*
The NVM User Row contains calibration data that are automatically read at device
power on.
The NVM User Row can be read at address 0x804000.
*/
#ifndef _NVM_USER_ROW_BASE
#define _NVM_USER_ROW_BASE 0x804000
#endif
#define _NVM_USER_ROW_N_BITS 64
#define _NVM_USER_ROW_N_BYTES (_NVM_USER_ROW_N_BITS / 8)
#define _NVM_USER_ROW_END (((uint8_t *)_NVM_USER_ROW_BASE) + _NVM_USER_ROW_N_BYTES - 1)
#define _IS_NVM_USER_ROW(b) \
(((uint8_t *)(b) >= (uint8_t *)(_NVM_USER_ROW_BASE)) && ((uint8_t *)(b) <= (uint8_t *)(_NVM_USER_ROW_END)))
#define _IN_NVM_USER_ROW(b, o) (((uint8_t *)(b) + (o)) <= (uint8_t *)(_NVM_USER_ROW_END))
/*
The NVM Software Calibration Area can be read at address 0x806020.
The NVM Software Calibration Area can not be written.
*/
#ifndef _NVM_SW_CALIB_AREA_BASE
#define _NVM_SW_CALIB_AREA_BASE 0x806020
#endif
#define _NVM_SW_CALIB_AREA_N_BITS 128
#define _NVM_SW_CALIB_AREA_N_BYTES (_NVM_SW_CALIB_AREA_N_BITS / 8)
#define _NVM_SW_CALIB_AREA_END (((uint8_t *)_NVM_SW_CALIB_AREA_BASE) + _NVM_SW_CALIB_AREA_N_BYTES - 1)
#define _IS_NVM_SW_CALIB_AREA(b) \
(((uint8_t *)(b) >= (uint8_t *)_NVM_SW_CALIB_AREA_BASE) && ((uint8_t *)(b) <= (uint8_t *)_NVM_SW_CALIB_AREA_END))
#define _IN_NVM_SW_CALIB_AREA(b, o) (((uint8_t *)(b) + (o)) <= (uint8_t *)(_NVM_SW_CALIB_AREA_END))
/**
* \internal Read left aligned data bits
* \param[in] base Base address for the data
* \param[in] bit_offset Offset for the bitfield start
* \param[in] n_bits Number of bits in the bitfield
*/
static inline uint32_t _user_area_read_l32_bits(const volatile uint32_t *base, const uint32_t bit_offset,
const uint8_t n_bits)
{
return base[bit_offset >> 5] & ((1 << n_bits) - 1);
}
/**
* \internal Read right aligned data bits
* \param[in] base Base address for the data
* \param[in] bit_offset Offset for the bitfield start
* \param[in] n_bits Number of bits in the bitfield
*/
static inline uint32_t _user_area_read_r32_bits(const volatile uint32_t *base, const uint32_t bit_offset,
const uint8_t n_bits)
{
return (base[bit_offset >> 5] >> (bit_offset & 0x1F)) & ((1 << n_bits) - 1);
}
int32_t _user_area_read(const void *base, const uint32_t offset, uint8_t *buf, uint32_t size)
{
ASSERT(buf);
/** Parameter check. */
if (_IS_NVM_USER_ROW(base)) {
if (!_IN_NVM_USER_ROW(base, offset)) {
return ERR_BAD_ADDRESS;
}
/* Cut off if request too many bytes */
if (!_IN_NVM_USER_ROW(base, offset + size - 1)) {
return ERR_INVALID_ARG;
}
} else if (_IS_NVM_SW_CALIB_AREA(base)) {
if (!_IN_NVM_SW_CALIB_AREA(base, offset)) {
return ERR_BAD_ADDRESS;
}
/* Cut off if request too many bytes */
if (!_IN_NVM_SW_CALIB_AREA(base, offset + size - 1)) {
return ERR_INVALID_ARG;
}
} else {
return ERR_UNSUPPORTED_OP;
}
/* Copy data */
memcpy(buf, ((uint8_t *)base) + offset, size);
return ERR_NONE;
}
uint32_t _user_area_read_bits(const void *base, const uint32_t bit_offset, const uint8_t n_bits)
{
volatile uint32_t *mem_base = (volatile uint32_t *)base;
uint32_t l_off, l_bits;
uint32_t r_off, r_bits;
/** Parameter check. */
if (_IS_NVM_USER_ROW(base)) {
ASSERT(_IN_NVM_USER_ROW(base, bit_offset >> 3) && _IN_NVM_USER_ROW(base, (bit_offset + n_bits - 1) >> 3));
} else if (_IS_NVM_SW_CALIB_AREA(base)) {
ASSERT(_IN_NVM_SW_CALIB_AREA(base, bit_offset >> 3)
&& _IN_NVM_SW_CALIB_AREA(base, (bit_offset + n_bits - 1) >> 3));
} else {
ASSERT(false);
}
/* Since the bitfield can cross 32-bits boundaries,
* left and right bits are read from 32-bit aligned address
* and then combined together. */
l_off = bit_offset & (~(32 - 1));
r_off = l_off + 32;
l_bits = 32 - (bit_offset & (32 - 1));
if (n_bits > l_bits) {
r_bits = n_bits - l_bits;
} else {
l_bits = n_bits;
r_bits = 0;
}
return _user_area_read_r32_bits(mem_base, bit_offset, l_bits)
+ (_user_area_read_l32_bits(mem_base, r_off, r_bits) << l_bits);
}
/** \internal Write 64-bit user row
* \param[in] _row Pointer to 64-bit user row data.
*/
static int32_t _user_row_write_exec(const uint32_t *_row)
{
Nvmctrl *hw = NVMCTRL;
uint32_t ctrlb = hri_nvmctrl_read_CTRLB_reg(NVMCTRL);
/* Denie if Security Bit is set */
if (hri_nvmctrl_get_STATUS_reg(hw, NVMCTRL_STATUS_SB)) {
return ERR_DENIED;
}
/* Do Save */
/* - Prepare. */
while (!hri_nvmctrl_get_INTFLAG_reg(hw, NVMCTRL_INTFLAG_READY)) {
/* Wait until this module isn't busy */
}
hri_nvmctrl_clear_STATUS_reg(hw, NVMCTRL_STATUS_MASK);
hri_nvmctrl_set_CTRLB_MANW_bit(hw);
/* - Erase AUX row. */
hri_nvmctrl_write_ADDR_reg(hw, (hri_nvmctrl_addr_reg_t)(_NVM_USER_ROW_BASE / 2));
hri_nvmctrl_write_CTRLA_reg(hw, NVMCTRL_CTRLA_CMD_EAR | NVMCTRL_CTRLA_CMDEX_KEY);
while (!hri_nvmctrl_get_INTFLAG_reg(hw, NVMCTRL_INTFLAG_READY)) {
/* Wait until this module isn't busy */
}
/* - Page buffer clear & write. */
hri_nvmctrl_write_CTRLA_reg(hw, NVMCTRL_CTRLA_CMD_PBC | NVMCTRL_CTRLA_CMDEX_KEY);
while (!hri_nvmctrl_get_INTFLAG_reg(hw, NVMCTRL_INTFLAG_READY)) {
/* Wait until this module isn't busy */
}
*((uint32_t *)NVMCTRL_AUX0_ADDRESS) = _row[0];
*(((uint32_t *)NVMCTRL_AUX0_ADDRESS) + 1) = _row[1];
/* - Write AUX row. */
hri_nvmctrl_write_ADDR_reg(hw, (hri_nvmctrl_addr_reg_t)(_NVM_USER_ROW_BASE / 2));
hri_nvmctrl_write_CTRLA_reg(hw, NVMCTRL_CTRLA_CMD_WAP | NVMCTRL_CTRLA_CMDEX_KEY);
while (!hri_nvmctrl_get_INTFLAG_reg(hw, NVMCTRL_INTFLAG_READY)) {
/* Wait until this module isn't busy */
}
/* Restore CTRLB */
hri_nvmctrl_write_CTRLB_reg(NVMCTRL, ctrlb);
return ERR_NONE;
}
int32_t _user_area_write(void *base, const uint32_t offset, const uint8_t *buf, const uint32_t size)
{
uint32_t _row[2]; /* Copy of user row. */
/** Parameter check. */
if (_IS_NVM_USER_ROW(base)) {
if (!_IN_NVM_USER_ROW(base, offset)) {
return ERR_BAD_ADDRESS;
} else if (!_IN_NVM_USER_ROW(base, offset + size - 1)) {
return ERR_INVALID_ARG;
}
} else if (_IS_NVM_SW_CALIB_AREA(base)) {
return ERR_DENIED;
} else {
return ERR_UNSUPPORTED_OP;
}
memcpy(_row, base, 8); /* Store previous data. */
memcpy((uint8_t *)_row + offset, buf, size); /* Modify with buf data. */
return _user_row_write_exec(_row);
}
int32_t _user_area_write_bits(void *base, const uint32_t bit_offset, const uint32_t bits, const uint8_t n_bits)
{
uint32_t _row[2]; /* Copy of user row. */
uint32_t l_off, l_bits;
uint32_t r_off, r_bits;
/** Parameter check. */
if (_IS_NVM_USER_ROW(base)) {
if (!_IN_NVM_USER_ROW(base, bit_offset >> 3)) {
return ERR_BAD_ADDRESS;
} else if (!_IN_NVM_USER_ROW(base, (bit_offset + n_bits - 1) >> 3)) {
return ERR_INVALID_ARG;
}
} else if (_IS_NVM_SW_CALIB_AREA(base)) {
return ERR_DENIED;
} else {
return ERR_UNSUPPORTED_OP;
}
/* Since the bitfield can cross 32-bits boundaries,
* left and right bits are splitted for 32-bit aligned address
* and then saved. */
l_off = bit_offset & (~(32 - 1));
r_off = l_off + 32;
l_bits = 32 - (bit_offset & (32 - 1));
if (n_bits > l_bits) {
r_bits = n_bits - l_bits;
} else {
l_bits = n_bits;
r_bits = 0;
}
memcpy(_row, base, 8); /* Store previous data. */
if (l_bits) {
uint32_t l_mask = ((1 << l_bits) - 1) << (bit_offset & (32 - 1));
_row[bit_offset >> 5] &= ~l_mask;
_row[bit_offset >> 5] |= (bits << (bit_offset & (32 - 1))) & l_mask;
}
if (r_bits) {
uint32_t r_mask = (1 << r_bits) - 1;
_row[r_off >> 5] &= ~r_mask;
_row[r_off >> 5] |= bits >> l_bits;
}
return _user_row_write_exec(_row);
}
/**
* \brief Return if given address is in Flash RWWEE array range.
*/
static bool _is_valid_rww_flash_address(uint32_t addr)
{
#define RWWEE_ADDR_START NVMCTRL_RWW_EEPROM_ADDR
#define RWWEE_ADDR_END (NVMCTRL_RWW_EEPROM_ADDR + NVMCTRL_PAGE_SIZE * NVMCTRL_RWWEE_PAGES)
if ((addr < NVMCTRL_RWW_EEPROM_ADDR)
|| (addr > (NVMCTRL_RWW_EEPROM_ADDR + NVMCTRL_PAGE_SIZE * NVMCTRL_RWWEE_PAGES))) {
return false;
}
return true;
}
/**
* \brief Get the RWWEE flash page size.
*/
uint32_t _rww_flash_get_page_size(struct _flash_device *const device)
{
(void)device;
return (uint32_t)NVMCTRL_PAGE_SIZE;
}
/**
* \brief Get the total page numbers of RWWEE flash.
*/
uint32_t _rww_flash_get_total_pages(struct _flash_device *const device)
{
(void)device;
return (uint32_t)NVMCTRL_RWWEE_PAGES;
}
/**
* \brief Reads a number of bytes in the internal RWWEE Flash.
*/
int32_t _rww_flash_read(struct _flash_device *const device, const uint32_t src_addr, uint8_t *buffer, uint32_t length)
{
/* Check if the address is valid */
if (!_is_valid_rww_flash_address(src_addr) || !_is_valid_rww_flash_address(src_addr + length)) {
return ERR_BAD_ADDRESS;
}
_flash_read(device, src_addr, buffer, length);
return ERR_NONE;
}
/**
* \brief Writes a number of bytes in the internal RWWEE Flash.
*/
int32_t _rww_flash_write(struct _flash_device *const device, const uint32_t dst_addr, uint8_t *buffer, uint32_t length)
{
uint8_t tmp_buffer[NVMCTRL_ROW_PAGES][NVMCTRL_PAGE_SIZE];
uint32_t row_start_addr, row_end_addr;
uint32_t i, j, k;
uint32_t wr_start_addr = dst_addr;
/* Check if the address is valid */
if (!_is_valid_rww_flash_address(dst_addr) || !_is_valid_rww_flash_address(dst_addr + length)) {
return ERR_BAD_ADDRESS;
}
do {
row_start_addr = wr_start_addr & ~((NVMCTRL_PAGE_SIZE * NVMCTRL_ROW_PAGES) - 1);
row_end_addr = row_start_addr + NVMCTRL_ROW_PAGES * NVMCTRL_PAGE_SIZE - 1;
/* store the erase data into temp buffer before write */
for (i = 0; i < NVMCTRL_ROW_PAGES; i++) {
_rww_flash_read(device, row_start_addr + i * NVMCTRL_PAGE_SIZE, tmp_buffer[i], NVMCTRL_PAGE_SIZE);
}
/* temp buffer update */
j = (wr_start_addr - row_start_addr) / NVMCTRL_PAGE_SIZE;
k = wr_start_addr - row_start_addr - j * NVMCTRL_PAGE_SIZE;
while ((wr_start_addr <= row_end_addr) && (length > 0)) {
tmp_buffer[j][k] = *buffer;
k = (k + 1) % NVMCTRL_PAGE_SIZE;
if (0 == k) {
j++;
}
wr_start_addr++;
buffer++;
length--;
}
/* erase row before write */
_flash_erase_row(device->hw, row_start_addr, NVMCTRL_CTRLA_CMD_RWWEEER);
/* write buffer to flash */
for (i = 0; i < NVMCTRL_ROW_PAGES; i++) {
_flash_program(device->hw,
row_start_addr + i * NVMCTRL_PAGE_SIZE,
tmp_buffer[i],
NVMCTRL_PAGE_SIZE,
NVMCTRL_CTRLA_CMD_RWWEEWP);
}
} while (row_end_addr < (wr_start_addr + length - 1));
return ERR_NONE;
}

110
watch-library/hpl/trng/hpl_trng.c Executable file
View file

@ -0,0 +1,110 @@
/**
* \file
*
* \brief True Random Number Generator
*
* Copyright (c) 2015-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 <err_codes.h>
#include <hpl_rand_sync.h>
#include <hpl_trng_config.h>
#include <utils_assert.h>
static inline int32_t _trng_init(void *hw)
{
if (hri_trng_get_CTRLA_reg(hw, TRNG_CTRLA_ENABLE)) {
return ERR_DENIED;
}
if (CONF_TRNG_RUNSTDBY) {
hri_trng_set_CTRLA_RUNSTDBY_bit(hw);
} else {
hri_trng_clear_CTRLA_RUNSTDBY_bit(hw);
}
if (CONF_TRNG_DATARDYEO) {
hri_trng_set_EVCTRL_DATARDYEO_bit(hw);
} else {
hri_trng_clear_EVCTRL_DATARDYEO_bit(hw);
}
return ERR_NONE;
}
int32_t _rand_sync_init(struct _rand_sync_dev *const dev, void *const hw)
{
int32_t rc;
ASSERT(dev && hw);
rc = _trng_init(hw);
if (rc == ERR_NONE) {
dev->prvt = hw;
dev->n_bits = 32;
}
return rc;
}
void _rand_sync_deinit(struct _rand_sync_dev *const dev)
{
_rand_sync_disable(dev);
}
int32_t _rand_sync_enable(struct _rand_sync_dev *const dev)
{
ASSERT(dev);
ASSERT(dev->prvt);
hri_trng_set_CTRLA_ENABLE_bit(dev->prvt);
return ERR_NONE;
}
void _rand_sync_disable(struct _rand_sync_dev *const dev)
{
ASSERT(dev);
ASSERT(dev->prvt);
hri_trng_clear_CTRLA_ENABLE_bit(dev->prvt);
}
int32_t _rand_sync_set_seed(struct _rand_sync_dev *const dev, const uint32_t seed)
{
(void)dev;
(void)seed;
return ERR_UNSUPPORTED_OP;
}
uint32_t _rand_sync_read_one(const struct _rand_sync_dev *const dev)
{
ASSERT(dev);
ASSERT(dev->prvt);
ASSERT(hri_trng_get_CTRLA_reg(dev->prvt, TRNG_CTRLA_ENABLE));
while (!hri_trng_get_INTFLAG_reg(dev->prvt, TRNG_INTFLAG_DATARDY)) {
/* Wait until data ready. */
}
return hri_trng_read_DATA_reg(dev->prvt);
}