Add platform support to Musca S1

Change-Id: Iebdd4bc402446caba6b7bd894eddb0a85ed884d8
Signed-off-by: Mark Horvath <mark.horvath@arm.com>
Signed-off-by: Gabor Toth <gabor.toth@arm.com>
pull/13196/head
Gabor Toth 2020-06-24 17:06:45 +02:00
parent 7f60090ddb
commit bdf2306f16
75 changed files with 15078 additions and 2 deletions

View File

@ -84,6 +84,12 @@
},
"MCU_PSOC6_M4": {
"target.macros_add": ["CY_RTOS_AWARE"]
},
"ARM_MUSCA_S1": {
"mutex-num": 4,
"semaphore-num": 4,
"thread-num": 9,
"thread-user-stack-size": 8096
}
}
}

View File

@ -230,6 +230,10 @@
"NUCLEO_L452RE-P": {
"crash-capture-enabled": true,
"fatal-error-auto-reboot-enabled": true
},
"ARM_MUSCA_S1": {
"stdio-convert-newlines": true,
"stdio-baud-rate": 115200
}
}
}

View File

@ -43,6 +43,9 @@
},
"ARM_MUSCA_B1_S": {
"storage_type": "TDB_INTERNAL"
},
"ARM_MUSCA_S1_S": {
"storage_type": "TDB_INTERNAL"
}
}
}

View File

@ -31,6 +31,10 @@
"internal_size": "0x8000",
"internal_base_address": "0x10000000"
},
"ARM_MUSCA_S1_S": {
"internal_size": "0x8000",
"internal_base_address": "0x1A1CA000"
},
"FVP_MPS2": {
"internal_size": "0x200000",
"internal_base_address": "0x00200000"

View File

@ -0,0 +1,2 @@
Unless specifically indicated otherwise in a file, MUSCA_S1 files in this directory are licensed under the BSD-3-Clause license,
as can be found in: LICENSE-bsd-3-clause.txt

View File

@ -0,0 +1,26 @@
Copyright 2019-2020 Arm Limited and affiliates.
SPDX-License-Identifier: BSD-3-Clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,49 @@
Permissive Binary License
Version 1.0, December 2020
Redistribution. Redistribution and use in binary form, without
modification, are permitted provided that the following conditions are
met:
1) Redistributions must reproduce the above copyright notice and the
following disclaimer in the documentation and/or other materials
provided with the distribution.
2) Unless to the extent explicitly permitted by law, no reverse
engineering, decompilation, or disassembly of this software is
permitted.
3) Redistribution as part of a software development kit must include the
accompanying file named DEPENDENCIES and any dependencies listed in
that file.
4) Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
Limited patent license. The copyright holders (and contributors) grant a
worldwide, non-exclusive, no-charge, royalty-free patent license to
make, have made, use, offer to sell, sell, import, and otherwise
transfer this software, where such license applies only to those patent
claims licensable by the copyright holders (and contributors) that are
necessarily infringed by this software. This patent license shall not
apply to any combinations that include this software. No hardware is
licensed hereunder.
If you institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the software
itself infringes your patent(s), then your rights granted under this
license shall terminate as of the date such litigation is filed.
DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS." ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,903 @@
/*
* Copyright (c) 2018-2019 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
/* Use memcpy function */
#include <string.h>
#include "mt25ql_flash_lib.h"
#include "qspi_ip6514e_drv.h"
/** Setter bit manipulation macro */
#define SET_BIT(WORD, BIT_INDEX) ((WORD) |= (1U << (BIT_INDEX)))
/** Clearing bit manipulation macro */
#define CLR_BIT(WORD, BIT_INDEX) ((WORD) &= ~(1U << (BIT_INDEX)))
/** Getter bit manipulation macro */
#define GET_BIT(WORD, BIT_INDEX) (bool)(((WORD) & (1U << (BIT_INDEX))))
#define BITS_PER_WORD 32U
#define BYTES_PER_WORD 4U
#define ARG_NOT_USED 0
#define ARG_PTR_NOT_USED NULL
/** MT25QL used command */
#define WRITE_ENABLE_CMD 0x06U
#define READ_ENHANCED_VOLATILE_CFG_REG_CMD 0x65U
#define WRITE_ENHANCED_VOLATILE_CFG_REG_CMD 0x61U
#define READ_VOLATILE_CFG_REG_CMD 0x85U
#define WRITE_VOLATILE_CFG_REG_CMD 0x81U
#define READ_FLAG_STATUS_REG_CMD 0x70U
#define SUBSECTOR_ERASE_32KB_CMD 0x52U
#define SUBSECTOR_ERASE_4KB_CMD 0x20U
#define SECTOR_ERASE_CMD 0xD8U
#define BULK_ERASE_CMD 0xC7U
/*
* The baud rate divisor in \ref mt25ql_dev_t needs to be configured adequately
* to handle those commands.
*/
#define QUAD_OUTPUT_FAST_READ_CMD 0x6BU
#define FAST_READ_CMD 0x0BU
#define READ_CMD 0x03U
#define QUAD_INPUT_FAST_PROGRAM_CMD 0x32U
#define PAGE_PROGRAM_CMD 0x02U
/** MT25QL Enhanced Volatile Configuration Register access */
#define ENHANCED_VOLATILE_CFG_REG_LEN 1U
#define ENHANCED_VOLATILE_CFG_REG_QSPI_POS 7U
#define ENHANCED_VOLATILE_CFG_REG_DSPI_POS 6U
/** MT25QL Volatile Configuration Register access */
#define VOLATILE_CFG_REG_LEN 1U
#define VOLATILE_CFG_REG_DUMMY_CYCLES_POS 4U
#define VOLATILE_CFG_REG_DUMMY_CYCLES_BITS 4U
/** MT25QL Flag Status Register access */
#define FLAG_STATUS_REG_LEN 1U
#define FLAG_STATUS_REG_READY_POS 7U
/*
* 10 is the minimal number of dummy clock cycles needed to reach the maximal
* frequency of the Quad Output Fast Read Command.
*/
#define QUAD_OUTPUT_FAST_READ_DUMMY_CYCLES 10U
#define FAST_READ_DUMMY_CYCLES 8U
#define RESET_STATE_DUMMY_CYCLES 8U
#define DEFAULT_READ_DUMMY_CYCLES 0U
#define QUAD_INPUT_FAST_PROGRAM_DUMMY_CYCLES 0U
#define PAGE_PROGRAM_DUMMY_CYCLES 0U
/* Only up to 8 bytes can be read or written using the Flash commands. */
#define CMD_DATA_MAX_SIZE 8U
/**
* \brief Change specific bits in a 32 bits word.
*
* \param[in,out] word Pointer of the word to change
* \param[in] bits bits_length bits to put at bits_pos in the word
* pointed
* \param[in] bits_length Number of bits to change
* \param[in] bits_pos Position of the bits to change
*
* \note This function will do nothing if the parameters given are incorrect:
* * word is NULL
* * bits_length + bits_pos > 32
* * bits_length is 0
*/
static void change_bits_in_word(volatile uint32_t *word,
uint32_t bits,
uint32_t bits_length,
uint32_t bits_pos)
{
uint32_t mask;
if ((word == NULL) ||
((bits_length + bits_pos) > BITS_PER_WORD) ||
(bits_length == 0U)) {
/* Silently fail */
return;
}
/* Change all the bits */
if (bits_length == BITS_PER_WORD) {
*word = bits;
return;
}
mask = ((1U << bits_length) - 1);
/*
* We change the bits in three steps:
* - clear bits_length bits with zeroes at bits_pos in the word
* - mask bits in case it contains more than bits_length bits
* - set the new bits in the cleared word
* Because the data pointed by word is only read once, the data will still
* be coherent after an interruption that changes it.
*/
*word = ((*word & ~(mask << bits_pos)) | ((bits & mask) << bits_pos));
}
/**
* \brief Send the Write Enable command, needed before any write.
*
* \param[in] dev Pointer to MT25QL device structure \ref mt25ql_dev_t
*/
static void send_write_enable(struct mt25ql_dev_t* dev)
{
qspi_ip6514e_send_simple_cmd(dev->controller, WRITE_ENABLE_CMD);
}
/**
* \brief Set SPI mode on the flash device and on the controller.
*
* \param[in] dev Pointer to MT25QL device structure \ref mt25ql_dev_t
* \param[in] spi_mode SPI mode to be set on flash device and controller
* \ref qspi_ip6514e_spi_mode_t
*
* \return Return error code as specified in \ref mt25ql_error_t
*/
static enum mt25ql_error_t set_spi_mode(struct mt25ql_dev_t* dev,
enum qspi_ip6514e_spi_mode_t spi_mode)
{
uint8_t enhanced_volatile_cfg_reg = 0;
enum qspi_ip6514e_error_t controller_error;
/* Read the Enhanced Volatile Configuration Register, modify it according
* to the requested SPI mode then write back the modified value to the
* register. This will activate the SPI mode on the flash side.
*/
controller_error = qspi_ip6514e_send_read_cmd(
dev->controller,
READ_ENHANCED_VOLATILE_CFG_REG_CMD,
&enhanced_volatile_cfg_reg,
ENHANCED_VOLATILE_CFG_REG_LEN,
ARG_NOT_USED,
ARG_NOT_USED,
0); /* No dummy cycles needed for
this command. */
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
switch(spi_mode) {
case QSPI_IP6514E_SPI_MODE:
/* Disable the Dual- and Quad-SPI modes.
* Clearing the bit enables the mode, setting it disables it.
*/
SET_BIT(enhanced_volatile_cfg_reg, ENHANCED_VOLATILE_CFG_REG_DSPI_POS);
SET_BIT(enhanced_volatile_cfg_reg, ENHANCED_VOLATILE_CFG_REG_QSPI_POS);
break;
case QSPI_IP6514E_DSPI_MODE:
/* Disable the Quad-SPI mode and activate DSPI mode.
* Clearing the bit enables the mode, setting it disables it.
*/
CLR_BIT(enhanced_volatile_cfg_reg, ENHANCED_VOLATILE_CFG_REG_DSPI_POS);
SET_BIT(enhanced_volatile_cfg_reg, ENHANCED_VOLATILE_CFG_REG_QSPI_POS);
break;
case QSPI_IP6514E_QSPI_MODE:
/* Disable the Dual-SPI mode and activate QSPI mode.
* Clearing the bit enables the mode, setting it disables it.
*/
SET_BIT(enhanced_volatile_cfg_reg, ENHANCED_VOLATILE_CFG_REG_DSPI_POS);
CLR_BIT(enhanced_volatile_cfg_reg, ENHANCED_VOLATILE_CFG_REG_QSPI_POS);
break;
default:
return MT25QL_ERR_WRONG_ARGUMENT;
}
send_write_enable(dev);
controller_error = qspi_ip6514e_send_write_cmd(
dev->controller,
WRITE_ENHANCED_VOLATILE_CFG_REG_CMD,
&enhanced_volatile_cfg_reg,
ENHANCED_VOLATILE_CFG_REG_LEN,
ARG_NOT_USED,
ARG_NOT_USED,
0); /* No dummy cycles needed for
this command. */
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
/* Activate the requested SPI mode on the controller side as well. */
controller_error = qspi_ip6514e_set_spi_mode(dev->controller,
spi_mode,
spi_mode,
spi_mode);
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
return MT25QL_ERR_NONE;
}
/**
* \brief Change the number of dummy clock cycles subsequent to all FAST READ
* commands.
*
* \param[in] dev Pointer to MT25QL device structure \ref mt25ql_dev_t
* \param[in] dummy_cycles Dummy clock cycles to set
*
* \return Return error code as specified in \ref mt25ql_error_t
*/
static enum mt25ql_error_t change_dummy_cycles(struct mt25ql_dev_t* dev,
uint32_t dummy_cycles)
{
uint32_t volatile_cfg_reg = 0;
enum qspi_ip6514e_error_t controller_error;
/*
* Changes the number of dummy cycles in the Volatile Configuration
* Register.
*/
controller_error = qspi_ip6514e_send_read_cmd(dev->controller,
READ_VOLATILE_CFG_REG_CMD,
&volatile_cfg_reg,
VOLATILE_CFG_REG_LEN,
ARG_NOT_USED,
ARG_NOT_USED,
0); /* No dummy cycles needed
for this command. */
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
change_bits_in_word(&volatile_cfg_reg,
dummy_cycles,
VOLATILE_CFG_REG_DUMMY_CYCLES_BITS,
VOLATILE_CFG_REG_DUMMY_CYCLES_POS);
send_write_enable(dev);
controller_error = qspi_ip6514e_send_write_cmd(dev->controller,
WRITE_VOLATILE_CFG_REG_CMD,
&volatile_cfg_reg,
VOLATILE_CFG_REG_LEN,
ARG_NOT_USED,
ARG_NOT_USED,
0); /* No dummy cycles needed
for this command. */
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
return MT25QL_ERR_NONE;
}
/**
* \brief Wait until the current program/erase is finished.
*
* \param[in] dev Pointer to MT25QL device structure \ref mt25ql_dev_t
*
* \return Return error code as specified in \ref mt25ql_error_t
*/
static enum mt25ql_error_t wait_program_or_erase_complete(
struct mt25ql_dev_t* dev)
{
enum qspi_ip6514e_error_t controller_error;
uint8_t flag_status_reg = 0;
/* Wait until the ready bit of the Flag Status Register is set */
while (!GET_BIT(flag_status_reg, FLAG_STATUS_REG_READY_POS)) {
controller_error = qspi_ip6514e_send_read_cmd(dev->controller,
READ_FLAG_STATUS_REG_CMD,
&flag_status_reg,
FLAG_STATUS_REG_LEN,
ARG_NOT_USED,
ARG_NOT_USED,
0); /* No dummy cycles
needed for this
command. */
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
}
return MT25QL_ERR_NONE;
}
/**
* \brief Execute a program command that crosses the page size boundary.
*
* \param[in] dev Pointer to MT25QL device structure
* \ref mt25ql_dev_t
* \param[in] opcode Opcode for the command.
* \param[in] write_data Pointer to a memory zone where the write_len
* number of bytes are located to write for this
* command.
* \param[in] write_len Number of bytes to write for the command.
* Between 1 and 8 bytes (both included) can be
* written.
* \param[in] addr Address used for the command
* \param[in] addr_bytes_number Number of address bytes for this command.
* If an address is not needed for the command,
* use 0 for argument, otherwise between 1 and
* 4 bytes (both included) can be used.
* \param[in] dummy_cycles Number of dummy cycles required for the
* command, between 0 and 31 (both included).
*
* \return Return error code as specified in \ref mt25ql_error_t
*
* \note This function will execute two commands: one to program the bytes up to
* the page boundary and another one to program the rest. It will wait
* that bytes are programmed from first command before triggering the
* second one.
* \note This function does not send a write enable command before the first
* command and does not check that bytes were programmed after the second
* command.
*/
static enum mt25ql_error_t send_boundary_cross_write_cmd(
struct mt25ql_dev_t* dev,
uint8_t opcode,
const void *write_data,
uint32_t write_len,
uint32_t addr,
uint32_t addr_bytes_number,
uint32_t dummy_cycles)
{
enum qspi_ip6514e_error_t controller_error;
enum mt25ql_error_t library_error;
/*
* Remaining bytes between the current address and the end of the current
* page.
*/
uint32_t page_remainder = FLASH_PAGE_SIZE - (addr % FLASH_PAGE_SIZE);
/* First write up to the end of the current page. */
controller_error = qspi_ip6514e_send_write_cmd(dev->controller, opcode,
write_data, page_remainder,
addr, addr_bytes_number,
dummy_cycles);
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
write_data = (void *)((uint32_t)write_data + page_remainder);
addr += page_remainder;
/* Wait for the page to be written before sending new commands. */
library_error = wait_program_or_erase_complete(dev);
if (library_error != MT25QL_ERR_NONE) {
return library_error;
}
/* Then write the remaining data of the write_len bytes. */
send_write_enable(dev);
controller_error = qspi_ip6514e_send_write_cmd(dev->controller, opcode,
write_data,
write_len - page_remainder,
addr, addr_bytes_number,
dummy_cycles);
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
return MT25QL_ERR_NONE;
}
enum mt25ql_error_t mt25ql_config_mode(struct mt25ql_dev_t* dev,
enum mt25ql_functional_state_t f_state)
{
enum qspi_ip6514e_error_t controller_error;
enum mt25ql_error_t library_error;
switch(f_state) {
case MT25QL_FUNC_STATE_DEFAULT:
dev->config_state.spi_mode = QSPI_IP6514E_SPI_MODE;
dev->config_state.opcode_read = READ_CMD;
dev->config_state.dummy_cycles_read = DEFAULT_READ_DUMMY_CYCLES;
dev->config_state.opcode_write = PAGE_PROGRAM_CMD;
dev->config_state.dummy_cycles_write = PAGE_PROGRAM_DUMMY_CYCLES;
break;
case MT25QL_FUNC_STATE_FAST:
dev->config_state.spi_mode = QSPI_IP6514E_SPI_MODE;
dev->config_state.opcode_read = FAST_READ_CMD;
dev->config_state.dummy_cycles_read = FAST_READ_DUMMY_CYCLES;
dev->config_state.opcode_write = PAGE_PROGRAM_CMD;
dev->config_state.dummy_cycles_write = PAGE_PROGRAM_DUMMY_CYCLES;
break;
case MT25QL_FUNC_STATE_QUAD_FAST:
dev->config_state.spi_mode = QSPI_IP6514E_QSPI_MODE;
dev->config_state.opcode_read = QUAD_OUTPUT_FAST_READ_CMD;
dev->config_state.dummy_cycles_read =
QUAD_OUTPUT_FAST_READ_DUMMY_CYCLES;
dev->config_state.opcode_write = QUAD_INPUT_FAST_PROGRAM_CMD;
dev->config_state.dummy_cycles_write =
QUAD_INPUT_FAST_PROGRAM_DUMMY_CYCLES;
break;
default:
return MT25QL_ERR_WRONG_ARGUMENT;
}
dev->config_state.func_state = f_state;
/* This function will first set the Flash memory SPI mode and then set
* the controller's SPI mode. It will fail if the two sides do not have
* the same mode when this function is called.
*/
library_error = set_spi_mode(dev, dev->config_state.spi_mode);
if (library_error != MT25QL_ERR_NONE) {
return library_error;
}
/* Set the number of dummy cycles for read commands. */
library_error = change_dummy_cycles(
dev, dev->config_state.dummy_cycles_read);
if (library_error != MT25QL_ERR_NONE) {
return library_error;
}
/* The rest of the configuration needs the controller to be disabled */
while(!qspi_ip6514e_is_idle(dev->controller));
qspi_ip6514e_disable(dev->controller);
/* Set the baud rate divisor as configured in the device structure. */
controller_error = qspi_ip6514e_set_baud_rate_div(dev->controller,
dev->baud_rate_div);
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
/* Set opcode and dummy cycles needed for read commands. */
controller_error = qspi_ip6514e_cfg_reads(
dev->controller, dev->config_state.opcode_read,
dev->config_state.dummy_cycles_read);
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
/* Set opcode and dummy cycles needed for write commands. */
controller_error = qspi_ip6514e_cfg_writes(
dev->controller, dev->config_state.opcode_write,
dev->config_state.dummy_cycles_write);
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
/* Set Flash memory constants: bytes per page and address bytes. */
controller_error = qspi_ip6514e_cfg_page_size(dev->controller,
FLASH_PAGE_SIZE);
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
controller_error = qspi_ip6514e_cfg_addr_bytes(dev->controller,
ADDR_BYTES);
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
qspi_ip6514e_enable(dev->controller);
return MT25QL_ERR_NONE;
}
enum mt25ql_error_t mt25ql_restore_reset_state(struct mt25ql_dev_t* dev)
{
enum mt25ql_error_t library_error;
/*
* This function will first change the Flash memory mode to single SPI and
* then change the controller to single SPI. It will fail if the two sides
* do not have the same mode when this function is called.
*/
library_error = set_spi_mode(dev, QSPI_IP6514E_SPI_MODE);
if (library_error != MT25QL_ERR_NONE) {
return library_error;
}
/* Set the default number of dummy cycles for direct read commands. */
library_error = change_dummy_cycles(dev, RESET_STATE_DUMMY_CYCLES);
if (library_error != MT25QL_ERR_NONE) {
return library_error;
}
/* The rest of the configuration needs the controller to be disabled */
while(!qspi_ip6514e_is_idle(dev->controller));
qspi_ip6514e_disable(dev->controller);
/* Restore the default value of the QSPI controller registers. */
qspi_ip6514e_reset_regs(dev->controller);
qspi_ip6514e_enable(dev->controller);
dev->config_state = (struct mt25ql_config_state_t){ 0 };
dev->config_state.func_state = MT25QL_FUNC_STATE_NOT_INITED;
return MT25QL_ERR_NONE;
}
enum mt25ql_error_t mt25ql_direct_read(struct mt25ql_dev_t* dev,
uint32_t addr,
void *data,
uint32_t len)
{
/*
* The direct access window size is the size of the memory that can be
* accessed with a direct access.
*/
uint32_t direct_access_window_size = dev->controller->cfg->addr_mask + 1;
/*
* The window number is the number of times it will be needed to remap the
* address with the remap register. We move this Direct Access window first
* window_number times starting at the beginning address to read full
* windows of direct_access_window_size bytes. Then we read the remainder
* bytes.
*/
uint32_t window_number = len / direct_access_window_size;
if (data == NULL || len == 0) {
return MT25QL_ERR_WRONG_ARGUMENT;
}
if ((addr + len) >= dev->size) {
return MT25QL_ERR_ADDR_TOO_BIG;
}
/*
* There is no limitation reading through a Flash page boundary hence we
* do not add the same logic here than in the write function.
*/
/* Transfer the bytes for the window_number windows first. */
for (uint32_t window = 0; window < window_number; window++) {
qspi_ip6514e_remap_addr(dev->controller, addr);
/*
* The AHB address to access the Flash memory does not change but it
* will be translated differently thanks to the remap function.
*/
memcpy(data,
(void *)dev->direct_access_start_addr,
direct_access_window_size);
len -= direct_access_window_size;
data = (void *)((uint32_t)data + direct_access_window_size);
addr += direct_access_window_size;
}
if (len) {
/* Transfer the reminder bytes */
qspi_ip6514e_remap_addr(dev->controller, addr);
memcpy(data, (void *)dev->direct_access_start_addr, len);
}
/* Disable remapping for direct accesses outside of this function. */
qspi_ip6514e_disable_remap(dev->controller);
return MT25QL_ERR_NONE;
}
enum mt25ql_error_t mt25ql_direct_write(struct mt25ql_dev_t* dev,
uint32_t addr,
const void *data,
uint32_t len)
{
enum mt25ql_error_t library_error;
/*
* The direct access window size is the size of the memory that can be
* accessed with a direct access.
*/
uint32_t direct_access_window_size = dev->controller->cfg->addr_mask + 1;
uint32_t window_number;
/* Offset between address and the previous 32 bits aligned word */
uint32_t word_offset;
if (data == NULL || len == 0) {
return MT25QL_ERR_WRONG_ARGUMENT;
}
if ((addr + len) >= dev->size) {
return MT25QL_ERR_ADDR_TOO_BIG;
}
/*
* If the remapping address is not aligned on a 32 bits boundary, a direct
* access of one word could cross a Flash page boundary. If that happens,
* the bytes of that word that are over the page boundary will instead be
* written at the beginning of the same page.
* To counter this problem, we align the remapping address and add the word
* offset to the address of the direct access for the first window only.
*/
word_offset = addr % BYTES_PER_WORD;
/* Make address aligned on a 32 bits alignment. */
addr -= word_offset;
/*
* Only direct_access_window_size address locations are available by direct
* access. We calculate the number of windows that we will need to transfer
* len bytes. We have to add in the window the offset that we add in the
* beginning.
*/
window_number = (len + word_offset) / direct_access_window_size;
/*
* This function assumes that the flash has already been erased.
* Transfer the bytes for the window_number windows first.
*/
for (uint32_t window = 0; window < window_number; window++) {
/* The controller needs to be disabled while remapping is done. */
qspi_ip6514e_remap_addr(dev->controller, addr);
/*
* The AHB address to access the Flash memory does not change but it
* will be translated differently thanks to the remap function.
*/
memcpy((void *)(dev->direct_access_start_addr + word_offset),
data,
direct_access_window_size - word_offset);
len -= (direct_access_window_size - word_offset);
data = (void *)((uint32_t)data +
(direct_access_window_size - word_offset));
addr += direct_access_window_size;
/*
* The address is now aligned, there is no need to add an offset for the
* remaining windows.
*/
word_offset = 0;
/*
* Wait until the last program operation is complete before changing
* the remap address.
*/
library_error = wait_program_or_erase_complete(dev);
if (library_error != MT25QL_ERR_NONE) {
return library_error;
}
}
if (len) {
/* Transfer the reminder bytes */
qspi_ip6514e_remap_addr(dev->controller, addr);
memcpy((void *)(dev->direct_access_start_addr + word_offset),
data,
len);
/* Wait until the last program operation is complete */
library_error = wait_program_or_erase_complete(dev);
if (library_error != MT25QL_ERR_NONE) {
return library_error;
}
}
/*
* Disable the default remap address for direct accesses outside of this
* function.
*/
qspi_ip6514e_disable_remap(dev->controller);
return MT25QL_ERR_NONE;
}
enum mt25ql_error_t mt25ql_command_read(struct mt25ql_dev_t* dev,
uint32_t addr,
void *data,
uint32_t len)
{
/* With one single command only 8 bytes can be read. */
uint32_t cmd_number = len / CMD_DATA_MAX_SIZE;
enum qspi_ip6514e_error_t controller_error;
if (dev->config_state.func_state == MT25QL_FUNC_STATE_NOT_INITED) {
return MT25QL_ERR_NOT_INITED;
}
for (uint32_t cmd_index = 0; cmd_index < cmd_number; cmd_index++) {
controller_error = qspi_ip6514e_send_read_cmd(
dev->controller,
dev->config_state.opcode_read,
data, CMD_DATA_MAX_SIZE, addr,
ADDR_BYTES,
dev->config_state.dummy_cycles_read);
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
data = (void *)((uint32_t)data + CMD_DATA_MAX_SIZE);
addr += CMD_DATA_MAX_SIZE;
len -= CMD_DATA_MAX_SIZE;
}
if (len) {
/* Read the remainder. */
controller_error = qspi_ip6514e_send_read_cmd(
dev->controller,
dev->config_state.opcode_read,
data, len, addr, ADDR_BYTES,
dev->config_state.dummy_cycles_read);
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
}
return MT25QL_ERR_NONE;
}
enum mt25ql_error_t mt25ql_command_write(struct mt25ql_dev_t* dev,
uint32_t addr,
const void *data,
uint32_t len)
{
/* With one single command only 8 bytes can be written. */
uint32_t cmd_number = len / CMD_DATA_MAX_SIZE;
enum qspi_ip6514e_error_t controller_error;
enum mt25ql_error_t library_error;
if (dev->config_state.func_state == MT25QL_FUNC_STATE_NOT_INITED) {
return MT25QL_ERR_NOT_INITED;
}
for (uint32_t cmd_index = 0; cmd_index < cmd_number; cmd_index++) {
send_write_enable(dev);
/*
* Check if this command is not writing over a page boundary: first and
* last bytes are in the same page.
*/
if ((addr / FLASH_PAGE_SIZE) !=
((addr + CMD_DATA_MAX_SIZE - 1) / FLASH_PAGE_SIZE)) {
/* The CMD_DATA_MAX_SIZE bytes written are crossing the boundary. */
library_error = send_boundary_cross_write_cmd(
dev, dev->config_state.opcode_write,
data, CMD_DATA_MAX_SIZE, addr,
ADDR_BYTES,
dev->config_state.dummy_cycles_write);
if (library_error != MT25QL_ERR_NONE) {
return library_error;
}
} else {
/* Normal case: not crossing the boundary. */
controller_error = qspi_ip6514e_send_write_cmd(
dev->controller,
dev->config_state.opcode_write,
data, CMD_DATA_MAX_SIZE, addr,
ADDR_BYTES,
dev->config_state.dummy_cycles_write);
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
}
/* Wait until the write operation is complete. */
library_error = wait_program_or_erase_complete(dev);
if (library_error != MT25QL_ERR_NONE) {
return library_error;
}
data = (void *)((uint32_t)data + CMD_DATA_MAX_SIZE);
addr += CMD_DATA_MAX_SIZE;
len -= CMD_DATA_MAX_SIZE;
}
if (len) {
/* Write the remainder. */
send_write_enable(dev);
/*
* Check if this command is not writing over a page boundary: first and
* last bytes are in the same page.
*/
if ((addr / FLASH_PAGE_SIZE) != ((addr + len - 1) / FLASH_PAGE_SIZE)) {
/* The CMD_DATA_MAX_SIZE bytes written are crossing the boundary. */
library_error = send_boundary_cross_write_cmd(
dev, dev->config_state.opcode_write,
data, len, addr, ADDR_BYTES,
dev->config_state.dummy_cycles_write);
if (library_error != MT25QL_ERR_NONE) {
return library_error;
}
} else {
/* Normal case: not crossing the boundary. */
controller_error = qspi_ip6514e_send_write_cmd(
dev->controller,
dev->config_state.opcode_write,
data, len, addr, ADDR_BYTES,
dev->config_state.dummy_cycles_write);
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
}
/* Wait until the write operation is complete. */
library_error = wait_program_or_erase_complete(dev);
if (library_error != MT25QL_ERR_NONE) {
return library_error;
}
}
return MT25QL_ERR_NONE;
}
enum mt25ql_error_t mt25ql_erase(struct mt25ql_dev_t* dev,
uint32_t addr,
enum mt25ql_erase_t erase_type)
{
enum qspi_ip6514e_error_t controller_error;
enum mt25ql_error_t library_error;
uint8_t erase_cmd;
uint32_t addr_bytes;
if (dev->config_state.func_state == MT25QL_FUNC_STATE_NOT_INITED) {
return MT25QL_ERR_NOT_INITED;
}
send_write_enable(dev);
switch (erase_type) {
case MT25QL_ERASE_ALL_FLASH:
if (addr != 0) {
return MT25QL_ERR_ADDR_NOT_ALIGNED;
}
erase_cmd = BULK_ERASE_CMD;
addr_bytes = ARG_NOT_USED;
break;
case MT25QL_ERASE_SECTOR_64K:
erase_cmd = SECTOR_ERASE_CMD;
addr_bytes = ADDR_BYTES;
if ((addr % SECTOR_64KB) != 0) {
return MT25QL_ERR_ADDR_NOT_ALIGNED;
}
break;
case MT25QL_ERASE_SUBSECTOR_32K:
erase_cmd = SUBSECTOR_ERASE_32KB_CMD;
addr_bytes = ADDR_BYTES;
if ((addr % SUBSECTOR_32KB) != 0) {
return MT25QL_ERR_ADDR_NOT_ALIGNED;
}
break;
case MT25QL_ERASE_SUBSECTOR_4K:
erase_cmd = SUBSECTOR_ERASE_4KB_CMD;
addr_bytes = ADDR_BYTES;
if ((addr % SUBSECTOR_4KB) != 0) {
return MT25QL_ERR_ADDR_NOT_ALIGNED;
}
break;
default:
return MT25QL_ERR_WRONG_ARGUMENT;
}
if (addr >= dev->size) {
return MT25QL_ERR_ADDR_TOO_BIG;
}
controller_error = qspi_ip6514e_send_cmd(dev->controller,
erase_cmd,
ARG_PTR_NOT_USED,
ARG_NOT_USED,
ARG_PTR_NOT_USED,
ARG_NOT_USED,
addr,
addr_bytes,
0); /* No dummy cycles needed for
any erase command. */
if (controller_error != QSPI_IP6514E_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
/* Wait until the erase operation is complete */
library_error = wait_program_or_erase_complete(dev);
if (library_error != MT25QL_ERR_NONE) {
return (enum mt25ql_error_t)controller_error;
}
return MT25QL_ERR_NONE;
}

View File

@ -0,0 +1,273 @@
/*
* Copyright (c) 2018-2019 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This library provides functions to control the MT25QL256ABA-1EW7-OSIT flash
* memory from Micron and should work for similar devices from the same vendor.
*/
#ifndef __MT25QL_H__
#define __MT25QL_H__
#include "qspi_ip6514e_drv.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MT25QL Flash Memory documentation defined values.
*/
#define FLASH_PAGE_SIZE (256U) /* 256B */
#define SUBSECTOR_4KB (0x00001000U) /* 4KB */
#define SUBSECTOR_32KB (0x00008000U) /* 32KB */
#define SECTOR_64KB (0x00010000U) /* 64KB */
#define ADDR_BYTES (3U)
enum mt25ql_error_t {
MT25QL_ERR_NONE = QSPI_IP6514E_ERR_NONE,
MT25QL_ERR_WRONG_ARGUMENT = QSPI_IP6514E_ERR_WRONG_ARGUMENT,
MT25QL_ERR_CTRL_NOT_DISABLED = QSPI_IP6514E_ERR_CONTROLLER_NOT_DISABLED,
MT25QL_ERR_READ_IN_PROGRESS = QSPI_IP6514E_ERR_READ_IN_PROGRESS,
MT25QL_ERR_WRITE_IN_PROGRESS = QSPI_IP6514E_ERR_WRITE_IN_PROGRESS,
MT25QL_ERR_ADDR_NOT_ALIGNED,
MT25QL_ERR_NOT_INITED,
MT25QL_ERR_ADDR_TOO_BIG,
};
enum mt25ql_erase_t {
MT25QL_ERASE_ALL_FLASH = 0U, /*!< Erase all flash */
MT25QL_ERASE_SUBSECTOR_4K = SUBSECTOR_4KB, /*!< Erase a 4 KB subsector */
MT25QL_ERASE_SUBSECTOR_32K = SUBSECTOR_32KB, /*!< Erase a 32 KB subsector */
MT25QL_ERASE_SECTOR_64K = SECTOR_64KB, /*!< Erase a sector (64 KB) */
};
enum mt25ql_functional_state_t {
MT25QL_FUNC_STATE_NOT_INITED = 0U,
/*!< QSPI Flash controller is not initialized, only direct read
* is guaranteed to be working
*/
MT25QL_FUNC_STATE_DEFAULT = 1U,
/*!< The QSPI Flash controller and memory is in default state,
* using basic read/write commands
*/
MT25QL_FUNC_STATE_FAST = 2U,
/*!< The QSPI Flash controller and memory is configured to operate in
* single SPI mode and fast Flash commands could be used for read and
* program operations.
*/
MT25QL_FUNC_STATE_QUAD_FAST = 3U,
/*!< The QSPI Flash controller and memory is configured to operate in
* Quad SPI mode and fast Flash commands could be used for read and
* program operations.
*/
};
struct mt25ql_config_state_t {
enum mt25ql_functional_state_t func_state;
/*!< Functional state id */
enum qspi_ip6514e_spi_mode_t spi_mode;
/*!< SPI mode for the current functional state */
uint8_t opcode_read;
/*!< Read opcode for the current functional state */
uint8_t opcode_write;
/*!< Write opcode for the current functional state */
uint32_t dummy_cycles_read;
/*!< Dummy cycles for the read command for the current functional state */
uint32_t dummy_cycles_write;
/*!< Dummy cycles for the write command for the current functional state */
};
struct mt25ql_dev_t {
struct qspi_ip6514e_dev_t *controller;
/*!< QSPI Flash controller. */
uint32_t direct_access_start_addr;
/*!< AHB address to directly access the contents of the Flash memory
* through the QSPI Controller.
*/
uint32_t baud_rate_div;
/*!< Clock divisor that will be used to configure the QSPI Flash
* Controller to access the Flash memory. The clock which frequency is
* divived is the one linked to the QSPI Flash controller. It can only
* be an even number between 2 and 32 (both included). It needs to be
* high enough to support the Quad Output Fast Read command with 8
* dummy cycles and the Quad Input Fast Program with 0 dummy cycles.
*/
uint32_t size; /*!< Total size of the MT25QL Flash memory */
struct mt25ql_config_state_t config_state;
/*!< Configured functional state (with parameter settings) of the
* QSPI Flash controller and memory.
*/
};
/**
* \brief Change configuration of the QSPI Flash controller and MT25QL memory
*
* Changes the configuration of the QSPI Flash controller and MT25QL
* Flash memory to operate in the specified SPI mode and to use the
* appropriate Flash commands for read and program operations.
* It also sets:
* + The number of dummy cycles for each operation
* + The bytes per page constant to 256 (MT25QL Flash specific)
* + The number of address bytes to 3
*
* \param[in] dev Pointer to MT25QL device structure \ref mt25ql_dev_t
* \param[in] f_state Functional state to be set on flash controller
* and device \ref mt25ql_functional_state_t
*
* \return Return error code as specified in \ref mt25ql_error_t
*
* \note This function assumes that the Flash memory device and the QSPI Flash
* controller operates with the same SPI protocol. This function will fail
* if the Flash device is in a different configuration.
*/
enum mt25ql_error_t mt25ql_config_mode(struct mt25ql_dev_t* dev,
enum mt25ql_functional_state_t f_state);
/**
* \brief Restore the QSPI Flash controller and MT25QL to reset state.
*
* \param[in] dev Pointer to MT25QL device structure \ref mt25ql_dev_t
*
* \return Return error code as specified in \ref mt25ql_error_t
*
* \note This function assumes that the Flash memory device and the QSPI Flash
* controller operates with the same SPI protocol. This function will fail
* if the Flash device is in a different configuration.
*/
enum mt25ql_error_t mt25ql_restore_reset_state(struct mt25ql_dev_t* dev);
/**
* \brief Read bytes from the flash memory (direct access)
*
* \param[in] dev Pointer to MT25QL device structure \ref mt25ql_dev_t
* \param[in] addr Flash memory address for the read operation
* \param[out] data Pointer where len bytes read from the flash memory will be
* written to
* \param[in] len Number of bytes to read
*
* \return Return error code as specified in \ref mt25ql_error_t
*
* \note This function will use direct access to read from the Flash memory. It
* can be used to access above the direct accessible memory zone if
* not all the AHB address wires are connected.
* \note The address given should be the address of the data inside the flash
* memory. To read the first byte inside the memory, use 0x00000000.
*/
enum mt25ql_error_t mt25ql_direct_read(struct mt25ql_dev_t* dev,
uint32_t addr,
void *data,
uint32_t len);
/**
* \brief Write bytes in the flash memory, at a location where data has already
* been erased (direct access)
*
* \param[in] dev Pointer to MT25QL device structure \ref mt25ql_dev_t
* \param[in] addr Flash memory address for the write operation
* \param[in] data Pointer to the len bytes that will be written to the flash
* memory
* \param[in] len Number of bytes to write
*
* \return Return error code as specified in \ref mt25ql_error_t
*
* \note This function will use direct access to write to the Flash memory. It
* can be used to access outside of the direct accessible memory zone if
* not all the AHB address wires are connected.
* \note The address given should be the address of the data inside the flash
* memory. To write the first byte inside the memory, use 0x00000000.
* \note Writing bytes in the flash memory clear them from 1 to 0, for that
* matter the location where data is written needs to be erased
* beforehand.
*/
enum mt25ql_error_t mt25ql_direct_write(struct mt25ql_dev_t* dev,
uint32_t addr,
const void *data,
uint32_t len);
/**
* \brief Read bytes from the flash memory (using Flash commands)
*
* \param[in] dev Pointer to MT25QL device structure \ref mt25ql_dev_t
* \param[in] addr Flash memory address for the read operation
* \param[out] data Pointer where len bytes read from the flash memory will be
* written to
* \param[in] len Number of bytes to read
*
* \return Return error code as specified in \ref mt25ql_error_t
*
* \note This function will use the Software Triggered Instruction Generator to
* read from the Flash memory using Flash commands.
* \note The address given should be the address of the data inside the flash
* memory. To read the first byte inside the memory, use 0x00000000.
*/
enum mt25ql_error_t mt25ql_command_read(struct mt25ql_dev_t* dev,
uint32_t addr,
void *data,
uint32_t len);
/**
* \brief Write bytes in the flash memory, at a location where data has already
* been erased (using Flash commands)
*
* \param[in] dev Pointer to MT25QL device structure \ref mt25ql_dev_t
* \param[in] addr Flash memory address for the write operation
* \param[in] data Pointer to the len bytes that will be written to the flash
* memory
* \param[in] len Number of bytes to write
*
* \return Return error code as specified in \ref mt25ql_error_t
*
* \note This function will use the Software Triggered Instruction Generator to
* write to the Flash memory using Flash commands.
* \note The address given should be the address of the data inside the flash
* memory. To write the first byte inside the memory, use 0x00000000.
* \note Writing bytes in the flash memory clear them from 1 to 0, for that
* matter the location where data is written needs to be erased
* beforehand.
*/
enum mt25ql_error_t mt25ql_command_write(struct mt25ql_dev_t* dev,
uint32_t addr,
const void *data,
uint32_t len);
/**
* \brief Erase all flash memory, a sector (64 KiB) or a subsector
* (32 KiB or 4 KiB)
*
* \param[in] dev Pointer to MT25QL device structure \ref mt25ql_dev_t
* \param[in] addr Address where to erase in the flash memory
* \param[in] erase_type Type of what to erase at the specified address:
* * whole flash memory
* * a subsector (4 KiB or 32 KiB)
* * a sector (64 KiB)
* \return Return error code as specified in \ref mt25ql_error_t
*
* \note The address need to be aligned with the size of what is erased or 0 if
* all flash memory is to be erased.
*/
enum mt25ql_error_t mt25ql_erase(struct mt25ql_dev_t* dev,
uint32_t addr,
enum mt25ql_erase_t erase_type);
#ifdef __cplusplus
}
#endif
#endif /* __MT25QL_H__ */

View File

@ -0,0 +1,49 @@
/* mbed Microcontroller Library
* Copyright (c) 2019-2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PERIPHERALNAMES_H
#define MBED_PERIPHERALNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
UART_0 = 0,
UART_1
} UARTName;
typedef enum {
I2C_0 = 0,
I2C_1
} I2CName;
#define STDIO_UART_TX UART1_TX
#define STDIO_UART_RX UART1_RX
#define STDIO_UART UART_1
#define USBTX STDIO_UART_TX
#define USBRX STDIO_UART_RX
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,117 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PINNAMES_H
#define MBED_PINNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PIN_INPUT,
PIN_OUTPUT
} PinDirection;
typedef enum {
PA0 = 0,
PA1 = 1,
PA2 = 2,
PA3 = 3,
PA4 = 4,
PA5 = 5,
PA6 = 6,
PA7 = 7,
PA8 = 8,
PA9 = 9,
PA10 = 10,
PA11 = 11,
PA12 = 12,
PA13 = 13,
PA14 = 14,
PA15 = 15,
PA16 = 16,
PA17 = 17,
PA18 = 18,
PA19 = 19,
PA20 = 20,
PA21 = 21,
PA22 = 22,
PA23 = 23,
PA24 = 24,
PA25 = 25,
/* Arduino Connector Namings */
D0 = PA0,
D1 = PA1,
D2 = PA2,
D3 = PA3,
D4 = PA4,
D5 = PA5,
D6 = PA6,
D7 = PA7,
D8 = PA8,
D9 = PA9,
D10 = PA10,
D11 = PA11,
D12 = PA12,
D13 = PA13,
D14 = PA14,
D15 = PA15,
/* UART pins */
UART0_RX = PA0, /* Alternate Function - 1 */
UART0_TX = PA1, /* Alternate Function - 1 */
UART1_RX = PA16,
UART1_TX = PA17,
LED1 = PA2,
LED2 = PA3,
LED3 = PA4,
/* I2C pins */
I2C0_SDA = PA14, /* Alternate Function - 1 */
I2C0_SCL = PA15, /* Alternate Function - 1 */
I2C1_SDA = PA18,
I2C1_SCL = PA19,
/* Not connected */
NC = (int)0xFFFFFFFF
} PinName;
typedef enum {
PRIMARY_FUNC = 0,
ALTERNATE_FUNC_1 = 1,
ALTERNATE_FUNC_2 = 2
} PinFunction;
typedef enum {
PullNone = 0,
PullUp,
PullDown,
PullDefault = PullNone
} PinMode;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,24 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_DEVICE_H
#define MBED_DEVICE_H
#include "objects.h"
#endif

View File

@ -0,0 +1,68 @@
#! armclang --target=arm-arm-none-eabi -march=armv8-m.main -E -xc
/*
* Copyright (c) 2019-2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "../../partition/region_defs.h"
#include "../cmsis_nvic.h"
#if !defined(MBED_ROM_START)
#define MBED_ROM_START NS_CODE_START // 0x0A080400
#endif
#if !defined(MBED_ROM_SIZE)
#define MBED_ROM_SIZE NS_CODE_SIZE // 0x7f400
#endif
#if !defined(MBED_RAM_START)
#define MBED_RAM_START NS_DATA_START // 0x20040000
#endif
#if !defined(MBED_RAM_SIZE)
#define MBED_RAM_SIZE NS_DATA_SIZE // 0x40000
#endif
#define VECTOR_SIZE NVIC_RAM_VECTOR_SIZE
#if !defined(MBED_CONF_TARGET_BOOT_STACK_SIZE)
# if defined(MBED_BOOT_STACK_SIZE)
# define MBED_CONF_TARGET_BOOT_STACK_SIZE MBED_BOOT_STACK_SIZE
# else
# define MBED_CONF_TARGET_BOOT_STACK_SIZE 0x400
# endif
#endif
#define RAM_FIXED_SIZE (MBED_CONF_TARGET_BOOT_STACK_SIZE+VECTOR_SIZE)
LR_CODE MBED_ROM_START MBED_ROM_SIZE {
ER_CODE MBED_ROM_START MBED_ROM_SIZE {
*.o (VECTOR +First)
.ANY (+RO)
}
RW_IRAM1 (MBED_RAM_START+VECTOR_SIZE) (MBED_RAM_SIZE-VECTOR_SIZE) {
* (+RW) ; RW data that gets copied from Flash to SRAM
* (+ZI) ; ZI data that gets initialised to zero in SRAM
}
ARM_LIB_HEAP AlignExpr(+0, 16) EMPTY (MBED_RAM_SIZE-RAM_FIXED_SIZE+MBED_RAM_START-AlignExpr(ImageLimit(RW_IRAM1), 16)) {
}
ARM_LIB_STACK (MBED_RAM_START+MBED_RAM_SIZE) EMPTY -MBED_CONF_TARGET_BOOT_STACK_SIZE { ; stack
}
}

View File

@ -0,0 +1,242 @@
;/*
; * Copyright (c) 2019-2020 Arm Limited
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Licensed under the Apache License, Version 2.0 (the "License");
; * you may not use this file except in compliance with the License.
; * You may obtain a copy of the License at
; *
; * http://www.apache.org/licenses/LICENSE-2.0
; *
; * Unless required by applicable law or agreed to in writing, software
; * distributed under the License is distributed on an "AS IS" BASIS,
; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; * See the License for the specific language governing permissions and
; * limitations under the License.
; */
;
; This file is derivative of CMSIS V5.01 startup_ARMv8MML.s
; Git SHA: 8a1d9d6ee18b143ae5befefa14d89fb5b3f99c75
;/*
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
;*/
; Vector Table Mapped to Address 0 at Reset
AREA VECTOR, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
IMPORT |Image$$ARM_LIB_STACK$$ZI$$Limit|
__Vectors ;Core Interrupts
DCD |Image$$ARM_LIB_STACK$$ZI$$Limit|; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
;SSE-200 Interrupts
DCD NS_WATCHDOG_RESET_IRQHandler ; 0: Non-Secure Watchdog Reset Request Interrupt
DCD NS_WATCHDOG_IRQHandler ; 1: Non-Secure Watchdog Interrupt
DCD S32K_TIMER_IRQHandler ; 2: S32K Timer Interrupt
DCD TIMER0_IRQHandler ; 3: CMSDK Timer 0 Interrupt
DCD TIMER1_IRQHandler ; 4: CMSDK Timer 1 Interrupt
DCD DUALTIMER_IRQHandler ; 5: CMSDK Dual Timer Interrupt
DCD MHU0_IRQHandler ; 6: Message Handling Unit 0 Interrupt
DCD MHU1_IRQHandler ; 7: Message Handling Unit 1 Interrupt
DCD CRYPTOCELL_IRQHandler ; 8: CryptoCell-312 Interrupt
DCD 0 ; 9: Reserved
DCD 0 ; 10: Reserved
DCD 0 ; 11: Reserved
DCD 0 ; 12: Reserved
DCD I_CACHE_INV_ERR_IRQHandler ; 13: Intsruction Cache Invalidation Interrupt
DCD 0 ; 14: Reserved
DCD SYS_PPU_IRQHandler ; 15: System PPU Interrupt
DCD CPU0_PPU_IRQHandler ; 16: CPU0 PPU Interrupt
DCD CPU1_PPU_IRQHandler ; 17: CPU1 PPU Interrupt
DCD CPU0_DGB_PPU_IRQHandler ; 18: CPU0 Debug PPU Interrupt
DCD CPU1_DGB_PPU_IRQHandler ; 19: CPU1 Debug PPU Interrupt
DCD CRYPTOCELL_PPU_IRQHandler ; 20: CryptoCell PPU Interrupt
DCD 0 ; 21: Reserved
DCD RAM0_PPU_IRQHandler ; 22: RAM 0 PPU Interrupt
DCD RAM1_PPU_IRQHandler ; 23: RAM 1 PPU Interrupt
DCD RAM2_PPU_IRQHandler ; 24: RAM 2 PPU Interrupt
DCD RAM3_PPU_IRQHandler ; 25: RAM 3 PPU Interrupt
DCD DEBUG_PPU_IRQHandler ; 26: Debug PPU Interrupt
DCD 0 ; 27: Reserved
DCD CPU0_CTI_IRQHandler ; 28: CPU0 CTI Interrupt
DCD CPU1_CTI_IRQHandler ; 29: CPU1 CTI Interrupt
DCD 0 ; 30: Reserved
DCD 0 ; 31: Reserved
;Expansion Interrupts
DCD 0 ; 32: Reserved
DCD GpTimer_IRQHandler ; 33: General Purpose Timer
DCD I2C0_IRQHandler ; 34: I2C0
DCD I2C1_IRQHandler ; 35: I2C1
DCD I2S_IRQHandler ; 36: I2S
DCD SPI_IRQHandler ; 37: SPI
DCD QSPI_IRQHandler ; 38: QSPI
DCD UART0_Rx_IRQHandler ; 39: UART0 receive FIFO interrupt
DCD UART0_Tx_IRQHandler ; 40: UART0 transmit FIFO interrupt
DCD UART0_RxTimeout_IRQHandler ; 41: UART0 receive timeout interrupt
DCD UART0_ModemStatus_IRQHandler ; 42: UART0 modem status interrupt
DCD UART0_Error_IRQHandler ; 43: UART0 error interrupt
DCD UART0_IRQHandler ; 44: UART0 interrupt
DCD UART1_Rx_IRQHandler ; 45: UART0 receive FIFO interrupt
DCD UART1_Tx_IRQHandler ; 46: UART0 transmit FIFO interrupt
DCD UART1_RxTimeout_IRQHandler ; 47: UART0 receive timeout interrupt
DCD UART1_ModemStatus_IRQHandler ; 48: UART0 modem status interrupt
DCD UART1_Error_IRQHandler ; 49: UART0 error interrupt
DCD UART1_IRQHandler ; 50: UART0 interrupt
DCD GPIO_0_IRQHandler ; 51: GPIO 0 interrupt
DCD GPIO_1_IRQHandler ; 52: GPIO 1 interrupt
DCD GPIO_2_IRQHandler ; 53: GPIO 2 interrupt
DCD GPIO_3_IRQHandler ; 54: GPIO 3 interrupt
DCD GPIO_4_IRQHandler ; 55: GPIO 4 interrupt
DCD GPIO_5_IRQHandler ; 56: GPIO 5 interrupt
DCD GPIO_6_IRQHandler ; 57: GPIO 6 interrupt
DCD GPIO_7_IRQHandler ; 58: GPIO 7 interrupt
DCD GPIO_8_IRQHandler ; 59: GPIO 8 interrupt
DCD GPIO_9_IRQHandler ; 60: GPIO 9 interrupt
DCD GPIO_10_IRQHandler ; 61: GPIO 10 interrupt
DCD GPIO_11_IRQHandler ; 62: GPIO 11 interrupt
DCD GPIO_12_IRQHandler ; 63: GPIO 12 interrupt
DCD GPIO_13_IRQHandler ; 64: GPIO 13 interrupt
DCD GPIO_14_IRQHandler ; 65: GPIO 14 interrupt
DCD GPIO_15_IRQHandler ; 66: GPIO 15 interrupt
DCD GPIO_Combined_IRQHandler ; 67: GPIO Combined interrupt
DCD PVT_IRQHandler ; 68: PVT sensor interrupt
DCD 0 ; 69: Reserved
DCD PWM_0_IRQHandler ; 70: PWM0 interrupt
DCD RTC_IRQHandler ; 71: RTC interrupt
DCD GpTimer1_IRQHandler ; 72: General Purpose Timer1
DCD GpTimer0_IRQHandler ; 73: General Purpose Timer0
DCD PWM_1_IRQHandler ; 74: PWM1 interrupt
DCD PWM_2_IRQHandler ; 75: PWM2 interrupt
DCD IOMUX_IRQHandler ; 76: IOMUX interrupt
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
; Reset Handler
AREA RESET, CODE, READONLY
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
End_Of_Main
B .
ALIGN 4
; Dummy Exception Handlers (infinite loops which can be modified)
MACRO
Default_Handler $handler_name
$handler_name PROC
EXPORT $handler_name [WEAK]
B .
ENDP
MEND
Default_Handler NMI_Handler
Default_Handler HardFault_Handler
Default_Handler MemManage_Handler
Default_Handler BusFault_Handler
Default_Handler UsageFault_Handler
Default_Handler SVC_Handler
Default_Handler DebugMon_Handler
Default_Handler PendSV_Handler
Default_Handler SysTick_Handler
Default_Handler NS_WATCHDOG_RESET_IRQHandler
Default_Handler NS_WATCHDOG_IRQHandler
Default_Handler S32K_TIMER_IRQHandler
Default_Handler TIMER0_IRQHandler
Default_Handler TIMER1_IRQHandler
Default_Handler DUALTIMER_IRQHandler
Default_Handler MHU0_IRQHandler
Default_Handler MHU1_IRQHandler
Default_Handler CRYPTOCELL_IRQHandler
Default_Handler I_CACHE_INV_ERR_IRQHandler
Default_Handler SYS_PPU_IRQHandler
Default_Handler CPU0_PPU_IRQHandler
Default_Handler CPU1_PPU_IRQHandler
Default_Handler CPU0_DGB_PPU_IRQHandler
Default_Handler CPU1_DGB_PPU_IRQHandler
Default_Handler CRYPTOCELL_PPU_IRQHandler
Default_Handler RAM0_PPU_IRQHandler
Default_Handler RAM1_PPU_IRQHandler
Default_Handler RAM2_PPU_IRQHandler
Default_Handler RAM3_PPU_IRQHandler
Default_Handler DEBUG_PPU_IRQHandler
Default_Handler CPU0_CTI_IRQHandler
Default_Handler CPU1_CTI_IRQHandler
Default_Handler GpTimer_IRQHandler
Default_Handler I2C0_IRQHandler
Default_Handler I2C1_IRQHandler
Default_Handler I2S_IRQHandler
Default_Handler SPI_IRQHandler
Default_Handler QSPI_IRQHandler
Default_Handler UART0_Rx_IRQHandler
Default_Handler UART0_Tx_IRQHandler
Default_Handler UART0_RxTimeout_IRQHandler
Default_Handler UART0_ModemStatus_IRQHandler
Default_Handler UART0_Error_IRQHandler
Default_Handler UART0_IRQHandler
Default_Handler UART1_Rx_IRQHandler
Default_Handler UART1_Tx_IRQHandler
Default_Handler UART1_RxTimeout_IRQHandler
Default_Handler UART1_ModemStatus_IRQHandler
Default_Handler UART1_Error_IRQHandler
Default_Handler UART1_IRQHandler
Default_Handler GPIO_0_IRQHandler
Default_Handler GPIO_1_IRQHandler
Default_Handler GPIO_2_IRQHandler
Default_Handler GPIO_3_IRQHandler
Default_Handler GPIO_4_IRQHandler
Default_Handler GPIO_5_IRQHandler
Default_Handler GPIO_6_IRQHandler
Default_Handler GPIO_7_IRQHandler
Default_Handler GPIO_8_IRQHandler
Default_Handler GPIO_9_IRQHandler
Default_Handler GPIO_10_IRQHandler
Default_Handler GPIO_11_IRQHandler
Default_Handler GPIO_12_IRQHandler
Default_Handler GPIO_13_IRQHandler
Default_Handler GPIO_14_IRQHandler
Default_Handler GPIO_15_IRQHandler
Default_Handler GPIO_Combined_IRQHandler
Default_Handler PVT_IRQHandler
Default_Handler PWM_0_IRQHandler
Default_Handler RTC_IRQHandler
Default_Handler GpTimer1_IRQHandler
Default_Handler GpTimer0_IRQHandler
Default_Handler PWM_1_IRQHandler
Default_Handler PWM_2_IRQHandler
Default_Handler IOMUX_IRQHandler
ALIGN
END

View File

@ -0,0 +1,197 @@
;/*
; * Copyright (c) 2019 ARM Limited
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Licensed under the Apache License, Version 2.0 (the "License");
; * you may not use this file except in compliance with the License.
; * You may obtain a copy of the License at
; *
; * http://www.apache.org/licenses/LICENSE-2.0
; *
; * Unless required by applicable law or agreed to in writing, software
; * distributed under the License is distributed on an "AS IS" BASIS,
; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; * See the License for the specific language governing permissions and
; * limitations under the License.
; *
; *
; * This file is derivative of CMSIS V5.00 gcc_arm.ld
; */
/* Linker script to configure memory regions. */
/* This file will be run trough the pre-processor. */
#include "../../partition/region_defs.h"
#include "../cmsis_nvic.h"
/* Stack size is 1K for Mbed-OS */
#if !defined(MBED_CONF_TARGET_BOOT_STACK_SIZE)
#define MBED_CONF_TARGET_BOOT_STACK_SIZE 0x400
#endif
MEMORY
{
FLASH (rx) : ORIGIN = NS_CODE_START, LENGTH = NS_CODE_SIZE
/* Vector table is copied to RAM, so RAM address needs to be adjusted */
RAM (rwx) : ORIGIN = NVIC_RAM_VECTOR_LIMIT, LENGTH = (NS_DATA_SIZE - NVIC_RAM_VECTOR_SIZE)
}
__stack_size__ = MBED_CONF_TARGET_BOOT_STACK_SIZE;
/* Library configurations */
GROUP(libgcc.a libc.a libm.a libnosys.a)
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
KEEP(*(.vectors))
__Vectors_End = .;
__Vectors_Size = __Vectors_End - __Vectors;
__end__ = .;
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* define etext2/data2_start/data2_end and
* define __STARTUP_COPY_MULTIPLE in startup_cmsdk_musca_ns.S */
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (DEFINED(__etext2) ? __etext2 : 0)
LONG (DEFINED(__data2_start__) ? __data2_start__ : 0)
LONG (DEFINED(__data2_start__) ? __data2_end__ - __data2_start__ : 0)
__copy_table_end__ = .;
} > FLASH
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_cmsdk_musca_ns.S */
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (DEFINED(__bss2_start__) ? __bss2_start__ : 0)
LONG (DEFINED(__bss2_start__) ? __bss2_end__ - __bss2_start__ : 0)
__zero_table_end__ = .;
} > FLASH
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
bss_size = __bss_end__ - __bss_start__;
.stack :
{
. = ALIGN(8);
__StackLimit = .;
KEEP(*(.stack*))
. += __stack_size__;
__StackTop = .;
} > RAM
PROVIDE(__stack = __StackTop);
.heap (COPY):
{
. = ALIGN(8);
__HeapBase = .;
__end__ = .;
end = __end__;
KEEP(*(.heap*))
. += (ORIGIN(RAM) + LENGTH(RAM) - .);
__HeapLimit = .;
__heap_limit = .; /* Add for _sbrk */
} > RAM
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackTop <= (NS_DATA_START + NS_DATA_SIZE), "RAM region overflowed")
}

View File

@ -0,0 +1,357 @@
;/*
; * Copyright (c) 2019-2020 Arm Limited
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Licensed under the Apache License, Version 2.0 (the "License");
; * you may not use this file except in compliance with the License.
; * You may obtain a copy of the License at
; *
; * http://www.apache.org/licenses/LICENSE-2.0
; *
; * Unless required by applicable law or agreed to in writing, software
; * distributed under the License is distributed on an "AS IS" BASIS,
; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; * See the License for the specific language governing permissions and
; * limitations under the License.
; *
; *
; * This file is derivative of CMSIS V5.00 startup_ARMCM33.S
; */
.syntax unified
.arch armv8-m.main
.section .vectors
.align 2
.globl __Vectors
__Vectors:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler */
.long HardFault_Handler /* Hard Fault Handler */
.long MemManage_Handler /* MPU Fault Handler */
.long BusFault_Handler /* Bus Fault Handler */
.long UsageFault_Handler /* Usage Fault Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long DebugMon_Handler /* Debug Monitor Handler */
.long 0 /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* Core interrupts */
.long NS_WATCHDOG_RESET_IRQHandler /* 0: Non-Secure Watchdog Reset Request Interrupt */
.long NS_WATCHDOG_IRQHandler /* 1: Non-Secure Watchdog Interrupt */
.long S32K_TIMER_IRQHandler /* 2: S32K Timer Interrupt */
.long TIMER0_IRQHandler /* 3: CMSDK Timer 0 Interrupt */
.long TIMER1_IRQHandler /* 4: CMSDK Timer 1 Interrupt */
.long DUALTIMER_IRQHandler /* 5: CMSDK Dual Timer Interrupt */
.long MHU0_IRQHandler /* 6: Message Handling Unit 0 Interrupt */
.long MHU1_IRQHandler /* 7: Message Handling Unit 1 Interrupt */
.long CRYPTOCELL_IRQHandler /* 8: CryptoCell-312 Interrupt */
.long 0 /* 9: Reserved */
.long 0 /* 10: Reserved */
.long 0 /* 11: Reserved */
.long 0 /* 12: Reserved */
.long I_CACHE_INV_ERR_IRQHandler /* 13: Intsruction Cache Invalidation Interrupt */
.long 0 /* 14: Reserved */
.long SYS_PPU_IRQHandler /* 15: System PPU Interrupt */
.long CPU0_PPU_IRQHandler /* 16: CPU0 PPU Interrupt */
.long CPU1_PPU_IRQHandler /* 17: CPU1 PPU Interrupt */
.long CPU0_DGB_PPU_IRQHandler /* 18: CPU0 Debug PPU Interrupt */
.long CPU1_DGB_PPU_IRQHandler /* 19: CPU1 Debug PPU Interrupt */
.long CRYPTOCELL_PPU_IRQHandler /* 20: CryptoCell PPU Interrupt */
.long 0 /* 21: Reserved */
.long RAM0_PPU_IRQHandler /* 22: RAM 0 PPU Interrupt */
.long RAM1_PPU_IRQHandler /* 23: RAM 1 PPU Interrupt */
.long RAM2_PPU_IRQHandler /* 24: RAM 2 PPU Interrupt */
.long RAM3_PPU_IRQHandler /* 25: RAM 3 PPU Interrupt */
.long DEBUG_PPU_IRQHandler /* 26: Debug PPU Interrupt */
.long 0 /* 27: Reserved */
.long CPU0_CTI_IRQHandler /* 28: CPU0 CTI Interrupt */
.long CPU1_CTI_IRQHandler /* 29: CPU1 CTI Interrupt */
.long 0 /* 30: Reserved */
.long 0 /* 31: Reserved */
/* External interrupts */
.long 0 /* 32: Reserved */
.long GpTimer_IRQHandler /* 33: General Purpose Timer */
.long I2C0_IRQHandler /* 34: I2C0 */
.long I2C1_IRQHandler /* 35: I2C1 */
.long I2S_IRQHandler /* 36: I2S */
.long SPI_IRQHandler /* 37: SPI */
.long QSPI_IRQHandler /* 38: QSPI */
.long UART0_Rx_IRQHandler /* 39: UART0 receive FIFO interrupt */
.long UART0_Tx_IRQHandler /* 40: UART0 transmit FIFO interrupt */
.long UART0_RxTimeout_IRQHandler /* 41: UART0 receive timeout interrupt */
.long UART0_ModemStatus_IRQHandler /* 42: UART0 modem status interrupt */
.long UART0_Error_IRQHandler /* 43: UART0 error interrupt */
.long UART0_IRQHandler /* 44: UART0 interrupt */
.long UART1_Rx_IRQHandler /* 45: UART1 receive FIFO interrupt */
.long UART1_Tx_IRQHandler /* 46: UART1 transmit FIFO interrupt */
.long UART1_RxTimeout_IRQHandler /* 47: UART1 receive timeout interrupt */
.long UART1_ModemStatus_IRQHandler /* 48: UART1 modem status interrupt */
.long UART1_Error_IRQHandler /* 49: UART1 error interrupt */
.long UART1_IRQHandler /* 50: UART1 interrupt */
.long GPIO_0_IRQHandler /* 51: GPIO 0 interrupt */
.long GPIO_1_IRQHandler /* 52: GPIO 1 interrupt */
.long GPIO_2_IRQHandler /* 53: GPIO 2 interrupt */
.long GPIO_3_IRQHandler /* 54: GPIO 3 interrupt */
.long GPIO_4_IRQHandler /* 55: GPIO 4 interrupt */
.long GPIO_5_IRQHandler /* 56: GPIO 5 interrupt */
.long GPIO_6_IRQHandler /* 57: GPIO 6 interrupt */
.long GPIO_7_IRQHandler /* 58: GPIO 7 interrupt */
.long GPIO_8_IRQHandler /* 59: GPIO 8 interrupt */
.long GPIO_9_IRQHandler /* 60: GPIO 9 interrupt */
.long GPIO_10_IRQHandler /* 61: GPIO 10 interrupt */
.long GPIO_11_IRQHandler /* 62: GPIO 11 interrupt */
.long GPIO_12_IRQHandler /* 63: GPIO 12 interrupt */
.long GPIO_13_IRQHandler /* 64: GPIO 13 interrupt */
.long GPIO_14_IRQHandler /* 65: GPIO 14 interrupt */
.long GPIO_15_IRQHandler /* 66: GPIO 15 interrupt */
.long GPIO_Combined_IRQHandler /* 67: GPIO Combined interrupt */
.long PVT_IRQHandler /* 68: PVT sensor interrupt */
.long 0 /* 69: Reserved */
.long PWM_0_IRQHandler /* 70: PWM0 interrupt */
.long RTC_IRQHandler /* 71: RTC interrupt */
.long GpTimer1_IRQHandler /* 72: General Purpose Timer0 */
.long GpTimer0_IRQHandler /* 73: General Purpose Timer1 */
.long PWM_1_IRQHandler /* 74: PWM1 interrupt */
.long PWM_2_IRQHandler /* 75: PWM2 interrupt */
.long IOMUX_IRQHandler /* 76: IOMUX interrupt */
.size __Vectors, . - __Vectors
.text
.thumb
.thumb_func
.align 2
.globl Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Firstly it copies data from read only memory to RAM. There are two schemes
* to copy. One can copy more than one sections. Another can only copy
* one section. The former scheme needs more instructions and read-only
* data to implement than the latter.
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
#ifdef __STARTUP_COPY_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of triplets, each of which specify:
* offset 0: LMA of start of a section to copy from
* offset 4: VMA of start of a section to copy to
* offset 8: size of the section to copy. Must be multiply of 4
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r4, =__copy_table_start__
ldr r5, =__copy_table_end__
.L_loop0:
cmp r4, r5
bge .L_loop0_done
ldr r1, [r4]
ldr r2, [r4, #4]
ldr r3, [r4, #8]
.L_loop0_0:
subs r3, #4
ittt ge
ldrge r0, [r1, r3]
strge r0, [r2, r3]
bge .L_loop0_0
adds r4, #12
b .L_loop0
.L_loop0_done:
#else
/* Single section scheme.
*
* The ranges of copy from/to are specified by following symbols
* __etext: LMA of start of the section to copy from. Usually end of text
* __data_start__: VMA of start of the section to copy to
* __data_end__: VMA of end of the section to copy to
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
.L_loop1:
cmp r2, r3
ittt lt
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt .L_loop1
#endif /*__STARTUP_COPY_MULTIPLE */
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
* There are two schemes too. One can clear multiple BSS sections. Another
* can only clear one section. The former is more size expensive than the
* latter.
*
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
* Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
*/
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of tuples specifying:
* offset 0: Start of a BSS section
* offset 4: Size of this BSS section. Must be multiply of 4
*/
ldr r3, =__zero_table_start__
ldr r4, =__zero_table_end__
.L_loop2:
cmp r3, r4
bge .L_loop2_done
ldr r1, [r3]
ldr r2, [r3, #4]
movs r0, 0
.L_loop2_0:
subs r2, #4
itt ge
strge r0, [r1, r2]
bge .L_loop2_0
adds r3, #8
b .L_loop2
.L_loop2_done:
#elif defined (__STARTUP_CLEAR_BSS)
/* Single BSS section scheme.
*
* The BSS section is specified by following symbols
* __bss_start__: start of the BSS section.
* __bss_end__: end of the BSS section.
*
* Both addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__bss_start__
ldr r2, =__bss_end__
movs r0, 0
.L_loop3:
cmp r1, r2
itt lt
strlt r0, [r1], #4
blt .L_loop3
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
#ifndef __NO_SYSTEM_INIT
bl SystemInit
#endif
#ifndef __START
#define __START _start
#endif
bl __START
.pool
.size Reset_Handler, . - Reset_Handler
/* Macro to define default handlers. */
.macro def_irq_handler handler_name
.align 1
.thumb_func
.weak \handler_name
\handler_name:
b \handler_name
.endm
def_irq_handler NMI_Handler
def_irq_handler HardFault_Handler
def_irq_handler MemManage_Handler
def_irq_handler BusFault_Handler
def_irq_handler UsageFault_Handler
def_irq_handler SVC_Handler
def_irq_handler DebugMon_Handler
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
/* Core interrupts */
def_irq_handler NS_WATCHDOG_RESET_IRQHandler /* 0: Non-Secure Watchdog Reset Request Interrupt */
def_irq_handler NS_WATCHDOG_IRQHandler /* 1: Non-Secure Watchdog Interrupt */
def_irq_handler S32K_TIMER_IRQHandler /* 2: S32K Timer Interrupt */
def_irq_handler TIMER0_IRQHandler /* 3: CMSDK Timer 0 Interrupt */
def_irq_handler TIMER1_IRQHandler /* 4: CMSDK Timer 1 Interrupt */
def_irq_handler DUALTIMER_IRQHandler /* 5: CMSDK Dual Timer Interrupt */
def_irq_handler MHU0_IRQHandler /* 6: Message Handling Unit 0 Interrupt */
def_irq_handler MHU1_IRQHandler /* 7: Message Handling Unit 1 Interrupt */
def_irq_handler CRYPTOCELL_IRQHandler /* 8: CryptoCell-312 Interrupt */
def_irq_handler I_CACHE_INV_ERR_IRQHandler /* 13: Intsruction Cache Invalidation Interrupt */
def_irq_handler SYS_PPU_IRQHandler /* 15: System PPU Interrupt */
def_irq_handler CPU0_PPU_IRQHandler /* 16: CPU0 PPU Interrupt */
def_irq_handler CPU1_PPU_IRQHandler /* 17: CPU1 PPU Interrupt */
def_irq_handler CPU0_DGB_PPU_IRQHandler /* 18: CPU0 Debug PPU Interrupt */
def_irq_handler CPU1_DGB_PPU_IRQHandler /* 19: CPU1 Debug PPU Interrupt */
def_irq_handler CRYPTOCELL_PPU_IRQHandler /* 20: CryptoCell PPU Interrupt */
def_irq_handler RAM0_PPU_IRQHandler /* 22: RAM 0 PPU Interrupt */
def_irq_handler RAM1_PPU_IRQHandler /* 23: RAM 1 PPU Interrupt */
def_irq_handler RAM2_PPU_IRQHandler /* 24: RAM 2 PPU Interrupt */
def_irq_handler RAM3_PPU_IRQHandler /* 25: RAM 3 PPU Interrupt */
def_irq_handler DEBUG_PPU_IRQHandler /* 26: Debug PPU Interrupt */
def_irq_handler CPU0_CTI_IRQHandler /* 28: CPU0 CTI Interrupt */
def_irq_handler CPU1_CTI_IRQHandler /* 29: CPU1 CTI Interrupt */
/* External interrupts */
def_irq_handler GpTimer_IRQHandler /* 33: General Purpose Timer */
def_irq_handler I2C0_IRQHandler /* 34: I2C0 */
def_irq_handler I2C1_IRQHandler /* 35: I2C1 */
def_irq_handler I2S_IRQHandler /* 36: I2S */
def_irq_handler SPI_IRQHandler /* 37: SPI */
def_irq_handler QSPI_IRQHandler /* 38: QSPI */
def_irq_handler UART0_Rx_IRQHandler /* 39: UART0 receive FIFO interrupt */
def_irq_handler UART0_Tx_IRQHandler /* 40: UART0 transmit FIFO interrupt */
def_irq_handler UART0_RxTimeout_IRQHandler /* 41: UART0 receive timeout interrupt */
def_irq_handler UART0_ModemStatus_IRQHandler /* 42: UART0 modem status interrupt */
def_irq_handler UART0_Error_IRQHandler /* 43: UART0 error interrupt */
def_irq_handler UART0_IRQHandler /* 44: UART0 interrupt */
def_irq_handler UART1_Rx_IRQHandler /* 45: UART1 receive FIFO interrupt */
def_irq_handler UART1_Tx_IRQHandler /* 46: UART1 transmit FIFO interrupt */
def_irq_handler UART1_RxTimeout_IRQHandler /* 47: UART1 receive timeout interrupt */
def_irq_handler UART1_ModemStatus_IRQHandler /* 48: UART1 modem status interrupt */
def_irq_handler UART1_Error_IRQHandler /* 49: UART1 error interrupt */
def_irq_handler UART1_IRQHandler /* 50: UART1 interrupt */
def_irq_handler GPIO_0_IRQHandler /* 51: GPIO 0 interrupt */
def_irq_handler GPIO_1_IRQHandler /* 52: GPIO 1 interrupt */
def_irq_handler GPIO_2_IRQHandler /* 53: GPIO 2 interrupt */
def_irq_handler GPIO_3_IRQHandler /* 54: GPIO 3 interrupt */
def_irq_handler GPIO_4_IRQHandler /* 55: GPIO 4 interrupt */
def_irq_handler GPIO_5_IRQHandler /* 56: GPIO 5 interrupt */
def_irq_handler GPIO_6_IRQHandler /* 57: GPIO 6 interrupt */
def_irq_handler GPIO_7_IRQHandler /* 58: GPIO 7 interrupt */
def_irq_handler GPIO_8_IRQHandler /* 59: GPIO 8 interrupt */
def_irq_handler GPIO_9_IRQHandler /* 60: GPIO 9 interrupt */
def_irq_handler GPIO_10_IRQHandler /* 61: GPIO 10 interrupt */
def_irq_handler GPIO_11_IRQHandler /* 62: GPIO 11 interrupt */
def_irq_handler GPIO_12_IRQHandler /* 63: GPIO 12 interrupt */
def_irq_handler GPIO_13_IRQHandler /* 64: GPIO 13 interrupt */
def_irq_handler GPIO_14_IRQHandler /* 65: GPIO 14 interrupt */
def_irq_handler GPIO_15_IRQHandler /* 66: GPIO 15 interrupt */
def_irq_handler GPIO_Combined_IRQHandler /* 67: GPIO Combined interrupt */
def_irq_handler PVT_IRQHandler /* 68: PVT sensor interrupt */
def_irq_handler PWM_0_IRQHandler /* 70: PWM0 interrupt */
def_irq_handler RTC_IRQHandler /* 71: RTC interrupt */
def_irq_handler GpTimer1_IRQHandler /* 72: General Purpose Timer0 */
def_irq_handler GpTimer0_IRQHandler /* 73: General Purpose Timer1 */
def_irq_handler PWM_1_IRQHandler /* 74: PWM1 interrupt */
def_irq_handler PWM_2_IRQHandler /* 75: PWM2 interrupt */
def_irq_handler IOMUX_IRQHandler /* 76: IOMUX interrupt */
.end

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 2017-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MUSCA_S1_CMSIS_H__
#define __MUSCA_S1_CMSIS_H__
/* Processor and Core Peripherals and configurations */
/* ========================================================================== */
/* ============= Processor and Core Peripheral Section ============= */
/* ========================================================================== */
/* ----- Start of section using anonymous unions and disabling warnings ----- */
#if defined (__CC_ARM)
#pragma push
#pragma anon_unions
#elif defined (__ICCARM__)
#pragma language=extended
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wc11-extensions"
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#elif defined (__GNUC__)
/* anonymous unions are enabled by default */
#elif defined (__TMS470__)
/* anonymous unions are enabled by default */
#elif defined (__TASKING__)
#pragma warning 586
#elif defined (__CSMC__)
/* anonymous unions are enabled by default */
#else
#warning Not supported compiler type
#endif
/* -- Configuration of the Cortex-M33 Processor and Core Peripherals -- */
#define __CM33_REV 0x0002U /* Core revision r0p2 */
#define __SAUREGION_PRESENT 1U /* SAU regions present */
#define __MPU_PRESENT 1U /* MPU present */
#define __VTOR_PRESENT 1U /* VTOR present */
#define __NVIC_PRIO_BITS 4U /* Number of Bits used for the
* Priority Levels */
#define __Vendor_SysTickConfig 0U /* Set to 1 if different SysTick
* Config is used */
#define __FPU_PRESENT 1U /* FPU present */
#define __DSP_PRESENT 1U /* DSP extension present */
#include "system_core_init.h"
#include "platform_irq.h"
#include <core_cm33.h> /*!< Arm Cortex-M33 processor and core peripherals */
/* ------ End of section using anonymous unions and disabling warnings ------ */
#if defined (__CC_ARM)
#pragma pop
#elif defined (__ICCARM__)
/* leave anonymous unions enabled */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang diagnostic pop
#elif defined (__GNUC__)
/* anonymous unions are enabled by default */
#elif defined (__TMS470__)
/* anonymous unions are enabled by default */
#elif defined (__TASKING__)
#pragma warning restore
#elif defined (__CSMC__)
/* anonymous unions are enabled by default */
#else
#warning Not supported compiler type
#endif
#endif /*__MUSCA_S1_CMSIS_H__ */

View File

@ -0,0 +1,35 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This file is included from the linker script,
* limited set of C constructs can be used here
*/
#ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H
#include "../partition/region_defs.h"
#define NVIC_NUM_VECTORS (16 + 77)
/** Location of vectors to move in RAM */
#define NVIC_RAM_VECTOR_ADDRESS NS_DATA_START
#define NVIC_RAM_VECTOR_SIZE (NVIC_NUM_VECTORS * 4)
#define NVIC_RAM_VECTOR_LIMIT (NVIC_RAM_VECTOR_ADDRESS + NVIC_RAM_VECTOR_SIZE)
#endif

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cmsis.h"
#ifndef NVIC_VIRTUAL_H
#define NVIC_VIRTUAL_H
#ifdef __cplusplus
extern "C" {
#endif
/* NVIC functions */
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
#define NVIC_EnableIRQ __NVIC_EnableIRQ
#define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ
#define NVIC_DisableIRQ __NVIC_DisableIRQ
#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
#define NVIC_GetActive __NVIC_GetActive
#define NVIC_SetPriority __NVIC_SetPriority
#define NVIC_GetPriority __NVIC_GetPriority
/**
* \brief Overriding the default CMSIS system reset implementation by calling
* secure TFM service.
*
*/
void NVIC_SystemReset(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2017-2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MUSCA_S1_DEVICE_CFG_H__
#define __MUSCA_S1_DEVICE_CFG_H__
/**
* \file device_cfg.h
* \brief Configuration file native driver re-targeting
*
* \details This file can be used to add native driver specific macro
* definitions to select which peripherals are available in the build.
*
* This is a default device configuration file with all peripherals enabled.
*/
/*ARM UART Controller PL011*/
#define UART0_PL011_NS
#define UART0_PL011_DEV UART0_PL011_DEV_NS
#define uart0_tx_irq_handler UART0_Tx_IRQHandler
#define uart0_rx_irq_handler UART0_Rx_IRQHandler
#define uart0_rx_timeout_irq_handler UART0_RxTimeout_IRQHandler
#define UART1_PL011_NS
#define UART1_PL011_DEV UART1_PL011_DEV_NS
#define uart1_tx_irq_handler UART1_Tx_IRQHandler
#define uart1_rx_irq_handler UART1_Rx_IRQHandler
#define uart1_rx_timeout_irq_handler UART1_RxTimeout_IRQHandler
/* CMSDK Timers */
#define CMSDK_TIMER0_NS
#define CMSDK_TIMER0_DEV CMSDK_TIMER0_DEV_NS
#define CMSDK_TIMER1_NS
#define CMSDK_TIMER1_DEV CMSDK_TIMER1_DEV_NS
/* GPIO */
#define GPIO0_CMSDK_NS
#define GPIO0_CMSDK_DEV GPIO0_CMSDK_DEV_NS;
/* GP Timer */
#define GP_TIMER_NS
#define GP_TIMER_DEV GP_TIMER_DEV_NS
#define GP_TIMER_ALARM0_IRQ GpTimer0_IRQn
#define GP_TIMER_IRQ0_HANDLER GpTimer0_IRQHandler
#define GP_TIMER_ALARM_NR TIMER_GP_READ_ALARM_0
#define GP_TIMER_FREQ_HZ 32768UL /* System Ref Clock */
#define GP_TIMER_BIT_WIDTH 32U
/* I2C IP6510 */
#define I2C0_IP6510_NS
#define I2C0_IP6510_DEV I2C0_IP6510_DEV_NS
#define I2C1_IP6510_NS
#define I2C1_IP6510_DEV I2C1_IP6510_DEV_NS
/**
* mbed usec high-resolution ticker configuration
*/
#define USEC_TIMER_DEV CMSDK_TIMER0_DEV_NS
#define usec_interval_irq_handler TIMER0_IRQHandler
#define USEC_INTERVAL_IRQ TIMER0_IRQn
/** Timer frequency is equal to SYSTEM_CLOCK, defined in system_core_clk.c */
#define TIMER_FREQ_HZ 50000000U
/** The us Ticker uses CMSDK Timer, that does not have HW prescaler.
* The reported shift define is necessary for the software emulated
* prescaler behavior, so the ticker works as if it was ticking on a
* virtually slower frequency. The value 6 sets up the ticker to work
* properly in the specified frequency interval.
*/
#define USEC_REPORTED_SHIFT 6
#define USEC_REPORTED_FREQ_HZ (TIMER_FREQ_HZ >> USEC_REPORTED_SHIFT)
#define USEC_REPORTED_BITS (32 - USEC_REPORTED_SHIFT)
#define UART_DEFAULT_BAUD_RATE 115200U
/* Cadence QSPI Flash Controller */
#define QSPI_IP6514E_NS
/* MT25QL Flash memory library */
#define MT25QL_NS
#define FLASH_DEV MT25QL_DEV_NS
#endif /* __ARM_LTD_DEVICE_CFG_H__ */

View File

@ -0,0 +1,573 @@
/*
* Copyright (c) 2017-2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file device_definition.c
* \brief This file defines exports the structures based on the peripheral
* definitions from device_cfg.h.
* This file is meant to be used as a helper for baremetal
* applications and/or as an example of how to configure the generic
* driver structures.
*/
#include "device_cfg.h"
#include "device_definition.h"
#include "platform_base_address.h"
/* ======= Peripheral configuration structure definitions ======= */
/* MUSCA S1 SCC driver structures */
#ifdef MUSCA_S1_SCC_S
static const struct musca_s1_scc_dev_cfg_t MUSCA_S1_SCC_DEV_CFG_S = {
.base = MUSCA_S1_SCC_S_BASE};
struct musca_s1_scc_dev_t MUSCA_S1_SCC_DEV_S = {&(MUSCA_S1_SCC_DEV_CFG_S)};
#endif
#ifdef MUSCA_S1_SCC_NS
static const struct musca_s1_scc_dev_cfg_t MUSCA_S1_SCC_DEV_CFG_NS = {
.base = MUSCA_S1_SCC_NS_BASE};
struct musca_s1_scc_dev_t MUSCA_S1_SCC_DEV_NS = {&(MUSCA_S1_SCC_DEV_CFG_NS)};
#endif
/* CMSDK GPIO driver structures */
#ifdef GPIO0_CMSDK_S
static const struct gpio_cmsdk_dev_cfg_t GPIO0_CMSDK_DEV_CFG_S = {
.base = MUSCA_S1_GPIO_S_BASE};
struct gpio_cmsdk_dev_t GPIO0_CMSDK_DEV_S = {&(GPIO0_CMSDK_DEV_CFG_S)};
#endif
#ifdef GPIO0_CMSDK_NS
static const struct gpio_cmsdk_dev_cfg_t GPIO0_CMSDK_DEV_CFG_NS = {
.base = MUSCA_S1_GPIO_NS_BASE};
struct gpio_cmsdk_dev_t GPIO0_CMSDK_DEV_NS = {&(GPIO0_CMSDK_DEV_CFG_NS)};
#endif
/* ARM PPC SSE 200 driver structures */
#ifdef AHB_PPC0_S
static struct ppc_sse200_dev_cfg_t AHB_PPC0_DEV_CFG_S = {
.spctrl_base = MUSCA_S1_SPCTRL_S_BASE,
.nspctrl_base = MUSCA_S1_NSPCTRL_NS_BASE };
static struct ppc_sse200_dev_data_t AHB_PPC0_DEV_DATA_S = {
.p_ns_ppc = 0,
.p_sp_ppc = 0,
.p_nsp_ppc = 0,
.int_bit_mask = 0,
.state = 0 };
struct ppc_sse200_dev_t AHB_PPC0_DEV_S = {
&AHB_PPC0_DEV_CFG_S, &AHB_PPC0_DEV_DATA_S };
#endif
#ifdef AHB_PPCEXP0_S
static struct ppc_sse200_dev_cfg_t AHB_PPCEXP0_DEV_CFG_S = {
.spctrl_base = MUSCA_S1_SPCTRL_S_BASE,
.nspctrl_base = MUSCA_S1_NSPCTRL_NS_BASE };
static struct ppc_sse200_dev_data_t AHB_PPCEXP0_DEV_DATA_S = {
.p_ns_ppc = 0,
.p_sp_ppc = 0,
.p_nsp_ppc = 0,
.int_bit_mask = 0,
.state = 0 };
struct ppc_sse200_dev_t AHB_PPCEXP0_DEV_S = {
&AHB_PPCEXP0_DEV_CFG_S, &AHB_PPCEXP0_DEV_DATA_S };
#endif
#ifdef APB_PPC0_S
static struct ppc_sse200_dev_cfg_t APB_PPC0_DEV_CFG_S = {
.spctrl_base = MUSCA_S1_SPCTRL_S_BASE,
.nspctrl_base = MUSCA_S1_NSPCTRL_NS_BASE };
static struct ppc_sse200_dev_data_t APB_PPC0_DEV_DATA_S = {
.p_ns_ppc = 0,
.p_sp_ppc = 0,
.p_nsp_ppc = 0,
.int_bit_mask = 0,
.state = 0 };
struct ppc_sse200_dev_t APB_PPC0_DEV_S = {
&APB_PPC0_DEV_CFG_S, &APB_PPC0_DEV_DATA_S };
#endif
#ifdef APB_PPC1_S
static struct ppc_sse200_dev_cfg_t APB_PPC1_DEV_CFG_S = {
.spctrl_base = MUSCA_S1_SPCTRL_S_BASE,
.nspctrl_base = MUSCA_S1_NSPCTRL_NS_BASE };
static struct ppc_sse200_dev_data_t APB_PPC1_DEV_DATA_S = {
.p_ns_ppc = 0,
.p_sp_ppc = 0,
.p_nsp_ppc = 0,
.int_bit_mask = 0,
.state = 0 };
struct ppc_sse200_dev_t APB_PPC1_DEV_S = {
&APB_PPC1_DEV_CFG_S, &APB_PPC1_DEV_DATA_S};
#endif
#ifdef APB_PPCEXP0_S
static struct ppc_sse200_dev_cfg_t APB_PPCEXP0_DEV_CFG_S = {
.spctrl_base = MUSCA_S1_SPCTRL_S_BASE,
.nspctrl_base = MUSCA_S1_NSPCTRL_NS_BASE };
static struct ppc_sse200_dev_data_t APB_PPCEXP0_DEV_DATA_S = {
.p_ns_ppc = 0,
.p_sp_ppc = 0,
.p_nsp_ppc = 0,
.int_bit_mask = 0,
.state = 0 };
struct ppc_sse200_dev_t APB_PPCEXP0_DEV_S = {
&APB_PPCEXP0_DEV_CFG_S, &APB_PPCEXP0_DEV_DATA_S };
#endif
#ifdef APB_PPCEXP1_S
static struct ppc_sse200_dev_cfg_t APB_PPCEXP1_DEV_CFG = {
.spctrl_base = MUSCA_S1_SPCTRL_S_BASE,
.nspctrl_base = MUSCA_S1_NSPCTRL_NS_BASE };
static struct ppc_sse200_dev_data_t APB_PPCEXP1_DEV_DATA_S = {
.p_ns_ppc = 0,
.p_sp_ppc = 0,
.p_nsp_ppc = 0,
.int_bit_mask = 0,
.state = 0 };
struct ppc_sse200_dev_t APB_PPCEXP1_DEV_S = {
&APB_PPCEXP1_DEV_CFG, &APB_PPCEXP1_DEV_DATA_S };
#endif
/* ARM MPC SIE 200 driver structures */
#ifdef MPC_ISRAM0_S
static const struct mpc_sie_dev_cfg_t MPC_ISRAM0_DEV_CFG_S = {
.base = MUSCA_S1_MPC_SRAM0_S_BASE};
static struct mpc_sie_dev_data_t MPC_ISRAM0_DEV_DATA_S = {
.range_list = 0,
.nbr_of_ranges = 0,
.is_initialized = false};
struct mpc_sie_dev_t MPC_ISRAM0_DEV_S = {
&(MPC_ISRAM0_DEV_CFG_S),
&(MPC_ISRAM0_DEV_DATA_S)};
#endif
#ifdef MPC_ISRAM1_S
static const struct mpc_sie_dev_cfg_t MPC_ISRAM1_DEV_CFG_S = {
.base = MUSCA_S1_MPC_SRAM1_S_BASE};
static struct mpc_sie_dev_data_t MPC_ISRAM1_DEV_DATA_S = {
.range_list = 0,
.nbr_of_ranges = 0,
.is_initialized = false};
struct mpc_sie_dev_t MPC_ISRAM1_DEV_S = {
&(MPC_ISRAM1_DEV_CFG_S),
&(MPC_ISRAM1_DEV_DATA_S)};
#endif
#ifdef MPC_ISRAM2_S
static const struct mpc_sie_dev_cfg_t MPC_ISRAM2_DEV_CFG_S = {
.base = MUSCA_S1_MPC_SRAM2_S_BASE};
static struct mpc_sie_dev_data_t MPC_ISRAM2_DEV_DATA_S = {
.range_list = 0,
.nbr_of_ranges = 0,
.is_initialized = false};
struct mpc_sie_dev_t MPC_ISRAM2_DEV_S = {
&(MPC_ISRAM2_DEV_CFG_S),
&(MPC_ISRAM2_DEV_DATA_S)};
#endif
#ifdef MPC_ISRAM3_S
static const struct mpc_sie_dev_cfg_t MPC_ISRAM3_DEV_CFG_S = {
.base = MUSCA_S1_MPC_SRAM3_S_BASE};
static struct mpc_sie_dev_data_t MPC_ISRAM3_DEV_DATA_S = {
.range_list = 0,
.nbr_of_ranges = 0,
.is_initialized = false};
struct mpc_sie_dev_t MPC_ISRAM3_DEV_S = {
&(MPC_ISRAM3_DEV_CFG_S),
&(MPC_ISRAM3_DEV_DATA_S)};
#endif
#ifdef MPC_CODE_SRAM_NS
static const struct mpc_sie_dev_cfg_t MPC_CODE_SRAM_DEV_CFG_NS = {
.base = MUSCA_S1_CODE_SRAM_MPC_NS_BASE};
static struct mpc_sie_dev_data_t MPC_CODE_SRAM_DEV_DATA_NS = {
.range_list = 0,
.nbr_of_ranges = 0,
.is_initialized = false};
struct mpc_sie_dev_t MPC_CODE_SRAM_DEV_NS = {
&(MPC_CODE_SRAM_DEV_CFG_NS),
&(MPC_CODE_SRAM_DEV_DATA_NS)};
#endif
#ifdef MPC_CODE_SRAM_S
static const struct mpc_sie_dev_cfg_t MPC_CODE_SRAM_DEV_CFG_S = {
.base = MUSCA_S1_CODE_SRAM_MPC_S_BASE};
static struct mpc_sie_dev_data_t MPC_CODE_SRAM_DEV_DATA_S = {
.range_list = 0,
.nbr_of_ranges = 0,
.is_initialized = false};
struct mpc_sie_dev_t MPC_CODE_SRAM_DEV_S = {
&(MPC_CODE_SRAM_DEV_CFG_S),
&(MPC_CODE_SRAM_DEV_DATA_S)};
#endif
#ifdef MPC_QSPI_S
static const struct mpc_sie_dev_cfg_t MPC_QSPI_DEV_CFG_S = {
.base = MUSCA_S1_QSPI_MPC_S_BASE};
static struct mpc_sie_dev_data_t MPC_QSPI_DEV_DATA_S = {
.range_list = 0,
.nbr_of_ranges = 0,
.is_initialized = false};
struct mpc_sie_dev_t MPC_QSPI_DEV_S = {
&(MPC_QSPI_DEV_CFG_S),
&(MPC_QSPI_DEV_DATA_S)};
#endif
#ifdef MPC_QSPI_NS
static const struct mpc_sie_dev_cfg_t MPC_QSPI_DEV_CFG_NS = {
.base = MUSCA_S1_QSPI_MPC_NS_BASE};
static struct mpc_sie_dev_data_t MPC_QSPI_DEV_DATA_NS = {
.range_list = 0,
.nbr_of_ranges = 0,
.is_initialized = false};
struct mpc_sie_dev_t MPC_QSPI_DEV_NS = {
&(MPC_QSPI_DEV_CFG_NS),
&(MPC_QSPI_DEV_DATA_NS)};
#endif
#ifdef MPC_MRAM_S
static const struct mpc_sie_dev_cfg_t MPC_MRAM_DEV_CFG_S = {
.base = MUSCA_S1_MRAM_MPC_S_BASE};
static struct mpc_sie_dev_data_t MPC_MRAM_DEV_DATA_S = {
.range_list = 0,
.nbr_of_ranges = 0,
.is_initialized = false};
struct mpc_sie_dev_t MPC_MRAM_DEV_S = {
&(MPC_MRAM_DEV_CFG_S),
&(MPC_MRAM_DEV_DATA_S)};
#endif
#ifdef MPC_MRAM_NS
static const struct mpc_sie_dev_cfg_t MPC_MRAM_DEV_CFG_NS = {
.base = MUSCA_S1_MRAM_MPC_NS_BASE};
static struct mpc_sie_dev_data_t MPC_MRAM_DEV_DATA_NS = {
.range_list = 0,
.nbr_of_ranges = 0,
.is_initialized = false};
struct mpc_sie_dev_t MPC_MRAM_DEV_NS = {
&(MPC_MRAM_DEV_CFG_NS),
&(MPC_MRAM_DEV_DATA_NS)};
#endif
/* ARM MHU driver structures */
#ifdef ARM_MHU0_S
static const struct arm_mhu_sse_200_dev_cfg_t ARM_MHU0_DEV_CFG_S = {
.base = MUSCA_S1_MHU0_S_BASE};
struct arm_mhu_sse_200_dev_t ARM_MHU0_DEV_S = {&(ARM_MHU0_DEV_CFG_S)};
#endif
#ifdef ARM_MHU0_NS
static const struct arm_mhu_sse_200_dev_cfg_t ARM_MHU0_DEV_CFG_NS = {
.base = MUSCA_S1_MHU0_NS_BASE};
struct arm_mhu_sse_200_dev_t ARM_MHU0_DEV_NS = {&(ARM_MHU0_DEV_CFG_NS)};
#endif
#ifdef ARM_MHU1_S
static const struct arm_mhu_sse_200_dev_cfg_t ARM_MHU1_DEV_CFG_S = {
.base = MUSCA_S1_MHU1_S_BASE};
struct arm_mhu_sse_200_dev_t ARM_MHU1_DEV_S = {&(ARM_MHU1_DEV_CFG_S)};
#endif
#ifdef ARM_MHU1_NS
static const struct arm_mhu_sse_200_dev_cfg_t ARM_MHU1_DEV_CFG_NS = {
.base = MUSCA_S1_MHU1_NS_BASE};
struct arm_mhu_sse_200_dev_t ARM_MHU1_DEV_NS = {&(ARM_MHU1_DEV_CFG_NS)};
#endif
/* SSE-200 Cache driver structure */
#ifdef SSE_200_CACHE_S
static const struct arm_cache_dev_cfg_t SSE_200_CACHE_CFG_S = {
.base = MUSCA_S1_CPU_ELEMENT_S_BASE};
struct arm_cache_dev_t SSE_200_CACHE_DEV_S = {&(SSE_200_CACHE_CFG_S)};
#endif
#ifdef SSE_200_CACHE_NS
static const struct arm_cache_dev_cfg_t SSE_200_CACHE_CFG_NS = {
.base = MUSCA_S1_CPU_ELEMENT_NS_BASE};
struct arm_cache_dev_t SSE_200_CACHE_DEV_NS = {&(SSE_200_CACHE_CFG_NS)};
#endif
/* I2C IP6510 driver structures */
#ifdef I2C0_IP6510_S
static const struct i2c_ip6510_dev_cfg_t I2C0_IP6510_DEV_CFG_S = {
.base = MUSCA_S1_I2C0_S_BASE,
.default_mode = I2C_IP6510_MASTER_MODE,
.default_bus_speed = I2C_IP6510_SPEED_100KHZ};
static struct i2c_ip6510_dev_data_t I2C0_IP6510_DEV_DATA_S = {
.state = 0,
.mode = 0,
.bus_speed = 0};
struct i2c_ip6510_dev_t I2C0_IP6510_DEV_S = {
&(I2C0_IP6510_DEV_CFG_S),
&(I2C0_IP6510_DEV_DATA_S)};
#endif
#ifdef I2C0_IP6510_NS
static const struct i2c_ip6510_dev_cfg_t I2C0_IP6510_DEV_CFG_NS = {
.base = MUSCA_S1_I2C0_NS_BASE,
.default_mode = I2C_IP6510_MASTER_MODE,
.default_bus_speed = I2C_IP6510_SPEED_100KHZ};
static struct i2c_ip6510_dev_data_t I2C0_IP6510_DEV_DATA_NS = {
.state = 0,
.mode = 0,
.bus_speed = 0};
struct i2c_ip6510_dev_t I2C0_IP6510_DEV_NS = {
&(I2C0_IP6510_DEV_CFG_NS),
&(I2C0_IP6510_DEV_DATA_NS)};
#endif
#ifdef I2C1_IP6510_S
static const struct i2c_ip6510_dev_cfg_t I2C1_IP6510_DEV_CFG_S = {
.base = MUSCA_S1_I2C1_S_BASE,
.default_mode = I2C_IP6510_MASTER_MODE,
.default_bus_speed = I2C_IP6510_SPEED_100KHZ};
static struct i2c_ip6510_dev_data_t I2C1_IP6510_DEV_DATA_S = {
.state = 0,
.mode = 0,
.bus_speed = 0};
struct i2c_ip6510_dev_t I2C1_IP6510_DEV_S = {
&(I2C1_IP6510_DEV_CFG_S),
&(I2C1_IP6510_DEV_DATA_S)};
#endif
#ifdef I2C1_IP6510_NS
static const struct i2c_ip6510_dev_cfg_t I2C1_IP6510_DEV_CFG_NS = {
.base = MUSCA_S1_I2C1_NS_BASE,
.default_mode = I2C_IP6510_MASTER_MODE,
.default_bus_speed = I2C_IP6510_SPEED_100KHZ};
static struct i2c_ip6510_dev_data_t I2C1_IP6510_DEV_DATA_NS = {
.state = 0,
.mode = 0,
.bus_speed = 0};
struct i2c_ip6510_dev_t I2C1_IP6510_DEV_NS = {
&(I2C1_IP6510_DEV_CFG_NS),
&(I2C1_IP6510_DEV_DATA_NS)};
#endif
/* CMSDK Timers driver structures */
#ifdef CMSDK_TIMER0_S
static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER0_DEV_CFG_S = {
.base = MUSCA_S1_CMSDK_TIMER0_S_BASE};
static struct timer_cmsdk_dev_data_t CMSDK_TIMER0_DEV_DATA_S = {
.is_initialized = 0};
struct timer_cmsdk_dev_t CMSDK_TIMER0_DEV_S = {&(CMSDK_TIMER0_DEV_CFG_S),
&(CMSDK_TIMER0_DEV_DATA_S)};
#endif
#ifdef CMSDK_TIMER0_NS
static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER0_DEV_CFG_NS = {
.base = MUSCA_S1_CMSDK_TIMER0_NS_BASE};
static struct timer_cmsdk_dev_data_t CMSDK_TIMER0_DEV_DATA_NS = {
.is_initialized = 0};
struct timer_cmsdk_dev_t CMSDK_TIMER0_DEV_NS = {&(CMSDK_TIMER0_DEV_CFG_NS),
&(CMSDK_TIMER0_DEV_DATA_NS)};
#endif
#ifdef CMSDK_TIMER1_S
static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER1_DEV_CFG_S = {
.base = MUSCA_S1_CMSDK_TIMER1_S_BASE};
static struct timer_cmsdk_dev_data_t CMSDK_TIMER1_DEV_DATA_S = {
.is_initialized = 0};
struct timer_cmsdk_dev_t CMSDK_TIMER1_DEV_S = {&(CMSDK_TIMER1_DEV_CFG_S),
&(CMSDK_TIMER1_DEV_DATA_S)};
#endif
#ifdef CMSDK_TIMER1_NS
static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER1_DEV_CFG_NS = {
.base = MUSCA_S1_CMSDK_TIMER1_NS_BASE};
static struct timer_cmsdk_dev_data_t CMSDK_TIMER1_DEV_DATA_NS = {
.is_initialized = 0};
struct timer_cmsdk_dev_t CMSDK_TIMER1_DEV_NS = {&(CMSDK_TIMER1_DEV_CFG_NS),
&(CMSDK_TIMER1_DEV_DATA_NS)};
#endif
/* CMSDK Dualtimer driver structures */
#ifdef CMSDK_DUALTIMER_S
static const struct dualtimer_cmsdk_dev_cfg_t CMSDK_DUALTIMER_DEV_CFG_S = {
.base = MUSCA_S1_CMSDK_DUALTIMER_S_BASE};
static struct dualtimer_cmsdk_dev_data_t CMSDK_DUALTIMER_DEV_DATA_S = {
.is_initialized = 0};
struct dualtimer_cmsdk_dev_t CMSDK_DUALTIMER_DEV_S = {
&(CMSDK_DUALTIMER_DEV_CFG_S),
&(CMSDK_DUALTIMER_DEV_DATA_S)};
#endif
#ifdef CMSDK_DUALTIMER_NS
static const struct dualtimer_cmsdk_dev_cfg_t CMSDK_DUALTIMER_DEV_CFG_NS = {
.base = MUSCA_S1_CMSDK_DUALTIMER_NS_BASE};
static struct dualtimer_cmsdk_dev_data_t CMSDK_DUALTIMER_DEV_DATA_NS = {
.is_initialized = 0};
struct dualtimer_cmsdk_dev_t CMSDK_DUALTIMER_DEV_NS = {
&(CMSDK_DUALTIMER_DEV_CFG_NS),
&(CMSDK_DUALTIMER_DEV_DATA_NS)};
#endif
/* General-Purpose Timer driver structures */
#ifdef GP_TIMER_S
static const struct timer_gp_dev_cfg_t GP_TIMER_DEV_CFG_S = {
.base = MUSCA_S1_TIMER_S_BASE};
static struct timer_gp_dev_data_t GP_TIMER_DEV_DATA_S = {
.is_initialized = false,
.alarm0_init = 0,
.alarm1_init = 0};
struct timer_gp_dev_t GP_TIMER_DEV_S = {
&(GP_TIMER_DEV_CFG_S),
&(GP_TIMER_DEV_DATA_S)};
#endif
#ifdef GP_TIMER_NS
static const struct timer_gp_dev_cfg_t GP_TIMER_DEV_CFG_NS = {
.base = MUSCA_S1_TIMER_NS_BASE};
static struct timer_gp_dev_data_t GP_TIMER_DEV_DATA_NS = {
.is_initialized = false,
.alarm0_init = 0,
.alarm1_init = 0};
struct timer_gp_dev_t GP_TIMER_DEV_NS = {
&(GP_TIMER_DEV_CFG_NS),
&(GP_TIMER_DEV_DATA_NS)};
#endif
/* PL031 Real-Time Clock structure */
#ifdef RTC_PL031_S
static const struct rtc_pl031_dev_cfg_t RTC_PL031_DEV_CFG_S = {
.base = MUSCA_S1_RTC_S_BASE};
struct rtc_pl031_dev_t RTC_PL031_DEV_S = {&(RTC_PL031_DEV_CFG_S)};
#endif
#ifdef RTC_PL031_NS
static const struct rtc_pl031_dev_cfg_t RTC_PL031_DEV_CFG_NS = {
.base = MUSCA_S1_RTC_NS_BASE};
struct rtc_pl031_dev_t RTC_PL031_DEV_NS = {&(RTC_PL031_DEV_CFG_NS)};
#endif
#ifdef UART0_PL011_S
static const struct uart_pl011_dev_cfg_t UART0_PL011_DEV_CFG_S = {
.base = MUSCA_S1_UART0_S_BASE,
.def_baudrate = UART_DEFAULT_BAUD_RATE,
.def_wlen = UART_PL011_WLEN_8,
.def_parity = UART_PL011_PARITY_DISABLED,
.def_stopbit = UART_PL011_STOPBIT_1};
static struct uart_pl011_dev_data_t UART0_PL011_DEV_DATA_S = {
.state = 0,
.uart_clk = 0,
.baudrate = 0};
struct uart_pl011_dev_t UART0_PL011_DEV_S = {&(UART0_PL011_DEV_CFG_S),
&(UART0_PL011_DEV_DATA_S)};
#endif
#ifdef UART0_PL011_NS
static const struct uart_pl011_dev_cfg_t UART0_PL011_DEV_CFG_NS = {
.base = MUSCA_S1_UART0_NS_BASE,
.def_baudrate = UART_DEFAULT_BAUD_RATE,
.def_wlen = UART_PL011_WLEN_8,
.def_parity = UART_PL011_PARITY_DISABLED,
.def_stopbit = UART_PL011_STOPBIT_1};
static struct uart_pl011_dev_data_t UART0_PL011_DEV_DATA_NS = {
.state = 0,
.uart_clk = 0,
.baudrate = 0};
struct uart_pl011_dev_t UART0_PL011_DEV_NS = {&(UART0_PL011_DEV_CFG_NS),
&(UART0_PL011_DEV_DATA_NS)};
#endif
#ifdef UART1_PL011_S
static const struct uart_pl011_dev_cfg_t UART1_PL011_DEV_CFG_S = {
.base = MUSCA_S1_UART1_S_BASE,
.def_baudrate = UART_DEFAULT_BAUD_RATE,
.def_wlen = UART_PL011_WLEN_8,
.def_parity = UART_PL011_PARITY_DISABLED,
.def_stopbit = UART_PL011_STOPBIT_1};
static struct uart_pl011_dev_data_t UART1_PL011_DEV_DATA_S = {
.state = 0,
.uart_clk = 0,
.baudrate = 0};
struct uart_pl011_dev_t UART1_PL011_DEV_S = {&(UART1_PL011_DEV_CFG_S),
&(UART1_PL011_DEV_DATA_S)};
#endif
#ifdef UART1_PL011_NS
static const struct uart_pl011_dev_cfg_t UART1_PL011_DEV_CFG_NS = {
.base = MUSCA_S1_UART1_NS_BASE,
.def_baudrate = UART_DEFAULT_BAUD_RATE,
.def_wlen = UART_PL011_WLEN_8,
.def_parity = UART_PL011_PARITY_DISABLED,
.def_stopbit = UART_PL011_STOPBIT_1};
static struct uart_pl011_dev_data_t UART1_PL011_DEV_DATA_NS = {
.state = 0,
.uart_clk = 0,
.baudrate = 0};
struct uart_pl011_dev_t UART1_PL011_DEV_NS = {&(UART1_PL011_DEV_CFG_NS),
&(UART1_PL011_DEV_DATA_NS)};
#endif
/* SPI IP6524 driver structures */
#ifdef SPI0_IP6524_S
static const struct spi_ip6524_dev_cfg_t SPI0_DEV_CFG_S = {
.base = MUSCA_S1_SPI0_S_BASE};
static struct spi_ip6524_dev_data_t SPI0_DEV_DATA_S = {
.state = 0};
struct spi_ip6524_dev_t SPI0_DEV_S = {&(SPI0_DEV_CFG_S),
&(SPI0_DEV_DATA_S)};
#endif
#ifdef SPI0_IP6524_NS
static const struct spi_ip6524_dev_cfg_t SPI0_DEV_CFG_NS = {
.base = MUSCA_S1_SPI0_NS_BASE};
static struct spi_ip6524_dev_data_t SPI0_DEV_DATA_NS = {
.state = 0};
struct spi_ip6524_dev_t SPI0_DEV_NS = {&(SPI0_DEV_CFG_NS),
&(SPI0_DEV_DATA_NS)};
#endif
/* QSPI IP6514E driver structures */
#ifdef QSPI_IP6514E_S
static const struct qspi_ip6514e_dev_cfg_t QSPI_DEV_CFG_S = {
.base = MUSCA_S1_QSPI_REG_S_BASE,
.addr_mask = (1U << 25) - 1, /* 32 MiB minus 1 byte */
};
struct qspi_ip6514e_dev_t QSPI_DEV_S = {
&QSPI_DEV_CFG_S
};
#endif
#ifdef QSPI_IP6514E_NS
static const struct qspi_ip6514e_dev_cfg_t QSPI_DEV_CFG_NS = {
.base = MUSCA_S1_QSPI_REG_NS_BASE,
.addr_mask = (1U << 25) - 1, /* 32 MiB minus 1 byte */
};
struct qspi_ip6514e_dev_t QSPI_DEV_NS = {
&QSPI_DEV_CFG_NS
};
#endif
/* ======= External peripheral configuration structure definitions ======= */
/* MT25QL Flash memory library structures */
#if (defined(MT25QL_S) && defined(QSPI_IP6514E_S))
struct mt25ql_dev_t MT25QL_DEV_S = {
.controller = &QSPI_DEV_S,
.direct_access_start_addr = MUSCA_S1_QSPI_FLASH_S_BASE,
.baud_rate_div = 4U,
.size = 0x01000000U, /* 16 MiB */
.config_state = { 0 },
};
#endif
#if (defined(MT25QL_NS) && defined(QSPI_IP6514E_NS))
struct mt25ql_dev_t MT25QL_DEV_NS = {
.controller = &QSPI_DEV_NS,
.direct_access_start_addr = MUSCA_S1_QSPI_FLASH_NS_BASE,
.baud_rate_div = 4U,
.size = 0x01000000U, /* 16 MiB */
.config_state = { 0 },
};
#endif

View File

@ -0,0 +1,283 @@
/*
* Copyright (c) 2017-2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file device_definition.h
* \brief The structure definitions in this file are exported based
* on the peripheral definitions from device_cfg.h.
* This file is meant to be used as a helper for baremetal
* applications and/or as an example of how to configure the generic
* driver structures.
*/
#ifndef __DEVICE_DEFINITION_H__
#define __DEVICE_DEFINITION_H__
#include "device_cfg.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ======= Peripheral configuration structure declarations ======= */
/* ARM SCC driver structures */
#ifdef MUSCA_S1_SCC_S
#include "musca_s1_scc_drv.h"
extern struct musca_s1_scc_dev_t MUSCA_S1_SCC_DEV_S;
#endif
#ifdef MUSCA_S1_SCC_NS
#include "musca_s1_scc_drv.h"
extern struct musca_s1_scc_dev_t MUSCA_S1_SCC_DEV_NS;
#endif
/* ARM GPIO driver structures */
#ifdef GPIO0_CMSDK_S
#include "gpio_cmsdk_drv.h"
extern struct gpio_cmsdk_dev_t GPIO0_CMSDK_DEV_S;
#endif
#ifdef GPIO0_CMSDK_NS
#include "gpio_cmsdk_drv.h"
extern struct gpio_cmsdk_dev_t GPIO0_CMSDK_DEV_NS;
#endif
/* ARM MPC SIE 200 driver structures */
#ifdef MPC_ISRAM0_S
#include "mpc_sie_drv.h"
extern struct mpc_sie_dev_t MPC_ISRAM0_DEV_S;
#endif
#ifdef MPC_ISRAM1_S
#include "mpc_sie_drv.h"
extern struct mpc_sie_dev_t MPC_ISRAM1_DEV_S;
#endif
#ifdef MPC_ISRAM2_S
#include "mpc_sie_drv.h"
extern struct mpc_sie_dev_t MPC_ISRAM2_DEV_S;
#endif
#ifdef MPC_ISRAM3_S
#include "mpc_sie_drv.h"
extern struct mpc_sie_dev_t MPC_ISRAM3_DEV_S;
#endif
#ifdef MPC_CODE_SRAM_S
#include "mpc_sie_drv.h"
extern struct mpc_sie_dev_t MPC_CODE_SRAM_DEV_S;
#endif
#ifdef MPC_CODE_SRAM_NS
#include "mpc_sie_drv.h"
extern struct mpc_sie_dev_t MPC_CODE_SRAM_DEV_NS;
#endif
#ifdef MPC_QSPI_S
#include "mpc_sie_drv.h"
extern struct mpc_sie_dev_t MPC_QSPI_DEV_S;
#endif
#ifdef MPC_QSPI_NS
#include "mpc_sie_drv.h"
extern struct mpc_sie_dev_t MPC_QSPI_DEV_NS;
#endif
#ifdef MPC_MRAM_S
#include "mpc_sie_drv.h"
extern struct mpc_sie_dev_t MPC_MRAM_DEV_S;
#endif
#ifdef MPC_MRAM_NS
#include "mpc_sie_drv.h"
extern struct mpc_sie_dev_t MPC_MRAM_DEV_NS;
#endif
/* ARM MHU driver structures */
#ifdef ARM_MHU0_S
#include "mhu_sse_200_drv.h"
extern struct arm_mhu_sse_200_dev_t ARM_MHU0_DEV_S;
#endif
#ifdef ARM_MHU0_NS
#include "mhu_sse_200_drv.h"
extern struct arm_mhu_sse_200_dev_t ARM_MHU0_DEV_NS;
#endif
#ifdef ARM_MHU1_S
#include "mhu_sse_200_drv.h"
extern struct arm_mhu_sse_200_dev_t ARM_MHU1_DEV_S;
#endif
#ifdef ARM_MHU1_NS
#include "mhu_sse_200_drv.h"
extern struct arm_mhu_sse_200_dev_t ARM_MHU1_DEV_NS;
#endif
/* ARM UART PL011 driver structures */
#ifdef UART0_PL011_S
#include "uart_pl011_drv.h"
extern struct uart_pl011_dev_t UART0_PL011_DEV_S;
#endif
#ifdef UART0_PL011_NS
#include "uart_pl011_drv.h"
extern struct uart_pl011_dev_t UART0_PL011_DEV_NS;
#endif
#ifdef UART1_PL011_S
#include "uart_pl011_drv.h"
extern struct uart_pl011_dev_t UART1_PL011_DEV_S;
#endif
#ifdef UART1_PL011_NS
#include "uart_pl011_drv.h"
extern struct uart_pl011_dev_t UART1_PL011_DEV_NS;
#endif
/* SSE-200 Cache driver structure */
#ifdef SSE_200_CACHE_S
#include "cache_drv.h"
extern struct arm_cache_dev_t SSE_200_CACHE_DEV_S;
#endif
#ifdef SSE_200_CACHE_NS
#include "cache_drv.h"
extern struct arm_cache_dev_t SSE_200_CACHE_DEV_NS;
#endif
/* I2C IP6510 driver structures */
#ifdef I2C0_IP6510_S
#include "i2c_ip6510_drv.h"
extern struct i2c_ip6510_dev_t I2C0_IP6510_DEV_S;
#endif
#ifdef I2C0_IP6510_NS
#include "i2c_ip6510_drv.h"
extern struct i2c_ip6510_dev_t I2C0_IP6510_DEV_NS;
#endif
#ifdef I2C1_IP6510_S
#include "i2c_ip6510_drv.h"
extern struct i2c_ip6510_dev_t I2C1_IP6510_DEV_S;
#endif
#ifdef I2C1_IP6510_NS
#include "i2c_ip6510_drv.h"
extern struct i2c_ip6510_dev_t I2C1_IP6510_DEV_NS;
#endif
/* CMSDK Dualtimer driver structures */
#ifdef CMSDK_DUALTIMER_S
#include "dualtimer_cmsdk_drv.h"
extern struct dualtimer_cmsdk_dev_t CMSDK_DUALTIMER_DEV_S;
#endif
#ifdef CMSDK_DUALTIMER_NS
#include "dualtimer_cmsdk_drv.h"
extern struct dualtimer_cmsdk_dev_t CMSDK_DUALTIMER_DEV_NS;
#endif
/* CMSDK Timer driver structures */
#ifdef CMSDK_TIMER0_S
#include "timer_cmsdk_drv.h"
extern struct timer_cmsdk_dev_t CMSDK_TIMER0_DEV_S;
#endif
#ifdef CMSDK_TIMER0_NS
#include "timer_cmsdk_drv.h"
extern struct timer_cmsdk_dev_t CMSDK_TIMER0_DEV_NS;
#endif
#ifdef CMSDK_TIMER1_S
#include "timer_cmsdk_drv.h"
extern struct timer_cmsdk_dev_t CMSDK_TIMER1_DEV_S;
#endif
#ifdef CMSDK_TIMER1_NS
#include "timer_cmsdk_drv.h"
extern struct timer_cmsdk_dev_t CMSDK_TIMER1_DEV_NS;
#endif
/* General-Purpose Timer driver structures */
#ifdef GP_TIMER_S
#include "timer_gp_drv.h"
extern struct timer_gp_dev_t GP_TIMER_DEV_S;
#endif
#ifdef GP_TIMER_NS
#include "timer_gp_drv.h"
extern struct timer_gp_dev_t GP_TIMER_DEV_NS;
#endif
/* RTC PL031 */
#ifdef RTC_PL031_S
#include "rtc_pl031_drv.h"
extern struct rtc_pl031_dev_t RTC_PL031_DEV_S;
#endif
#ifdef RTC_PL031_NS
#include "rtc_pl031_drv.h"
extern struct rtc_pl031_dev_t RTC_PL031_DEV_NS;
#endif
/* Cadence SPI IP6524 driver structures */
#ifdef SPI0_IP6524_S
#include "spi_ip6524_drv.h"
extern struct spi_ip6524_dev_t SPI0_DEV_S;
#endif
#ifdef SPI0_IP6524_NS
#include "spi_ip6524_drv.h"
extern struct spi_ip6524_dev_t SPI0_DEV_NS;
#endif
/* QSPI Flash Controller driver structures */
#ifdef QSPI_IP6514E_S
#include "qspi_ip6514e_drv.h"
extern struct qspi_ip6514e_dev_t QSPI_DEV_S;
#endif
#ifdef QSPI_IP6514E_NS
#include "qspi_ip6514e_drv.h"
extern struct qspi_ip6514e_dev_t QSPI_DEV_NS;
#endif
/* ARM PPC driver structures */
#ifdef AHB_PPC0_S
#include "ppc_sse200_drv.h"
extern struct ppc_sse200_dev_t AHB_PPC0_DEV_S;
#endif
#ifdef AHB_PPCEXP0_S
#include "ppc_sse200_drv.h"
extern struct ppc_sse200_dev_t AHB_PPCEXP0_DEV_S;
#endif
#ifdef APB_PPC0_S
#include "ppc_sse200_drv.h"
extern struct ppc_sse200_dev_t APB_PPC0_DEV_S;
#endif
#ifdef APB_PPC1_S
#include "ppc_sse200_drv.h"
extern struct ppc_sse200_dev_t APB_PPC1_DEV_S;
#endif
#ifdef APB_PPCEXP0_S
#include "ppc_sse200_drv.h"
extern struct ppc_sse200_dev_t APB_PPCEXP0_DEV_S;
#endif
#ifdef APB_PPCEXP1_S
#include "ppc_sse200_drv.h"
extern struct ppc_sse200_dev_t APB_PPCEXP1_DEV_S;
#endif
/* ======= External peripheral configuration structure declarations ======= */
/* MT25QL Flash memory library structures */
#if (defined(MT25QL_S) && defined(QSPI_IP6514E_S))
#include "mt25ql_flash_lib.h"
extern struct mt25ql_dev_t MT25QL_DEV_S;
#endif
#if (defined(MT25QL_NS) && defined(QSPI_IP6514E_NS))
#include "mt25ql_flash_lib.h"
extern struct mt25ql_dev_t MT25QL_DEV_NS;
#endif
#ifdef __cplusplus
}
#endif
#endif /* __DEVICE_DEFINITION_H__ */

View File

@ -0,0 +1,340 @@
/*
* Copyright (c) 2017-2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file cache_drv.c
* \brief Driver for L1 instruction cache based on SSE-200 version r1p0
*/
#include "cache_drv.h"
/**
* \brief L1 cache register map structure
*/
struct _arm_cache_reg_map_t {
volatile uint32_t cacheichwparams;
/*!< Offset: 0x000 (R/ ) HW Parameters Register */
volatile uint32_t cacheicctrl;
/*!< Offset: 0x004 (R/W) Control Register */
volatile uint32_t reserved_0[62];
/*!< Offset: 0x00C-0x0FC Reserved */
volatile uint32_t cacheicirqstat;
/*!< Offset: 0x100 (R/ ) Interrupt Request Status Register */
volatile uint32_t cacheicirqsclr;
/*!< Offset: 0x104 ( /W) Interrupt Status Clear Register */
volatile uint32_t cacheicirqen;
/*!< Offset: 0x108 (R/W) Interrupt Enable Register */
volatile uint32_t cacheicdbgfillerr;
/*!< Offset: 0x10C (R/ ) Fill Error Address Register */
volatile uint32_t reserved_1[124];
/*!< Offset: 0x110-0x2FC Reserved */
volatile uint32_t cacheicsh;
/*!< Offset: 0x300 (R/ ) Cache Statistic Hit Register */
volatile uint32_t cacheicsm;
/*!< Offset: 0x304 (R/ ) Cache Statistic Miss Register */
volatile uint32_t cacheicsuc;
/*!< Offset: 0x308 (R/ ) Cache Statistic Uncached Register */
volatile uint32_t reserved_2[331];
/*!< Offset: 0x30C-0xFCC Reserved */
volatile uint32_t cachepidr4;
/*!< Offset: 0xFD0 (R/ ) Product ID Register 4 */
volatile uint32_t cachepidr5;
/*!< Offset: 0xFD4 (R/ ) Product ID Register 5 */
volatile uint32_t cachepidr6;
/*!< Offset: 0xFD8 (R/ ) Product ID Register 6 */
volatile uint32_t cachepidr7;
/*!< Offset: 0xFDC (R/ ) Product ID Register 7 */
volatile uint32_t cachepidr0;
/*!< Offset: 0xFE0 (R/ ) Product ID Register 0 */
volatile uint32_t cachepidr1;
/*!< Offset: 0xFE4 (R/ ) Product ID Register 1 */
volatile uint32_t cachepidr2;
/*!< Offset: 0xFE8 (R/ ) Product ID Register 2 */
volatile uint32_t cachepidr3;
/*!< Offset: 0xFEC (R/ ) Product ID Register 3 */
volatile uint32_t cachecidr0;
/*!< Offset: 0xFF0 (R/ ) Component ID Register 0 */
volatile uint32_t cachecidr1;
/*!< Offset: 0xFF4 (R/ ) Component ID Register 1 */
volatile uint32_t cachecidr2;
/*!< Offset: 0xFF8 (R/ ) Component ID Register 2 */
volatile uint32_t cachecidr3;
/*!< Offset: 0xFFC (R/ ) Component ID Register 3 */
};
#define ARM_CACHEICHWPARAMS_CSIZE_MASK (0xFu<<ARM_CACHEICHWPARAMS_CSIZE_OFF)
#define ARM_CACHEICHWPARAMS_STATS_MASK (0x1u<<ARM_CACHEICHWPARAMS_STATS_OFF)
#define ARM_CACHEICHWPARAMS_INVMAT_MASK (0x1u<<ARM_CACHEICHWPARAMS_INVMAT_OFF)
#define ARM_CACHEICCTRL_CACHEEN_MASK (0x1u<<ARM_CACHEICCTRL_CACHEEN_OFF)
#define ARM_CACHEICCTRL_PINV_MASK (0x1u<<ARM_CACHEICCTRL_PINV_OFF)
#define ARM_CACHEICCTRL_FINV_MASK (0x1u<<ARM_CACHEICCTRL_FINV_OFF)
#define ARM_CACHEICCTRL_STATEN_MASK (0x1u<<ARM_CACHEICCTRL_STATEN_OFF)
#define ARM_CACHEICCTRL_STATC_MASK (0x1u<<ARM_CACHEICCTRL_STATC_OFF)
#define ARM_CACHEICCTRL_HALLOC_MASK (0x1u<<ARM_CACHEICCTRL_HALLOC_OFF)
enum arm_cache_size_t arm_cache_get_size(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
enum arm_cache_size_t val = (enum arm_cache_size_t)
(p_cache->cacheichwparams & ARM_CACHEICHWPARAMS_CSIZE_MASK);
/**
* 9: 512 byte
* 10: 1 KB
* 11: 2 KB
* 12: 4 KB
* 13: 8 KB
* 14: 16 KB
* Other values are reserved, returning error
*/
if(val < arm_cache_size_512B || val > arm_cache_size_16KB) {
return arm_cache_size_err;
} else {
return val;
}
}
bool arm_cache_is_stat_func_available(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
return (bool)(p_cache->cacheichwparams & ARM_CACHEICHWPARAMS_STATS_MASK);
}
bool arm_cache_is_invalidate_cache_line_enabled(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
return (bool)(p_cache->cacheichwparams & ARM_CACHEICHWPARAMS_INVMAT_MASK);
}
void arm_cache_enable(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
p_cache->cacheicctrl |= ARM_CACHEICCTRL_CACHEEN_MASK;
return;
}
void arm_cache_enable_blocking(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
p_cache->cacheicctrl |= ARM_CACHEICCTRL_CACHEEN_MASK;
while(!(arm_cache_get_raw_intr_status(dev) & arm_cache_cec_intr_mask));
arm_cache_clear_intr(dev, arm_cache_cec_intr_mask);
return;
}
void arm_cache_disable(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
p_cache->cacheicctrl &= ~ARM_CACHEICCTRL_CACHEEN_MASK;
return;
}
void arm_cache_disable_blocking(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
p_cache->cacheicctrl &= ~ARM_CACHEICCTRL_CACHEEN_MASK;
while(!(arm_cache_get_raw_intr_status(dev) & arm_cache_cdc_intr_mask));
arm_cache_clear_intr(dev, arm_cache_cdc_intr_mask);
return;
}
bool arm_cache_is_enabled(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
return (bool)(p_cache->cacheicctrl & ARM_CACHEICCTRL_CACHEEN_MASK);
}
void arm_cache_full_invalidate(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
p_cache->cacheicctrl |= ARM_CACHEICCTRL_FINV_MASK;
return;
}
void arm_cache_full_invalidate_blocking(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
p_cache->cacheicctrl |= ARM_CACHEICCTRL_FINV_MASK;
while(!(arm_cache_get_raw_intr_status(dev) & arm_cache_ic_intr_mask));
arm_cache_clear_intr(dev, arm_cache_ic_intr_mask);
return;
}
void arm_cache_statistic_enable(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
p_cache->cacheicctrl |= ARM_CACHEICCTRL_STATEN_MASK;
return;
}
void arm_cache_statistic_disable(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
p_cache->cacheicctrl &= ~ARM_CACHEICCTRL_STATEN_MASK;
return;
}
void arm_cache_clear_statistic_value(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
p_cache->cacheicctrl |= ARM_CACHEICCTRL_STATC_MASK;
return;
}
void arm_cache_handler_alloc_enable(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
p_cache->cacheicctrl |= ARM_CACHEICCTRL_HALLOC_MASK;
return;
}
void arm_cache_handler_alloc_disable(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
p_cache->cacheicctrl &= ~ARM_CACHEICCTRL_HALLOC_MASK;
return;
}
void arm_cache_enable_intr(struct arm_cache_dev_t* dev,
enum arm_cache_intr_t mask)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
p_cache->cacheicirqen |= (uint32_t)(mask);
return;
}
void arm_cache_disable_intr(struct arm_cache_dev_t* dev,
enum arm_cache_intr_t mask)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
p_cache->cacheicirqen &= ~(uint32_t)(mask);
return;
}
void arm_cache_clear_intr(struct arm_cache_dev_t* dev,
enum arm_cache_intr_t mask)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
p_cache->cacheicirqsclr = (uint32_t)mask;
return;
}
enum arm_cache_intr_t arm_cache_get_masked_intr_status(
struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
return (enum arm_cache_intr_t)
(p_cache->cacheicirqstat & p_cache->cacheicirqen);
}
enum arm_cache_intr_t arm_cache_get_raw_intr_status(
struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
return (enum arm_cache_intr_t)(p_cache->cacheicirqstat);
}
uint32_t arm_cache_get_debug_fill_address(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
return p_cache->cacheicdbgfillerr;
}
uint32_t arm_cache_get_hit_count(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
return p_cache->cacheicsh;
}
uint32_t arm_cache_get_miss_count(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
return p_cache->cacheicsm;
}
uint32_t arm_cache_get_uncached_count(struct arm_cache_dev_t* dev)
{
struct _arm_cache_reg_map_t* p_cache =
(struct _arm_cache_reg_map_t*)dev->cfg->base;
return p_cache->cacheicsuc;
}

View File

@ -0,0 +1,381 @@
/*
* Copyright (c) 2017-2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file cache_drv.h
* \brief Driver for L1 instruction cache based on SSE-200 version r1p0
*/
#ifndef __ARM_CACHE_DRV_H__
#define __ARM_CACHE_DRV_H__
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief L1 cache configuration structure
*/
struct arm_cache_dev_cfg_t {
const uint32_t base; /*!< L1 cache base address */
};
/**
* \brief L1 cache device structure
*/
struct arm_cache_dev_t {
const struct arm_cache_dev_cfg_t* const cfg; /*!< L1 cache configuration */
};
#define ARM_CACHEICHWPARAMS_CSIZE_OFF 0x0u
/*!< Instruction cache size bit field offset */
#define ARM_CACHEICHWPARAMS_STATS_OFF 0x4u
/*!< Statistic functionality bit field offset */
#define ARM_CACHEICHWPARAMS_DMA_OFF 0x5u
/*!< DMA engine bit field offset */
#define ARM_CACHEICHWPARAMS_INVMAT_OFF 0x6u
/*!< Bit field offset to indicates whether
* invalidate cache line on write match is
* enabled */
#define ARM_CACHEICHWPARAMS_COFFSIZE_OFF 0xCu
/*!< Cacheable Block Size bit field offset */
#define ARM_CACHEICHWPARAMS_COFFSET_OFF 0x10u
/*!< Cacheable Offset Addr bit field offset */
#define ARM_CACHEICCTRL_CACHEEN_OFF 0x0u
/*!< Cache enable bit field offset */
#define ARM_CACHEICCTRL_FINV_OFF 0x2u
/*!< Full invalidate bit field offset */
#define ARM_CACHEICCTRL_STATEN_OFF 0x3u
/*!< Enable Statistic bit field offset */
#define ARM_CACHEICCTRL_STATC_OFF 0x4u
/*!< Clear Statistic bit field offset */
#define ARM_CACHEICCTRL_HALLOC_OFF 0x5u
/*!< Enable handler alloc bit field offset */
#define ARM_CACHE_INTR_IC_OFF 0x0u /*!< Invalidate Complete IRQ offset */
#define ARM_CACHE_INTR_CDC_OFF 0x1u /*!< Cache Disable Complete IRQ offset */
#define ARM_CACHE_INTR_CEC_OFF 0x2u /*!< Cache Enable Complete IRQ offset */
#define ARM_CACHE_INTR_CFE_OFF 0x3u /*!< Cache Fill Error IRQ offset */
#define ARM_CACHE_INTR_SV_OFF 0x4u /*!< Security violation IRQ offset */
#define ARM_CACHE_INTR_SS_OFF 0x5u /*!< Statistics Saturated IRQ offset */
/**
* \brief L1 Cache Interrupt data structure
*/
enum arm_cache_intr_t {
arm_cache_ic_intr_mask = (0x1u<<ARM_CACHE_INTR_IC_OFF),
/*!< Invalidate Complete IRQ Mask */
arm_cache_cdc_intr_mask = (0x1u<<ARM_CACHE_INTR_CDC_OFF),
/*!< Cache Disable Complete IRQ Mask */
arm_cache_cec_intr_mask = (0x1u<<ARM_CACHE_INTR_CEC_OFF),
/*!< Cache Enable Complete IRQ Mask */
arm_cache_cfe_intr_mask = (0x1u<<ARM_CACHE_INTR_CFE_OFF),
/*!< Cache Fill Error IRQ Mask */
arm_cache_sv_intr_mask = (0x1u<<ARM_CACHE_INTR_SV_OFF),
/*!< Security violation IRQ Mask */
arm_cache_ss_intr_mask = (0x1u<<ARM_CACHE_INTR_SS_OFF),
/*!< Statistics Saturated IRQ Mask */
};
/**
* \brief L1 Cache size data structure
*/
enum arm_cache_size_t {
arm_cache_size_err = 0, /*!< Invalid Cache size*/
arm_cache_size_512B = 9, /*!< Cache size 512 byte*/
arm_cache_size_1KB = 10, /*!< Cache size 1KB*/
arm_cache_size_2KB = 11, /*!< Cache size 2KB*/
arm_cache_size_4KB = 12, /*!< Cache size 4KB*/
arm_cache_size_8KB = 13, /*!< Cache size 8KB*/
arm_cache_size_16KB = 14, /*!< Cache size 16KB*/
};
/**
* \brief Returns cache size
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \return Returns cache size struct \ref arm_cache_size_t
*
* \note This function doesn't check if dev is NULL.
*/
enum arm_cache_size_t arm_cache_get_size(struct arm_cache_dev_t* dev);
/**
* \brief Check if statistic functionality is available in Icache
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \return Returns bool, true if statistic functionality is available,
* false otherwise
*
* \note This function doesn't check if dev is NULL.
*/
bool arm_cache_is_stat_func_available(struct arm_cache_dev_t* dev);
/**
* \brief Check if invalidate cache line on write match is enabled
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \return Returns bool, true if invalidate cache line is enabled,
* false otherwise
*
* \note This function doesn't check if dev is NULL.
*/
bool arm_cache_is_invalidate_cache_line_enabled(struct arm_cache_dev_t* dev);
/**
* \brief Enables cache in ARM SSE-200.
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void arm_cache_enable(struct arm_cache_dev_t* dev);
/**
* \brief Enables cache, returns when enable action is completed.
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \note Ensure that Cache Enable Interrupt is cleared before calling this API,
* \ref arm_cache_clear_intr()
* \note This is a blocking API, returns when the cache is enabled
* \note This function doesn't check if dev is NULL.
*/
void arm_cache_enable_blocking(struct arm_cache_dev_t* dev);
/**
* \brief Disables cache in ARM SSE-200.
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void arm_cache_disable(struct arm_cache_dev_t* dev);
/**
* \brief Disables cache, returns when disable action is completed.
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \note Ensure that Cache Disable Interrupt is cleared before calling this API,
* \ref arm_cache_clear_intr()
* \note This is a blocking API, returns when the cache is disabled
* \note This function doesn't check if dev is NULL.
*/
void arm_cache_disable_blocking(struct arm_cache_dev_t* dev);
/**
* \brief Check if cache is enabled.
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \return Returns bool, true if cache is enabled, false otherwise
*
* \note This function doesn't check if dev is NULL.
*/
bool arm_cache_is_enabled(struct arm_cache_dev_t* dev);
/**
* \brief Invalidates full cache in ARM SSE-200.
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \note Calling this API will trigger the Instruction cache to invalidate
* all cache lines.
* \note This function doesn't check if dev is NULL.
*/
void arm_cache_full_invalidate(struct arm_cache_dev_t* dev);
/**
* \brief Invalidates full cache, returns when invalidated action is completed.
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \note Ensure that Invalidate Complete Intr is cleared before calling this API
* \ref arm_cache_clear_intr()
* \note This is a blocking API, returns when the cache is invalidated
* \note Calling this API will trigger the Instruction cache to invalidate
* all cache lines.
* \note This function doesn't check if dev is NULL.
*/
void arm_cache_full_invalidate_blocking(struct arm_cache_dev_t* dev);
/**
* \brief Enables statistic function for cache in ARM SSE-200.
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void arm_cache_statistic_enable(struct arm_cache_dev_t* dev);
/**
* \brief Disables statistic function for cache in ARM SSE-200.
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void arm_cache_statistic_disable(struct arm_cache_dev_t* dev);
/**
* \brief Clear statistic values for cache in ARM SSE-200.
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void arm_cache_clear_statistic_value(struct arm_cache_dev_t* dev);
/**
* \brief Enables handler allocation function for cache in ARM SSE-200.
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void arm_cache_handler_alloc_enable(struct arm_cache_dev_t* dev);
/**
* \brief Disables handler allocation function for cache in ARM SSE-200.
*
* \param[in] dev L1 cache device struct \ref arm_cache_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void arm_cache_handler_alloc_disable(struct arm_cache_dev_t* dev);
/**
* \brief Enables cache interrupts
*
* \param[in] dev Cache device struct \ref arm_cache_dev_t
* \param[in] mask Bit mask for enabling interrupts \ref arm_cache_intr_t
*
* \note User is responsible to set mask accordingly. Mask set to 0 will not
* have any effect.
* \note User is responsible to configure the interrupt vector and
* the interrupt controller.
* \note This function doesn't check if dev is NULL.
*/
void arm_cache_enable_intr(struct arm_cache_dev_t* dev,
enum arm_cache_intr_t mask);
/**
* \brief Disables cache interrupts
*
* \param[in] dev Cache device struct \ref arm_cache_dev_t
* \param[in] mask Bit mask for disabling interrupts \ref arm_cache_intr_t
*
* \note User is responsible to set mask accordingly. Mask set to 0 will not
* have any effect.
* \note This function doesn't check if dev is NULL.
*/
void arm_cache_disable_intr(struct arm_cache_dev_t* dev,
enum arm_cache_intr_t mask);
/**
* \brief Clears cache Interrupt
*
* \param[in] dev Cache device struct \ref arm_cache_dev_t
* \param[in] mask Bit mask for clearing interrupts \ref arm_cache_intr_t
*
* \note This function doesn't check if dev is NULL.
*/
void arm_cache_clear_intr(struct arm_cache_dev_t* dev,
enum arm_cache_intr_t mask);
/**
* \brief Returns the cache Masked interrupt status
*
* \param[in] dev Cache device struct \ref arm_cache_dev_t
*
* \return Masked interrupt status \ref arm_cache_intr_t
*
* \note This function doesn't check if dev is NULL.
*/
enum arm_cache_intr_t arm_cache_get_masked_intr_status(
struct arm_cache_dev_t* dev);
/**
* \brief Returns the cache Raw interrupt status
*
* \param[in] dev Cache device struct \ref arm_cache_dev_t
*
* \return Raw interrupt status \ref arm_cache_intr_t
*
* \note This function doesn't check if dev is NULL.
*/
enum arm_cache_intr_t arm_cache_get_raw_intr_status(
struct arm_cache_dev_t* dev);
/**
* \brief Returns the debug fill error address
*
* \param[in] dev Cache device struct \ref arm_cache_dev_t
*
* \return Address that is involved in a recent fill error
*
* \note This function doesn't check if dev is NULL.
*/
uint32_t arm_cache_get_debug_fill_address(struct arm_cache_dev_t* dev);
/**
* \brief Returns the Icache hit counter value
*
* \param[in] dev Cache device struct \ref arm_cache_dev_t
*
* \return Icache hit counter value since the last counter clear operation
*
* \note This function doesn't check if dev is NULL.
*/
uint32_t arm_cache_get_hit_count(struct arm_cache_dev_t* dev);
/**
* \brief Returns the Icache miss counter value
*
* \param[in] dev Cache device struct \ref arm_cache_dev_t
*
* \return Icache miss counter value since the last counter clear operation
*
* \note This function doesn't check if dev is NULL.
*/
uint32_t arm_cache_get_miss_count(struct arm_cache_dev_t* dev);
/**
* \brief Returns the Icache uncached access counter value
*
* \param[in] dev Cache device struct \ref arm_cache_dev_t
*
* \return Icache uncached counter value since the last counter clear operation
*
* \note This function doesn't check if dev is NULL.
*/
uint32_t arm_cache_get_uncached_count(struct arm_cache_dev_t* dev);
#ifdef __cplusplus
}
#endif
#endif /* __ARM_CACHE_DRV_H__ */

View File

@ -0,0 +1,326 @@
/*
* Copyright (c) 2016-2018 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
#include <stddef.h>
#include "gpio_cmsdk_drv.h"
/* GPIO register map structure */
struct gpio_cmsdk_reg_map_t {
volatile uint32_t data; /* Offset: 0x000 (R/W) Data register */
volatile uint32_t dataout; /* Offset: 0x004 (R/W) Data output
* latch register */
volatile uint32_t reserved0[2];
volatile uint32_t outenableset; /* Offset: 0x010 (R/W) Output enable
* set register */
volatile uint32_t outenableclr; /* Offset: 0x014 (R/W) Output enable
* clear register */
volatile uint32_t altfuncset; /* Offset: 0x018 (R/W) Alternate function
* set register */
volatile uint32_t altfuncclr; /* Offset: 0x01C (R/W) Alternate function
* clear register */
volatile uint32_t intenset; /* Offset: 0x020 (R/W) Interrupt enable
* set register */
volatile uint32_t intenclr; /* Offset: 0x024 (R/W) Interrupt enable
* clear register */
volatile uint32_t inttypeset; /* Offset: 0x028 (R/W) Interrupt type
* set register */
volatile uint32_t inttypeclr; /* Offset: 0x02C (R/W) Interrupt type
* clear register */
volatile uint32_t intpolset; /* Offset: 0x030 (R/W) Interrupt polarity
* set register */
volatile uint32_t intpolclr; /* Offset: 0x034 (R/W) Interrupt polarity
* clear register */
union {
volatile uint32_t intstatus; /* Offset: 0x038 (R/ ) Interrupt status
* register */
volatile uint32_t intclear; /* Offset: 0x038 ( /W) Interrupt clear
* register */
}intreg;
volatile uint32_t reserved1[997];
volatile uint32_t pid4; /* Peripheral ID Register 4 */
volatile uint32_t pid0; /* Peripheral ID Register 0 */
volatile uint32_t pid1; /* Peripheral ID Register 1 */
volatile uint32_t pid2; /* Peripheral ID Register 2 */
volatile uint32_t pid3; /* Peripheral ID Register 3 */
volatile uint32_t cid0; /* Component ID Register 0 */
volatile uint32_t cid1; /* Component ID Register 1 */
volatile uint32_t cid2; /* Component ID Register 2 */
volatile uint32_t cid4; /* Component ID Register 3 */
};
void gpio_cmsdk_init(struct gpio_cmsdk_dev_t* dev)
{
/* Nothing to init on the GPIO device */
}
/**
* \brief Configures port.
*
* \param[in] dev GPIO device to initalize \ref gpio_cmsdk_dev_t
* \param[in] pin_mask Pin mask for port access
* \param[in] direction Input or output \ref gpio_cmsdk_direction_t
* \param[in] altfunc_flags Alternate function \ref gpio_cmsdk_altfunc_t
*
*/
static void set_port_config(struct gpio_cmsdk_dev_t* dev, uint32_t pin_mask,
enum gpio_cmsdk_direction_t direction,
enum gpio_cmsdk_altfunc_t altfunc_flags)
{
struct gpio_cmsdk_reg_map_t* p_gpio_port =
(struct gpio_cmsdk_reg_map_t*)dev->cfg->base;
if(direction == GPIO_CMSDK_INPUT) {
p_gpio_port->outenableclr = pin_mask;
} else {
p_gpio_port->outenableset = pin_mask;
}
if (altfunc_flags == GPIO_CMSDK_MAIN_FUNC) {
p_gpio_port->altfuncclr = pin_mask;
} else {
p_gpio_port->altfuncset = pin_mask;
}
return;
}
enum gpio_cmsdk_error_t
gpio_cmsdk_pin_config(struct gpio_cmsdk_dev_t* dev, uint32_t pin_num,
enum gpio_cmsdk_direction_t direction,
enum gpio_cmsdk_altfunc_t altfunc_flags)
{
uint32_t pin_mask = (1UL << pin_num);
if(pin_num >= GPIO_CMSDK_MAX_PIN_NUM) {
return GPIO_CMSDK_ERR_INVALID_ARG;
}
set_port_config(dev, pin_mask, direction, altfunc_flags);
return GPIO_CMSDK_ERR_NONE;
}
enum gpio_cmsdk_error_t
gpio_cmsdk_port_config(struct gpio_cmsdk_dev_t* dev, uint32_t pin_mask,
enum gpio_cmsdk_direction_t direction,
enum gpio_cmsdk_altfunc_t altfunc_flags)
{
if(pin_mask > GPIO_CMSDK_MAX_PORT_MASK) {
return GPIO_CMSDK_ERR_INVALID_ARG;
}
set_port_config(dev, pin_mask, direction, altfunc_flags);
return GPIO_CMSDK_ERR_NONE;
}
void gpio_cmsdk_config_irq(struct gpio_cmsdk_dev_t* dev, uint32_t pin_mask,
enum gpio_cmsdk_irq_type_t irq_type,
enum gpio_cmsdk_irq_polarity_t irq_pol)
{
struct gpio_cmsdk_reg_map_t* p_gpio_port =
(struct gpio_cmsdk_reg_map_t*)dev->cfg->base;
/* Interrupt type: EDGE = 1 - LEVEL = 0 */
if(irq_type == GPIO_CMSDK_IRQ_EDGE) {
p_gpio_port->inttypeset = pin_mask;
} else if(irq_type == GPIO_CMSDK_IRQ_LEVEL) {
p_gpio_port->inttypeclr = pin_mask;
}
/* Interrupt polarity */
if(irq_pol == GPIO_CMSDK_IRQ_LOW_OR_FALLING_EDGE) {
p_gpio_port->intpolclr = pin_mask;
} else if(irq_pol == GPIO_CMSDK_IRQ_HIGH_OR_RISING_EDGE) {
p_gpio_port->intpolset = pin_mask;
}
}
enum gpio_cmsdk_error_t gpio_cmsdk_pin_write(struct gpio_cmsdk_dev_t* dev,
uint32_t pin_num,
uint32_t value)
{
struct gpio_cmsdk_reg_map_t* p_gpio_port =
(struct gpio_cmsdk_reg_map_t*)dev->cfg->base;
/* GPIO data output register is a read-modify-write register,
* so before writing a value on a GPIO pin it is required to disable
* the interrupts to prevent concurrency problems.
*/
if(pin_num >= GPIO_CMSDK_MAX_PIN_NUM) {
return GPIO_CMSDK_ERR_INVALID_ARG;
}
if(value) {
/* Sets the pin */
p_gpio_port->dataout |= (1UL << pin_num);
} else {
/* Clears the pin */
p_gpio_port->dataout &= ~(1UL << pin_num);
}
return GPIO_CMSDK_ERR_NONE;
}
enum gpio_cmsdk_error_t gpio_cmsdk_port_write(struct gpio_cmsdk_dev_t* dev,
uint32_t pin_mask,
uint32_t value)
{
struct gpio_cmsdk_reg_map_t* p_gpio_port =
(struct gpio_cmsdk_reg_map_t*)dev->cfg->base;
/* GPIO data output register is a read-modify-write register,
* so before writing a value on a GPIO pin it is required to disable
* the interrupts to prevent concurrency problems.
*/
if(pin_mask > GPIO_CMSDK_MAX_PORT_MASK) {
return GPIO_CMSDK_ERR_INVALID_ARG;
}
/* Clear all bits defined in the mask,
* and set selected bits from value parameter.
*/
p_gpio_port->dataout =
((~pin_mask & p_gpio_port->dataout) | (pin_mask & value));
return GPIO_CMSDK_ERR_NONE;
}
enum gpio_cmsdk_error_t
gpio_cmsdk_pin_read(struct gpio_cmsdk_dev_t* dev,
uint32_t pin_num,
uint32_t *data)
{
uint32_t value;
struct gpio_cmsdk_reg_map_t* p_gpio_port =
(struct gpio_cmsdk_reg_map_t*)dev->cfg->base;
if(pin_num >= GPIO_CMSDK_MAX_PIN_NUM) {
return GPIO_CMSDK_ERR_INVALID_ARG;
}
value = p_gpio_port->data;
*data = (value >> pin_num) & 1UL;
return GPIO_CMSDK_ERR_NONE;
}
enum gpio_cmsdk_error_t
gpio_cmsdk_port_read(struct gpio_cmsdk_dev_t* dev, uint32_t pin_mask,
uint32_t *data)
{
struct gpio_cmsdk_reg_map_t* p_gpio_port =
(struct gpio_cmsdk_reg_map_t*)dev->cfg->base;
if(pin_mask > GPIO_CMSDK_MAX_PORT_MASK) {
return GPIO_CMSDK_ERR_INVALID_ARG;
}
*data = p_gpio_port->data & pin_mask;
return GPIO_CMSDK_ERR_NONE;
}
enum gpio_cmsdk_error_t
gpio_cmsdk_set_pin_irq_cfg(struct gpio_cmsdk_dev_t* dev, uint32_t pin_num,
enum gpio_cmsdk_irq_status_t status)
{
struct gpio_cmsdk_reg_map_t* p_gpio_port =
(struct gpio_cmsdk_reg_map_t*)dev->cfg->base;
if(pin_num >= GPIO_CMSDK_MAX_PIN_NUM) {
return GPIO_CMSDK_ERR_INVALID_ARG;
}
if(status == GPIO_CMSDK_IRQ_ENABLE) {
p_gpio_port->intenset = (1UL << pin_num);
} else {
p_gpio_port->intenclr = (1UL << pin_num);
}
return GPIO_CMSDK_ERR_NONE;
}
enum gpio_cmsdk_error_t
gpio_cmsdk_set_port_irq_cfg(struct gpio_cmsdk_dev_t* dev, uint32_t pin_mask,
enum gpio_cmsdk_irq_status_t status)
{
struct gpio_cmsdk_reg_map_t* p_gpio_port =
(struct gpio_cmsdk_reg_map_t*)dev->cfg->base;
if(pin_mask > GPIO_CMSDK_MAX_PORT_MASK) {
return GPIO_CMSDK_ERR_INVALID_ARG;
}
if(status == GPIO_CMSDK_IRQ_ENABLE) {
p_gpio_port->intenset = pin_mask;
} else {
p_gpio_port->intenclr = pin_mask;
}
return GPIO_CMSDK_ERR_NONE;
}
enum gpio_cmsdk_error_t
gpio_cmsdk_get_pin_irq_status(struct gpio_cmsdk_dev_t* dev,
uint32_t pin_num, uint32_t* status)
{
struct gpio_cmsdk_reg_map_t* p_gpio_port =
(struct gpio_cmsdk_reg_map_t*)dev->cfg->base;
if(pin_num >= GPIO_CMSDK_MAX_PIN_NUM) {
return GPIO_CMSDK_ERR_INVALID_ARG;
}
*status = ((p_gpio_port->intreg.intstatus >> pin_num) & 1UL);
return GPIO_CMSDK_ERR_NONE;
}
enum gpio_cmsdk_error_t
gpio_cmsdk_get_port_irq_status(struct gpio_cmsdk_dev_t* dev,
uint32_t pin_mask, uint32_t* status)
{
struct gpio_cmsdk_reg_map_t* p_gpio_port =
(struct gpio_cmsdk_reg_map_t*)dev->cfg->base;
if(pin_mask > GPIO_CMSDK_MAX_PORT_MASK) {
return GPIO_CMSDK_ERR_INVALID_ARG;
}
*status = (p_gpio_port->intreg.intstatus & pin_mask);
return GPIO_CMSDK_ERR_NONE;
}
enum gpio_cmsdk_error_t gpio_cmsdk_clear_irq(struct gpio_cmsdk_dev_t* dev,
uint8_t pin_num)
{
struct gpio_cmsdk_reg_map_t* p_gpio_port =
(struct gpio_cmsdk_reg_map_t*)dev->cfg->base;
if(pin_num >= GPIO_CMSDK_MAX_PIN_NUM) {
return GPIO_CMSDK_ERR_INVALID_ARG;
}
p_gpio_port->intreg.intclear = (1UL << pin_num);
return GPIO_CMSDK_ERR_NONE;
}

View File

@ -0,0 +1,281 @@
/*
* Copyright (c) 2016-2018 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file gpio_cmsdk_drv.h
* \brief Generic driver for ARM GPIO.
*/
#ifndef __GPIO_CMSDK_DRV_H__
#define __GPIO_CMSDK_DRV_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define GPIO_CMSDK_MAX_PIN_NUM 16U
#define GPIO_CMSDK_MAX_PORT_MASK ((1U << GPIO_CMSDK_MAX_PIN_NUM) - 1U)
/* GPIO enumeration types */
enum gpio_cmsdk_direction_t {
GPIO_CMSDK_INPUT = 0, /*!< GPIO is input */
GPIO_CMSDK_OUTPUT /*!< GPIO is output */
};
enum gpio_cmsdk_altfunc_t {
GPIO_CMSDK_MAIN_FUNC = 0, /*!< Alternate function is not enabled */
GPIO_CMSDK_ALT_FUNC /*!< Alternate function is enabled */
};
enum gpio_cmsdk_irq_status_t {
GPIO_CMSDK_IRQ_DISABLE = 0, /*!< Disable interruptions */
GPIO_CMSDK_IRQ_ENABLE /*!< Enable interruptions */
};
enum gpio_cmsdk_irq_type_t {
GPIO_CMSDK_IRQ_LEVEL = 0, /*!< Level Interrupt */
GPIO_CMSDK_IRQ_EDGE /*!< Edge Interrupt */
};
enum gpio_cmsdk_irq_polarity_t {
GPIO_CMSDK_IRQ_LOW_OR_FALLING_EDGE = 0, /*!< Interrupt active low or
falling edge */
GPIO_CMSDK_IRQ_HIGH_OR_RISING_EDGE /*!< Interrupt active high or
rising edge */
};
enum gpio_cmsdk_error_t {
GPIO_CMSDK_ERR_NONE = 0, /*!< No error */
GPIO_CMSDK_ERR_INVALID_ARG, /*!< Error invalid input argument */
GPIO_CMSDK_ALTFUNC_EERROR, /*!< Alternate function returned error */
};
/* CMSDK GPIO device configuration structure */
struct gpio_cmsdk_dev_cfg_t {
const uint32_t base; /*!< GPIO base address */
};
/* CMSDK GPIO device structure */
struct gpio_cmsdk_dev_t {
const struct gpio_cmsdk_dev_cfg_t* const cfg; /*!< GPIO configuration */
};
/**
* \brief Initializes GPIO port.
*
* \param[in] dev GPIO device to initalize \ref gpio_cmsdk_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void gpio_cmsdk_init(struct gpio_cmsdk_dev_t* dev);
/**
* \brief Configures pin.
*
* \param[in] dev GPIO device to configure \ref gpio_cmsdk_dev_t
* \param[in] pin_num Pin number for pin access
* \param[in] direction Input or output \ref gpio_cmsdk_direction_t
* \param[in] altfunc_flags Alternate function \ref gpio_cmsdk_altfunc_t
*
* \return Returns error code as specified in \ref gpio_cmsdk_flags_t
*
* \note This function doesn't check if dev is NULL.
*/
enum gpio_cmsdk_error_t
gpio_cmsdk_pin_config(struct gpio_cmsdk_dev_t* dev, uint32_t pin_num,
enum gpio_cmsdk_direction_t direction,
enum gpio_cmsdk_altfunc_t altfunc_flags);
/**
* \brief Configures port.
*
* \param[in] dev GPIO device to configure \ref gpio_cmsdk_dev_t
* \param[in] pin_mask Bitmask of the selected pins
* \param[in] direction Input or output \ref gpio_cmsdk_direction_t
* \param[in] altfunc_flags Alternate function \ref gpio_cmsdk_altfunc_t
*
* \return Returns error code as specified in \ref gpio_cmsdk_error_t
*
* \note This function doesn't check if dev is NULL.
*/
enum gpio_cmsdk_error_t
gpio_cmsdk_port_config(struct gpio_cmsdk_dev_t* dev, uint32_t pin_mask,
enum gpio_cmsdk_direction_t direction,
enum gpio_cmsdk_altfunc_t altfunc_flags);
/**
* \brief Configures interrupt type
*
* \param[in] dev GPIO device to initalize \ref gpio_cmsdk_dev_t
* \param[in] pin_mask Bitmask of the selected pins
* \param[in] irq_type Interrupt type \ref gpio_cmsdk_irq_type_t
* \param[in] irq_pol Interrupt polarity \ref gpio_cmsdk_irq_polarity_t
*
* \note This function doesn't check if dev is NULL.
*/
void gpio_cmsdk_config_irq(struct gpio_cmsdk_dev_t* dev, uint32_t pin_mask,
enum gpio_cmsdk_irq_type_t irq_type,
enum gpio_cmsdk_irq_polarity_t irq_pol);
/**
* \brief Sets state of the output pin.
*
* \param[in] dev GPIO device to use for the pin \ref gpio_cmsdk_dev_t
* \param[in] pin_num Pin number for pin access
* \param[in] value Value(s) to set.
*
* \return Returns error code as specified in \ref gpio_cmsdk_error_t
*
* \note This function doesn't check if dev is NULL.
* \note GPIO data output register is a read-modify-write register,
* so before writing a value on a GPIO pin it is required to disable
* the interrupts to prevent concurrency problems.
*/
enum gpio_cmsdk_error_t gpio_cmsdk_pin_write(struct gpio_cmsdk_dev_t* dev,
uint32_t pin_num,
uint32_t value);
/**
* \brief Sets state of the output port.
*
* \param[in] dev GPIO device to use for the pins \ref gpio_cmsdk_dev_t
* \param[in] pin_mask Bitmask of the selected pins
* \param[in] value Bitmask of pins states to set
*
* \return Returns error code as specified in \ref gpio_cmsdk_error_t
*
* \note This function doesn't check if dev is NULL.
* \note GPIO data output register is a read-modify-write register,
* so before writing a value on a GPIO pin it is required to disable
* the interrupts to prevent concurrency problems.
*/
enum gpio_cmsdk_error_t gpio_cmsdk_port_write(struct gpio_cmsdk_dev_t* dev,
uint32_t pin_mask,
uint32_t value);
/**
* \brief Reads the pin status.
*
* \param[in] dev GPIO device to use for the pin \ref gpio_cmsdk_dev_t
* \param[in] pin_num Pin number for pin access
* \param[out] data Bit value read from the IO pin
*
* \return Returns error code as specified in \ref gpio_cmsdk_error_t
*
* \note This function doesn't check if dev is NULL.
*/
enum gpio_cmsdk_error_t
gpio_cmsdk_pin_read(struct gpio_cmsdk_dev_t* dev, uint32_t pin_num, uint32_t *data);
/**
* \brief Reads the port status.
*
* \param[in] dev GPIO device to use for the pins \ref gpio_cmsdk_dev_t
* \param[in] pin_mask Bitmask of the selected pins
* \param[out] data Bit values for the mask read from the IO pin
*
* \return Returns error code as specified in \ref gpio_cmsdk_error_t
*
* \note This function doesn't check if dev is NULL.
*/
enum gpio_cmsdk_error_t
gpio_cmsdk_port_read(struct gpio_cmsdk_dev_t* dev, uint32_t pin_mask,
uint32_t *data);
/**
* \brief Enables/disables interrupt for the given pin.
*
* \param[in] dev GPIO device to initalize \ref gpio_cmsdk_dev_t
* \param[in] pin_num Pin number to configure
* \param[in] status Interrupt status \ref gpio_cmsdk_irq_status
*
* \return Returns error code as specified in \ref gpio_cmsdk_error_t
*
* \note This function doesn't check if dev is NULL.
*/
enum gpio_cmsdk_error_t
gpio_cmsdk_set_pin_irq_cfg(struct gpio_cmsdk_dev_t* dev, uint32_t pin_num,
enum gpio_cmsdk_irq_status_t status);
/**
* \brief Enables/disables interrupt for the given pins.
*
* \param[in] dev GPIO device to use for the pins \ref gpio_cmsdk_dev_t
* \param[in] pin_mask Bitmask of the pins to configure
* \param[in] status Interrupt status \ref gpio_cmsdk_irq_status
*
* \return Returns error code as specified in \ref gpio_cmsdk_error_t
*
* \note This function doesn't check if dev is NULL.
*/
enum gpio_cmsdk_error_t
gpio_cmsdk_set_port_irq_cfg(struct gpio_cmsdk_dev_t* dev, uint32_t pin_mask,
enum gpio_cmsdk_irq_status_t status);
/**
* \brief Get interrupt status for the given pin.
*
* \param[in] dev GPIO device to use for the pin \ref gpio_cmsdk_dev_t
* \param[in] pin_num Pin number for the access
* \param[out] status Interrupt status values. If the access is by pin, then
* the status will be 0 or 1.
*
* \return Returns error code as specified in \ref gpio_cmsdk_error_t
*
* \note This function doesn't check if dev is NULL.
*/
enum gpio_cmsdk_error_t
gpio_cmsdk_get_pin_irq_status(struct gpio_cmsdk_dev_t* dev,
uint32_t pin_num, uint32_t* status);
/**
* \brief Get interrupt status for the given port.
*
* \param[in] dev GPIO device to use for the pins \ref gpio_cmsdk_dev_t
* \param[in] pin_mask Bitmask of the pins to configure
* \param[out] status Interrupt status values. If the access is by pin,
* then the status will be 0 or 1.
*
* \return Returns error code as specified in \ref gpio_cmsdk_error_t
*
* \note This function doesn't check if dev is NULL.
*/
enum gpio_cmsdk_error_t
gpio_cmsdk_get_port_irq_status(struct gpio_cmsdk_dev_t* dev,
uint32_t pin_mask, uint32_t* status);
/**
* \brief Clears gpio interrupt.
*
* \param[in] dev GPIO device to initalize \ref gpio_cmsdk_dev_t
* \param[in] pin_num Pin number.
*
* \return Returns error code as specified in \ref gpio_cmsdk_error_t
*
* \note This function doesn't check if dev is NULL.
*/
enum gpio_cmsdk_error_t gpio_cmsdk_clear_irq(struct gpio_cmsdk_dev_t* dev,
uint8_t pin_num);
#ifdef __cplusplus
}
#endif
#endif /* __GPIO_CMSDK_DRV_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,649 @@
/*
* Copyright (c) 2018-2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file i2c_ip6510_drv.h
* \brief Driver for IP6510 I2C controller.
*/
#ifndef __I2C_IP6510_DRV_H__
#define __I2C_IP6510_DRV_H__
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief I2C (IP6510) device state types.
*/
enum i2c_ip6510_state_t {
I2C_IP6510_UNINITIALIZED = 0u,
I2C_IP6510_INITIALIZED = 1u,
};
/**
* \brief I2C (IP6510) bus state types.
*/
enum i2c_ip6510_bus_state_t {
I2C_IP6510_BUS_INACTIVE = 0u,
I2C_IP6510_BUS_ACTIVE = 1u,
};
/**
* \brief Allowed transfer direction options.
*/
enum i2c_ip6510_transf_dir_t {
I2C_IP6510_TRANSMITTER = 0u,
I2C_IP6510_RECEIVER = 1u,
};
/**
* \brief Supported I2C (IP6510) device mode options.
*/
enum i2c_ip6510_device_mode_t {
I2C_IP6510_SLAVE_MODE = 0u,
I2C_IP6510_MASTER_MODE = 1u,
};
/**
* \brief Supported I2C (IP6510) addressing options.
*/
enum i2c_ip6510_addr_mode_t {
I2C_IP6510_EXT_ADDR_MODE = 0u,
I2C_IP6510_NOR_ADDR_MODE = 1u,
};
/**
* \brief Supported I2C (IP6510) bus data rate options.
*/
enum i2c_ip6510_speed_t {
I2C_IP6510_SPEED_100KHZ = 0u,
I2C_IP6510_SPEED_400KHZ = 1u,
I2C_IP6510_SPEED_MAX_SUPPORTED = 2u,
};
#define I2C_IP6510_INTR_COMP_OFF (0u)
/*!< Transfer complete interrupt bit field offset */
#define I2C_IP6510_INTR_DATA_OFF (1u)
/*!< More data interrupt bit field offset */
#define I2C_IP6510_INTR_NACK_OFF (2u)
/*!< Transfer not ACKed interrupt bit field offset */
#define I2C_IP6510_INTR_TO_OFF (3u)
/*!< Transfer time out interrupt bit field offset */
#define I2C_IP6510_INTR_SLVRDY_OFF (4u)
/*!< Monitored slave ready interrupt bit field offset */
#define I2C_IP6510_INTR_RXOVF_OFF (5u)
/*!< Receive overflow interrupt bit field offset */
#define I2C_IP6510_INTR_TXOVF_OFF (6u)
/*!< FIFO transmit overflow interrupt bit field offset */
#define I2C_IP6510_INTR_RXUNF_OFF (7u)
/*!< FIFO receive underflow interrupt bit field offset */
#define I2C_IP6510_INTR_ARBLOST_OFF (9u)
/*!< Arbitration lost interrupt bit field offset */
#define I2C_IP6510_ALL_INTR_MASK (0x2FFu)
/**
* \brief I2C (IP6510) interrupt data structure
*/
enum i2c_ip6510_intr_t {
I2C_IP6510_INTR_COMP_MASK = (0x1u<<I2C_IP6510_INTR_COMP_OFF),
I2C_IP6510_INTR_DATA_MASK = (0x1u<<I2C_IP6510_INTR_DATA_OFF),
I2C_IP6510_INTR_NACK_MASK = (0x1u<<I2C_IP6510_INTR_NACK_OFF),
I2C_IP6510_INTR_TO_MASK = (0x1u<<I2C_IP6510_INTR_TO_OFF),
I2C_IP6510_INTR_SLVRDY_MASK = (0x1u<<I2C_IP6510_INTR_SLVRDY_OFF),
I2C_IP6510_INTR_RXOVF_MASK = (0x1u<<I2C_IP6510_INTR_RXOVF_OFF),
I2C_IP6510_INTR_TXOVF_MASK = (0x1u<<I2C_IP6510_INTR_TXOVF_OFF),
I2C_IP6510_INTR_RXUNF_MASK = (0x1u<<I2C_IP6510_INTR_RXUNF_OFF),
I2C_IP6510_INTR_ARBLOST_MASK = (0x1u<<I2C_IP6510_INTR_ARBLOST_OFF),
};
/**
* \brief I2C (IP6510) error enumeration types.
*/
enum i2c_ip6510_error_t {
I2C_IP6510_ERR_NONE = 0u,
I2C_IP6510_ERR_NOT_INIT = 1u,
I2C_IP6510_ERR_ALREADY_INIT = 2u,
I2C_IP6510_ERR_INVALID_ARG = 3u,
I2C_IP6510_ERR_NACK = 4u,
I2C_IP6510_ERR_RXOVF = 5u,
I2C_IP6510_ERR_TXOVF = 6u,
I2C_IP6510_ERR_RXUNF = 7u,
I2C_IP6510_ERR_TIMEOUT = 8u,
I2C_IP6510_ERR = 9u,
};
/**
* \brief I2C (IP6510) device configuration structure.
*/
struct i2c_ip6510_dev_cfg_t {
const uint32_t base;
/*!< I2C device base address */
const enum i2c_ip6510_speed_t default_bus_speed;
/*!< I2C bus data rate */
const enum i2c_ip6510_device_mode_t default_mode;
/*!< I2C device mode (Master/Slave) */
};
/**
* \brief I2C (IP6510) device data structure.
*/
struct i2c_ip6510_dev_data_t {
enum i2c_ip6510_state_t state; /*!< I2C device state */
enum i2c_ip6510_device_mode_t mode; /*!< I2C device mode (Master/Slave) */
enum i2c_ip6510_speed_t bus_speed; /*!< I2C bus operational data rate */
uint32_t sys_clk; /*!< System clock frequency */
};
/**
* \brief I2C (IP6510) device structure.
*/
struct i2c_ip6510_dev_t {
const struct i2c_ip6510_dev_cfg_t* const cfg;
/*!< I2C (IP6510) configuration structure */
struct i2c_ip6510_dev_data_t* const data;
/*!< I2C (IP6510) data structure */
};
/**
* \brief Initializes I2C (IP6510) device.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] sys_clk System clock frequency used by the device.
*
* It configures the interface as I2C Master with the default data rate
* and disables every I2C interrupts.
*
* \return Returns error code as specified in \ref i2c_ip6510_error_t
*
* \note This API should be called before calling any of the below I2C APIs.
* \note This function doesn't check if dev is NULL.
*/
enum i2c_ip6510_error_t i2c_ip6510_init(struct i2c_ip6510_dev_t* dev,
uint32_t sys_clk);
/**
* \brief Uninitializes I2C (IP6510) device and resets registers.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void i2c_ip6510_uninit(struct i2c_ip6510_dev_t* dev);
/**
* \brief Enables Hold mode.
*
* Sets hold bit, so the master does not terminate automatically a read or
* write transfer.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void i2c_ip6510_hold_enable(const struct i2c_ip6510_dev_t* dev);
/**
* \brief Disables Hold mode.
*
* Resets hold bit, so the master can terminate automatically a read or
* write transfer.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void i2c_ip6510_hold_disable(const struct i2c_ip6510_dev_t* dev);
/**
* \brief Returns the I2C (IP6510) device operational state.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
*
* \return Returns the I2C (IP6510) device state \ref i2c_ip6510_state_t
*
* \note This function doesn't check if dev is NULL.
*/
enum i2c_ip6510_state_t i2c_ip6510_get_state(
const struct i2c_ip6510_dev_t* dev);
/**
* \brief Returns the I2C interface mode.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
*
* \return Returns the I2C interface mode \ref i2c_ip6510_device_mode_t
*
* \note This function doesn't check if dev is NULL.
*/
enum i2c_ip6510_device_mode_t i2c_ip6510_get_device_mode(
const struct i2c_ip6510_dev_t* dev);
/**
* \brief Sets the I2C data rate.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] speed New I2C data rate \ref i2c_ip6510_speed_t
*
* \return Returns error code as specified in \ref i2c_ip6510_error_t
*
* \note The I2C device should be in valid state before calling this API.
* \ref i2c_ip6510_get_state should return I2C_IP6510_INITIALIZED.
* \note This function doesn't check if dev is NULL.
*/
enum i2c_ip6510_error_t i2c_ip6510_set_speed(struct i2c_ip6510_dev_t* dev,
enum i2c_ip6510_speed_t speed);
/**
* \brief Returns the actual I2C data rate.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
*
* \return Returns the actual I2C data rate \ref i2c_ip6510_speed_t
*
* \note This function doesn't check if dev is NULL.
*/
enum i2c_ip6510_speed_t i2c_ip6510_get_speed(
const struct i2c_ip6510_dev_t* dev);
/**
* \brief Returns the state of the I2C bus.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
*
* \return Returns the I2C bus state \ref i2c_ip6510_bus_state_t
*
* \note This function doesn't check if dev is NULL.
*/
enum i2c_ip6510_bus_state_t i2c_ip6510_get_bus_status(
const struct i2c_ip6510_dev_t* dev);
/**
* \brief Returns the transfer size registers value.
*
* Transfer size registers value contains:
* Master transmitter mode: number of data bytes still not transmitted
* minus one.
* Master receiver mode: number of data bytes that are still expected
* to be received.
* Slave transmitter mode: number of bytes remaining in the FIFO after
* the master terminates the transfer.
* Slave receiver mode: number of valid data bytes in the FIFO.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
*
* \return Returns the transfer size registers value.
*
* \note This function doesn't check if dev is NULL.
*/
int i2c_ip6510_get_transfer_size(const struct i2c_ip6510_dev_t* dev);
/**
* \brief Returns the I2C interrupt status.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
*
* \return The returned status value can be checked against values from
* the \ref i2c_ip6510_intr_t type.
*
* \note This function doesn't check if dev is NULL.
*/
uint32_t i2c_ip6510_get_irq_status(const struct i2c_ip6510_dev_t* dev);
/**
* \brief Returns the I2C interrupt mask status.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
*
* \return The returned mask value can be checked against values from
* the \ref i2c_ip6510_intr_t type.
*
* \note This function doesn't check if dev is NULL.
*/
uint32_t i2c_ip6510_get_irq_mask(const struct i2c_ip6510_dev_t* dev);
/**
* \brief Clears the specified I2C interrupts.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] mask Bit mask for clearing interrupts. Values from
* \ref i2c_ip6510_intr_t could be used to create the mask.
*
* \note This function doesn't check if dev is NULL.
*/
void i2c_ip6510_clear_irq(struct i2c_ip6510_dev_t* dev, uint32_t mask);
/**
* \brief Enables the specified I2C interrupts.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] mask Bit mask for enabling interrupts. Values from
* \ref i2c_ip6510_intr_t could be used to create the mask.
*
* \note User is responsible to configure the interrupt vector and
* the interrupt controller.
* \note This function doesn't check if dev is NULL.
*/
void i2c_ip6510_enable_irq(struct i2c_ip6510_dev_t* dev, uint32_t mask);
/**
* \brief Disables I2C interrupts.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] mask Bit mask for disabling interrupts. Values from
* \ref i2c_ip6510_intr_t could be used to create the mask.
*
* \note User is responsible to configure the interrupt vector and
* the interrupt controller.
* \note This function doesn't check if dev is NULL.
*/
void i2c_ip6510_disable_irq(struct i2c_ip6510_dev_t* dev, uint32_t mask);
/**
* \brief Sets the time out interval.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] interval New time out interval in number of scl cycles minus one.
*
* \note The default time out interval is 0x20.
* \note This function doesn't check if dev is NULL.
*/
void i2c_ip6510_set_timeout(struct i2c_ip6510_dev_t* dev,
uint8_t interval);
/**
* \brief Sets the pause interval in slave monitor mode.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] interval New pause interval in number of scl cycles minus one.
*
* \note The default pause interval is 0 (continuous monitoring).
* \note This function doesn't check if dev is NULL.
*/
void i2c_ip6510_set_slave_monitor_pause_interval(struct i2c_ip6510_dev_t* dev,
uint8_t interval);
/**
* \brief Returns the pause interval of slave monitor mode.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
*
* \return Returns the pause interval of slave monitor mode
* in number of scl cycles minus one.
*
* \note The default pause interval is 0 (continuous monitoring).
* \note This function doesn't check if dev is NULL.
*/
uint8_t i2c_ip6510_get_slave_monitor_pause_interval(
struct i2c_ip6510_dev_t* dev);
/**
* \brief Sets the length of the glitch filter.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] length New length of the glitch filter [0(min) ... 15(max)].
*
* \note If length of glitch filter is set to 0 then the glitch filter is
* bypassed. The default glitch filter length is 0.
* \note This function doesn't check if dev is NULL.
*/
void i2c_ip6510_set_glitch_filter_length(struct i2c_ip6510_dev_t* dev,
uint32_t length);
/**
* \brief Returns the length of the glitch filter.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
*
* \return Returns the actual length of the glitch filter.
*
* \note The default glitch filter length is 0.
* \note This function doesn't check if dev is NULL.
*/
uint8_t i2c_ip6510_get_glitch_filter_length(const struct i2c_ip6510_dev_t* dev);
/**
* \brief The I2C device monitors if addressed I2C slave is present on the bus.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] addr Address of the monitored I2C device (7 bits or 10 bits).
*
* \return Returns error code as specified in \ref i2c_ip6510_error_t
* Return value is I2C_IP6510_ERR_NONE if the addressed I2C slave is
* present on the bus.
*
* \note The I2C interface should be in Master mode before calling this API,
* for better performance the function doesn't check this,
* \ref i2c_ip6510_get_device_mode should return I2C_IP6510_MASTER_MODE.
* \note This function doesn't check if dev is NULL.
*/
enum i2c_ip6510_error_t i2c_ip6510_monitor_slave(struct i2c_ip6510_dev_t* dev,
uint16_t addr);
/**
* \brief Writes data to I2C device.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] addr I2C device address (7 bits or 10 bits).
* \param[in] tx_data Data buffer pointer to write.
* \param[in] stop If false, master does not generate STOP symbol.
* \param[in,out] tx_length Data buffer length (number of bytes to write).
* On return: stores the number of bytes written.
*
* \return Returns error code as specified in \ref i2c_ip6510_error_t
*
* \note The I2C interface should be in Master mode before calling this API,
* for better performance the function doesn't check this,
* \ref i2c_ip6510_get_device_mode should return I2C_IP6510_MASTER_MODE.
* \note This function doesn't check if the pointers are NULL.
*/
enum i2c_ip6510_error_t i2c_ip6510_master_write(struct i2c_ip6510_dev_t* dev,
uint16_t addr,
const uint8_t* tx_data,
bool stop,
uint32_t* tx_length);
/**
* \brief Reads data from I2C device.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] addr I2C device address (7 bits or 10 bits).
* \param[in] rx_data Buffer pointer to store the read data.
* \param[in] stop If false, master does not generate STOP symbol.
* \param[in,out] rx_length Buffer length (number of bytes to read).
* On return: stores the number of read bytes.
*
* \return Returns error code as specified in \ref i2c_ip6510_error_t
*
* \note The I2C interface should be in Master mode before calling this API,
* for better performance the function doesn't check this,
* \ref i2c_ip6510_get_device_mode should return I2C_IP6510_MASTER_MODE.
* \note This function doesn't check if the pointers are NULL.
*/
enum i2c_ip6510_error_t i2c_ip6510_master_read(struct i2c_ip6510_dev_t* dev,
uint16_t addr,
uint8_t* rx_data,
bool stop,
uint32_t* rx_length);
/**
* \brief Writes to and reads from I2C device (combined transfer).
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] addr I2C device address (7 bits or 10 bits).
* \param[in] tx_data Data buffer pointer to write.
* \param[in] rx_data Buffer pointer to store the read data.
* \param[in,out] tx_length Data buffer length (number of bytes to write).
* On return: stores the number of bytes written.
* \param[in,out] rx_length Buffer length (number of bytes to read).
* On return: stores the number of read bytes.
*
* \return Returns error code as specified in \ref i2c_ip6510_error_t
*
* \note The I2C interface should be in Master mode before calling this API,
* for better performance the function doesn't check this,
* \ref i2c_ip6510_get_device_mode should return I2C_IP6510_MASTER_MODE.
* \note This function doesn't check if the pointers are NULL.
*/
enum i2c_ip6510_error_t i2c_ip6510_master_write_read(
struct i2c_ip6510_dev_t* dev,
uint16_t addr,
const uint8_t* tx_data,
uint8_t* rx_data,
uint32_t* tx_length,
uint32_t* rx_length);
/*
* \brief Writes one byte to I2C device
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] addr Address to write to, accepts both 7 and 10 bit
* addresses
* \param[in] tx_data Data pointer to write.
* \param[in] set_addr Set true for the first data byte. If true,
* overwrites address register, starting a new
* transaction. Set false for all following bytes in
* the same transaction.
*
* \return Returns error code as specified in \ref i2c_ip6510_error_t
*
* \note This function doesn't check if dev is NULL.
*/
enum i2c_ip6510_error_t i2c_ip6510_master_byte_write(
const struct i2c_ip6510_dev_t* dev,
uint16_t addr,
const uint8_t* tx_data,
bool set_addr);
/*
* \brief Reads one byte from I2C device
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] addr Address to read from, accepts both 7 and 10 bit
* addresses
* \param[in] last_byte If true ends transmission on the next byte received
* \param[in] set_addr Set true for the first data byte. If true,
* overwrites address register, starting a new
* transaction. Set false for all following bytes in
* the same transaction.
* \param[out] rx_data Data pointer to read to.
*
* \return Returns error code as specified in \ref i2c_ip6510_error_t
*
* \note This function doesn't check if dev is NULL.
*/
enum i2c_ip6510_error_t i2c_ip6510_master_byte_read(
const struct i2c_ip6510_dev_t* dev,
uint16_t addr,
bool last_byte,
bool set_addr,
uint8_t* rx_data);
/**
* \brief Sets the I2C interface to be in slave mode with the given address.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] addr Unique identifying address of the I2C interface.
*
* It sets the I2C interface to be in slave mode with an address which
* identifies the interface on the I2C bus and sets the appropriate I2C
* data rate for the slave mode.
*
* \return Returns error code as specified in \ref i2c_ip6510_error_t
*
* \note This function doesn't check if dev is NULL.
*/
enum i2c_ip6510_error_t i2c_ip6510_set_slave_mode(
struct i2c_ip6510_dev_t* dev,
uint16_t addr);
/**
* \brief Sets the I2C interface to be in master mode
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
*
* It only sets the I2C interface to be in master mode thus it will not answer
* to further transfer requests.
*
* \note This function doesn't check if dev is NULL.
*/
void i2c_ip6510_set_master_mode(struct i2c_ip6510_dev_t* dev);
/**
* \brief Returns the direction of the transmission received from the Master.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
*
* \return Received direction of the transmission \ref i2c_ip6510_transf_dir_t
*
* \note This function doesn't check if dev is NULL.
*/
enum i2c_ip6510_transf_dir_t i2c_ip6510_get_slave_tranf_dir(
struct i2c_ip6510_dev_t* dev);
/**
* \brief Sends data over the I2C bus to the Master.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] tx_data Data buffer pointer to write.
* \param[in,out] tx_length Data buffer length (number of bytes to write).
* On return: stores the number of bytes written.
*
* \return Returns error code as specified in \ref i2c_ip6510_error_t
*
* \note This API should be called only if transmission request has been
* received from the Master.
* \note The I2C interface should be in Slave mode before calling this API,
* for better performance the function doesn't check this,
* \ref i2c_ip6510_get_device_mode should return I2C_IP6510_SLAVE_MODE.
* \note This function doesn't check if the pointers are NULL.
*/
enum i2c_ip6510_error_t i2c_ip6510_slave_write(struct i2c_ip6510_dev_t* dev,
const uint8_t* tx_data,
uint32_t* tx_length);
/**
* \brief Receives data from I2C Master.
*
* \param[in] dev I2C (IP6510) device structure \ref i2c_ip6510_dev_t
* \param[in] rx_data Buffer pointer to store the read data.
* \param[in,out] rx_length Buffer length (number of bytes to read), a system
* known parameter or must be communicated in advance.
* On return: stores the number of bytes read.
*
* \return Returns error code as specified in \ref i2c_ip6510_error_t
*
* \note This API should be called only if transmission request has been
* received from the Master.
* \note The I2C interface should be in Slave mode before calling this API,
* for better performance the function doesn't check this,
* \ref i2c_ip6510_get_device_mode should return I2C_IP6510_SLAVE_MODE.
* \note This function doesn't check if the pointers are NULL.
*/
enum i2c_ip6510_error_t i2c_ip6510_slave_read(struct i2c_ip6510_dev_t* dev,
uint8_t* rx_data,
uint32_t* rx_length);
#ifdef __cplusplus
}
#endif
#endif /* __I2C_IP6510_DRV_H__ */

View File

@ -0,0 +1,419 @@
/*
* Copyright (c) 2017-2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "musca_s1_scc_drv.h"
/* Use __ISB(), __DSB() */
#include "cmsis.h"
/** Setter bit manipulation macro */
#define SET_BIT(WORD, BIT_INDEX) ((WORD) |= (1u << (BIT_INDEX)))
/** Clearing bit manipulation macro */
#define CLR_BIT(WORD, BIT_INDEX) ((WORD) &= ~(1u << (BIT_INDEX)))
struct musca_s1_scc_reg_map_t {
/* 0x000-0x800 Reserved (offset) */
const uint32_t reserved0[512];
/* 0x800 RW Clock Control Selection Register */
volatile uint32_t clk_ctrl_sel;
/* 0x804 RW Clock PLL Prediv Control Register */
volatile uint32_t clk_pll_prediv_ctrl;
/* 0x808 RW Body Bias Generator CLK Div Register */
volatile uint32_t clk_bbgen_div_clk;
/* 0x80C Reserved */
const uint32_t reserved1;
/* 0x810 RW QSPI Post PLL CLK divider Register */
volatile uint32_t clk_postdiv_qspi;
/* 0x814 RW RTC Post PLL CLK div ctrl Register */
volatile uint32_t clk_postdiv_ctrl_rtc;
/* 0x818 Reserved */
const uint32_t reserved2;
/* 0x81C RW TEST CLK Post PLL CLK Div Register */
volatile uint32_t clk_postdiv_ctrl_test;
/* 0x820 RW Post PLL CLK divider bypass Register */
volatile uint32_t ctrl_bypass_div;
/* 0x824 RW PLL0 Control Register */
volatile uint32_t pll_ctrl_pll0_clk;
/* 0x828-0x82C Reserved */
const uint32_t reserved3[2];
/* 0x830 RW Clock gate enable control Register */
volatile uint32_t clk_ctrl_enable;
/* 0x834 RW PLL Status Register */
volatile uint32_t clk_status;
/* 0x838-0x83C Reserved */
const uint32_t reserved4[2];
/* 0x840 RW Reset Control Register */
volatile uint32_t reset_ctrl;
/* 0x844 Reserved */
const uint32_t reserved5;
/* 0x848 RW Debug Control Register */
volatile uint32_t dbg_ctrl;
/* 0x84C RW SRAM Control Register */
volatile uint32_t sram_ctrl;
/* 0x850 RW MPC Interupt Control Register */
volatile uint32_t intr_ctrl;
/* 0x854 Reserved */
const uint32_t reserved6;
/* 0x858 RW Reset vector for CPU0 SRAM */
volatile uint32_t cpu0_vtor;
/* 0x85C RW Reset vector for CPU0 MRAM */
volatile uint32_t cpu0_vtor_1;
/* 0x860 RW Reset vector for CPU1 SRAM */
volatile uint32_t cpu1_vtor;
/* 0x864 RW Reset vector for CPU1 MRAM */
volatile uint32_t cpu1_vtor_1;
/* 0x868 RW Main function in data select */
volatile uint32_t iomux_main_insel;
/* 0x874 Reserved */
const uint32_t reserved7;
/* 0x870 RW Main function out data select */
volatile uint32_t iomux_main_outsel;
/* 0x874 Reserved */
const uint32_t reserved8;
/* 0x878 RW Main function out enable select */
volatile uint32_t iomux_main_oensel;
/* 0x87C Reserved */
const uint32_t reserved9;
/* 0x880 RW Main function default in select */
volatile uint32_t iomux_main_default_in;
/* 0x884 Reserved */
const uint32_t reserved10;
/* 0x888 RW Alt function 1 in data select */
volatile uint32_t iomux_altf1_insel;
/* 0x88C Reserved */
const uint32_t reserved11;
/* 0x890 RW Alt function 1 out data select */
volatile uint32_t iomux_altf1_outsel;
/* 0x894 Reserved */
const uint32_t reserved12;
/* 0x898 RW Alt function 1 out enable select */
volatile uint32_t iomux_altf1_oensel;
/* 0x89C Reserved */
const uint32_t reserved13;
/* 0x8A0 RW Alt function 1 default in select */
volatile uint32_t iomux_altf1_default_in;
/* 0x8A4 Reserved */
const uint32_t reserved14;
/* 0x8A8 RW Alt function 2 in data select */
volatile uint32_t iomux_altf2_insel;
/* 0x8AC Reserved */
const uint32_t reserved15;
/* 0x8B0 RW Alt function 2 out data select */
volatile uint32_t iomux_altf2_outsel;
/* 0x8B4 Reserved */
const uint32_t reserved16;
/* 0x8B8 RW Alt function 2 out enable select */
volatile uint32_t iomux_altf2_oensel;
/* 0x8BC Reserved */
const uint32_t reserved17;
/* 0x8C0 RW Alt function 2 default in select */
volatile uint32_t iomux_altf2_default_in;
/* 0x8C4-0x8E4 Reserved */
const uint32_t reserved18[9];
/* 0x8E8 RW Drive Select 0 */
volatile uint32_t iopad_ds0;
/* 0x8EC Reserved */
const uint32_t reserved19;
/* 0x8F0 RW Drive Select 1 */
volatile uint32_t iopad_ds1;
/* 0x8F4 Reserved */
const uint32_t reserved20;
/* 0x8F8 RW Pull Enable */
volatile uint32_t iopad_pe;
/* 0x8FC Reserved */
const uint32_t reserved21;
/* 0x900 RW Pull Select */
volatile uint32_t iopad_ps;
/* 0x904 Reserved */
const uint32_t reserved22;
/* 0x908 RW Slew Select */
volatile uint32_t iopad_sr;
/* 0x90C Reserved */
const uint32_t reserved23;
/* 0x910 RW Input Select */
volatile uint32_t iopad_is;
/* 0x914 Reserved */
const uint32_t reserved24;
/* 0x918 RW PVT control register */
volatile uint32_t pvt_ctrl;
/* 0x91C-0x938 Reserved */
const uint32_t reserved25[8];
/* 0x93C RW Static configuration */
volatile uint32_t static_conf_sig1;
/* 0x940-0x994 Reserved */
const uint32_t reserved26[22];
/* 0x998 RW eMRAM control 0 register */
volatile uint32_t scc_mram_ctrl0;
/* 0x99C RW eMRAM control 1 register */
volatile uint32_t scc_mram_ctrl1;
/* 0x9A0 RW eMRAM control 2 register */
volatile uint32_t scc_mram_ctrl2;
/* 0x9A4-0x9AC Reserved */
const uint32_t reserved27[3];
/* 0x9B0 RW eMRAM data input 0 register */
volatile uint32_t scc_mram_din0;
/* 0x9B4 RW eMRAM data input 1 register */
volatile uint32_t scc_mram_din1;
/* 0x9B8 RW eMRAM data input 2 register */
volatile uint32_t scc_mram_din2;
/* 0x9BC Reserved */
const uint32_t reserved28;
/* 0x9C0 RW eMRAM data output 0 register */
volatile uint32_t scc_mram_dout0;
/* 0x9C4 RW eMRAM data output 1 register */
volatile uint32_t scc_mram_dout1;
/* 0x9C8 RW eMRAM data output 2 register */
volatile uint32_t scc_mram_dout2;
/* 0x9CC-0x9DC Reserved */
const uint32_t reserved29[5];
/* 0x9E0 RW CLK pahes shift control register */
volatile uint32_t selection_control_reg;
/* 0x9E4-0xA00 Reserved */
const uint32_t reserved30[8];
/* 0xA04 RW SSE-200 OTP control register */
volatile uint32_t sse_otp_ctrl;
/* 0xA08-0xA1C Reserved */
const uint32_t reserved31[6];
/* 0xA20 RW Body-Biasing control register */
volatile uint32_t bbgen_ctrl;
/* 0xA24 RW Spaer control register */
volatile uint32_t spare_ctrl1;
/* 0xA28-0xBFC Reserved */
const uint32_t reserved32[118];
/* 0xC00 RO Chip ID 0x0797_0477 */
const uint32_t chip_id;
/* 0xC04 RO I/O in status */
const uint32_t io_in_status;
};
/**
* \brief Musca-S1 SCC eMRAM control 0 register bit fields
*/
#define SCC_MRAM_CTRL0_MRAM_CLK_EN 0u
/*!< eMRAM control register 0 Enable eMRAM clock offset */
#define SCC_MRAM_CTRL0_PROC_SPEC_CLK_EN 1u
/*!< eMRAM control register 0 Enable eMRAM controller clock offset */
#define SCC_MRAM_CTRL0_AUTOSTOP_EN 2u
/*!< eMRAM control register 0 Enable autostop offset */
#define SCC_MRAM_CTRL0_MRAM_INV_CLK_SEL 3u
/*!< eMRAM control register 0 Select clock inversion offset */
#define SCC_MRAM_CTRL0_FAST_READ_EN 4u
/*!< eMRAM control register 0 Enable fast read offset */
#define SCC_MRAM_CTRL0_MRAM_DOUT_SEL 5u
/*!< eMRAM control register 0 Select eMRAM0 output data offset */
#define SCC_MRAM_CTRL0_PG_VDD_0 8u
/*!< eMRAM control register 0 eMRAM0 PG VDD offset */
#define SCC_MRAM_CTRL0_PG_VDD18_0 9u
/*!< eMRAM control register 0 eMRAM1 PG VDD18_0 offset */
#define SCC_MRAM_CTRL0_PG_VDD_1 10u
/*!< eMRAM control register 0 eMRAM1 PG VDD offset */
#define SCC_MRAM_CTRL0_PG_VDD18_1 11u
/*!< eMRAM control register 0 eMRAM1 PG VDD18 offset */
#define SCC_MRAM_CTRL0_WRITE_CSN_CLKS 12u
/*!< eMRAM control register 0 WRITE_CSN_CLKS offset */
#define SCC_MRAM_CTRL0_CSN_HIGH_CLKS 16u
/*!< eMRAM control register 0 CSN_HIGH_CLKS offset */
#define SCC_MRAM_CTRL0_READ_CSN_CLKS 20u
/*!< eMRAM control register 0 Number of clocks for single read offset */
#define SCC_MRAM_CTRL0_MRAM_OTP_CLK_EN 29u
/*!< eMRAM control register 0 Enable eMRAM OTP clock offset */
#define SCC_MRAM_CTRL0_MRAM_CLK_SYNC_BYPASS 30u
/*!< eMRAM control register 0 Bypass eMRAM clock divider sync offset */
#define SCC_MRAM_CTRL0_MRAM_DA_EN 31u
/*!< eMRAM control register 0 Enable eMRAM direct access offset */
/**
* \brief Clears selected alternate functions for selected pins
*
* \param[in] dev SCC registers base address \ref musca_s1_scc_reg_map_t
* \param[in] func_mask Bitmask of alternate functions to clear
* \ref gpio_altfunc_mask_t
* \param[in] pin_mask Pin mask for the alternate functions
*/
static void scc_clear_alt_func(struct musca_s1_scc_reg_map_t* scc_regs,
enum gpio_altfunc_mask_t func_mask,
uint32_t pin_mask)
{
if (func_mask & GPIO_MAIN_FUNC_MASK) {
scc_regs->iomux_main_insel &= ~pin_mask;
scc_regs->iomux_main_outsel &= ~pin_mask;
scc_regs->iomux_main_oensel &= ~pin_mask;
}
if (func_mask & GPIO_ALTFUNC_1_MASK) {
scc_regs->iomux_altf1_insel &= ~pin_mask;
scc_regs->iomux_altf1_outsel &= ~pin_mask;
scc_regs->iomux_altf1_oensel &= ~pin_mask;
}
if (func_mask & GPIO_ALTFUNC_2_MASK) {
scc_regs->iomux_altf2_insel &= ~pin_mask;
scc_regs->iomux_altf2_outsel &= ~pin_mask;
scc_regs->iomux_altf2_oensel &= ~pin_mask;
}
}
void musca_s1_scc_set_alt_func(struct musca_s1_scc_dev_t* dev,
enum gpio_altfunc_t altfunc, uint32_t pin_mask)
{
struct musca_s1_scc_reg_map_t* scc_regs =
(struct musca_s1_scc_reg_map_t*) dev->cfg->base;
enum gpio_altfunc_mask_t altfunc_to_clear = GPIO_ALTFUNC_NONE;
volatile uint32_t *insel = NULL;
volatile uint32_t *outsel = NULL;
volatile uint32_t *oensel = NULL;
if (altfunc >= GPIO_ALTFUNC_MAX) {
/* If no altfunction is selected, then nothing to do.
* This is possible during init and we do not
* want to change the reset values set by the HW
*/
return;
}
switch (altfunc) {
case GPIO_MAIN_FUNC:
insel = &scc_regs->iomux_main_insel;
outsel = &scc_regs->iomux_main_outsel;
oensel = &scc_regs->iomux_main_oensel;
altfunc_to_clear = GPIO_MAIN_FUNC_NEG_MASK;
break;
case GPIO_ALTFUNC_1:
insel = &scc_regs->iomux_altf1_insel;
outsel = &scc_regs->iomux_altf1_outsel;
oensel = &scc_regs->iomux_altf1_oensel;
altfunc_to_clear = GPIO_ALTFUNC_1_NEG_MASK;
break;
case GPIO_ALTFUNC_2:
insel = &scc_regs->iomux_altf2_insel;
outsel = &scc_regs->iomux_altf2_outsel;
oensel = &scc_regs->iomux_altf2_oensel;
altfunc_to_clear = GPIO_ALTFUNC_2_NEG_MASK;
break;
default:
break;
}
/* Select the wanted function's output enable bit first.
* This way the output won't be disabled which is desired
* if we switch from output to output function
*/
*oensel |= pin_mask;
/* Clear all alternate function registers which are not selected */
scc_clear_alt_func(scc_regs, altfunc_to_clear, pin_mask);
/* Enable input and output data line */
*insel |= pin_mask;
*outsel |= pin_mask;
}
void musca_s1_scc_set_pinmode(struct musca_s1_scc_dev_t* dev, uint32_t pin_mask,
enum pinmode_select_t mode)
{
struct musca_s1_scc_reg_map_t* scc_regs =
(struct musca_s1_scc_reg_map_t*) dev->cfg->base;
switch (mode) {
case PINMODE_NONE:
scc_regs->iopad_pe &= ~pin_mask;
break;
case PINMODE_PULL_DOWN:
/* If the pull select bit is set to 0 it means pull down */
scc_regs->iopad_ps &= ~pin_mask;
scc_regs->iopad_pe |= pin_mask;
break;
case PINMODE_PULL_UP:
/* If the pull select bit is set to 1 it means pull up */
scc_regs->iopad_ps |= pin_mask;
scc_regs->iopad_pe |= pin_mask;
break;
default:
break;
}
}
void musca_s1_scc_set_default_in(struct musca_s1_scc_dev_t* dev,
enum gpio_altfunc_t altfunc,
uint32_t default_in_mask,
uint32_t default_in_value)
{
struct musca_s1_scc_reg_map_t* scc_regs =
(struct musca_s1_scc_reg_map_t*) dev->cfg->base;
uint32_t iomux_value = 0;
if (altfunc >= GPIO_ALTFUNC_MAX) {
/* If no altfunction is selected, then nothing to do */
return;
}
switch (altfunc) {
case GPIO_MAIN_FUNC:
iomux_value = scc_regs->iomux_main_default_in & ~default_in_mask;
iomux_value |= (default_in_value & default_in_mask);
scc_regs->iomux_main_default_in = iomux_value;
scc_regs->iomux_main_insel =
(scc_regs->iomux_main_insel & ~default_in_mask);
break;
case GPIO_ALTFUNC_1:
iomux_value = scc_regs->iomux_altf1_default_in & ~default_in_mask;
iomux_value |= (default_in_value & default_in_mask);
scc_regs->iomux_altf1_default_in = iomux_value;
scc_regs->iomux_altf1_insel =
(scc_regs->iomux_altf1_insel & ~default_in_mask);
break;
case GPIO_ALTFUNC_2:
iomux_value = scc_regs->iomux_altf2_default_in & ~default_in_mask;
iomux_value |= (default_in_value & default_in_mask);
scc_regs->iomux_altf2_default_in = iomux_value;
scc_regs->iomux_altf2_insel =
(scc_regs->iomux_altf2_insel & ~default_in_mask);
break;
default:
break;
}
}
void musca_s1_scc_mram_fast_read_enable(struct musca_s1_scc_dev_t* dev)
{
struct musca_s1_scc_reg_map_t* scc_regs =
(struct musca_s1_scc_reg_map_t*) dev->cfg->base;
__DSB();
SET_BIT(scc_regs->scc_mram_ctrl0, SCC_MRAM_CTRL0_FAST_READ_EN);
__DSB();
__ISB();
}
void musca_s1_scc_mram_fast_read_disable(struct musca_s1_scc_dev_t* dev)
{
struct musca_s1_scc_reg_map_t* scc_regs =
(struct musca_s1_scc_reg_map_t*) dev->cfg->base;
__DSB();
CLR_BIT(scc_regs->scc_mram_ctrl0, SCC_MRAM_CTRL0_FAST_READ_EN);
__DSB();
__ISB();
}
bool musca_s1_scc_mram_is_fast_read_enabled(struct musca_s1_scc_dev_t* dev)
{
struct musca_s1_scc_reg_map_t* scc_regs =
(struct musca_s1_scc_reg_map_t*) dev->cfg->base;
return (bool)(scc_regs->scc_mram_ctrl0 &
(1u << SCC_MRAM_CTRL0_FAST_READ_EN));
}

View File

@ -0,0 +1,136 @@
/*
* Copyright (c) 2017-2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MUSCA_S1_SCC_DRV_H__
#define __MUSCA_S1_SCC_DRV_H__
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Enum to store alternate function values.
* They are used as shift operand, must be unsigned.
*/
enum gpio_altfunc_t {
GPIO_MAIN_FUNC = 0UL,
GPIO_ALTFUNC_1,
GPIO_ALTFUNC_2,
GPIO_ALTFUNC_MAX
};
#define GPIO_ALTFUNC_ALL_MASK ((1U << GPIO_ALTFUNC_MAX) - 1)
/**
* \brief Enum to store alternate function mask values.
*/
enum gpio_altfunc_mask_t {
GPIO_ALTFUNC_NONE = 0,
GPIO_MAIN_FUNC_MASK = (1UL << GPIO_MAIN_FUNC),
GPIO_ALTFUNC_1_MASK = (1UL << GPIO_ALTFUNC_1),
GPIO_ALTFUNC_2_MASK = (1UL << GPIO_ALTFUNC_2),
GPIO_MAIN_FUNC_NEG_MASK = (~GPIO_MAIN_FUNC_MASK & GPIO_ALTFUNC_ALL_MASK),
GPIO_ALTFUNC_1_NEG_MASK = (~GPIO_ALTFUNC_1_MASK & GPIO_ALTFUNC_ALL_MASK),
GPIO_ALTFUNC_2_NEG_MASK = (~GPIO_ALTFUNC_2_MASK & GPIO_ALTFUNC_ALL_MASK)
};
enum pinmode_select_t {
PINMODE_NONE,
PINMODE_PULL_DOWN,
PINMODE_PULL_UP
};
/* MUSCA SCC device configuration structure */
struct musca_s1_scc_dev_cfg_t {
const uint32_t base; /*!< SCC base address */
};
/* MUSCA SCC device structure */
struct musca_s1_scc_dev_t {
const struct musca_s1_scc_dev_cfg_t* const cfg; /*!< SCC configuration */
};
/**
* \brief Sets selected alternate functions for selected pins
*
* \param[in] dev SCC device pointer \ref musca_s1_scc_dev_t
* \param[in] altfunc Alternate function to set \ref gpio_altfunc_t
* \param[in] pin_mask Pin mask for the alternate functions
*
* \note This function doesn't check if scc dev is NULL.
* \note If no alternate function is selected, the function won't do anything
*/
void musca_s1_scc_set_alt_func(struct musca_s1_scc_dev_t* dev,
enum gpio_altfunc_t altfunc, uint32_t pin_mask);
/**
* \brief Sets pinmode for the given pins
*
* \param[in] dev SCC device pointer \ref musca_s1_scc_dev_t
* \param[in] pin_mask Pin mask for the alternate functions
* \param[in] mode Pin mode to set \ref pinmode_select_t
*
* \note This function doesn't check if scc dev is NULL.
*/
void musca_s1_scc_set_pinmode(struct musca_s1_scc_dev_t* dev, uint32_t pin_mask,
enum pinmode_select_t mode);
/**
* \brief Sets default input values for the selected pins
*
* \param[in] dev SCC device pointer \ref musca_s1_scc_dev_t
* \param[in] altfunc The selected alternate function that is set the
* specified default in value \ref gpio_altfunc_t
* \param[in] default_in_mask Pin mask for selecting pins
* \param[in] default_in_value Pin values for the selected pins
*
* \note This function doesn't check if scc_base is NULL.
* \note If no alternate function is selected, the function won't do anything
*/
void musca_s1_scc_set_default_in(struct musca_s1_scc_dev_t* dev,
enum gpio_altfunc_t altfunc,
uint32_t default_in_mask,
uint32_t default_in_value);
/**
* \brief Enables eMRAM fast read
*
*/
void musca_s1_scc_mram_fast_read_enable(struct musca_s1_scc_dev_t* dev);
/**
* \brief Disables eMRAM fast read
*
*/
void musca_s1_scc_mram_fast_read_disable(struct musca_s1_scc_dev_t* dev);
/**
* \brief Check if eMRAM fast read is enabled
*
* \return Returns bool, true if fast read is enabled, false otherwise
*/
bool musca_s1_scc_mram_is_fast_read_enabled(struct musca_s1_scc_dev_t* dev);
#ifdef __cplusplus
}
#endif
#endif /* __MUSCA_S1_SCC_DRV_H__ */

View File

@ -0,0 +1,757 @@
/*
* Copyright (c) 2018-2019 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
/* Use memcpy */
#include <string.h>
#include "qspi_ip6514e_drv.h"
/** Setter bit manipulation macro */
#define SET_BIT(WORD, BIT_INDEX) ((WORD) |= (1U << (BIT_INDEX)))
/** Clearing bit manipulation macro */
#define CLR_BIT(WORD, BIT_INDEX) ((WORD) &= ~(1U << (BIT_INDEX)))
/** Getter bit manipulation macro */
#define GET_BIT(WORD, BIT_INDEX) (bool)(((WORD) & (1U << (BIT_INDEX))))
#define WORD_ALIGN_4B_MASK 0x3U /* Mask the first 2 bits */
#define IS_ADDR_ALIGNED(ADDR) (((uint32_t)(ADDR) & (WORD_ALIGN_4B_MASK)) == 0U)
#define BITS_PER_BYTE 8U
#define BITS_PER_WORD 32U
#define CFG_READS true
#define CFG_WRITES false
#define ARG_NOT_USED 0
#define ARG_PTR_NOT_USED NULL
#define DATA_REG_NUMBER 2U
#define DATA_REG_LOWER 0U
#define DATA_REG_UPPER 1U
#define ERROR_VALUE 0xFFFFFFFFU
/**
* \brief QSPI IP6514E register map structure
*/
struct _qspi_ip6514e_reg_map_t {
volatile uint32_t qspi_cfg; /*!< 0x00 (R/W) */
volatile uint32_t device_read_inst; /*!< 0x04 (R/W) */
volatile uint32_t device_write_inst; /*!< 0x08 (R/W) */
volatile uint32_t hidden1[2];
volatile uint32_t device_size; /*!< 0x14 (R/W) */
volatile uint32_t hidden2[3];
volatile uint32_t remap_addr; /*!< 0x24 (R/W) */
volatile uint32_t hidden3[26];
volatile uint32_t flash_cmd_ctrl; /*!< 0x90 (R/W) */
volatile uint32_t flash_cmd_addr; /*!< 0x94 (R/W) */
volatile uint32_t hidden4[2];
volatile uint32_t flash_cmd_read_data_lower; /*!< 0xA0 (R/ ) */
volatile uint32_t flash_cmd_read_data_upper; /*!< 0xA4 (R/ ) */
volatile uint32_t flash_cmd_write_data_lower; /*!< 0xA8 (R/W) */
volatile uint32_t flash_cmd_write_data_upper; /*!< 0xAC (R/W) */
volatile uint32_t hidden5[2];
};
/** QSPI Configuration register description (offset 0x00) */
#define QSPI_CFG_ENABLE_POS 0U
#define QSPI_CFG_ENABLE_ADDR_REMAP_POS 16U
#define QSPI_CFG_BAUD_DIV_POS 19U
#define QSPI_CFG_BAUD_DIV_MIN 2U
#define QSPI_CFG_BAUD_DIV_MAX 32U
#define QSPI_CFG_BAUD_DIV_BITS 4U
#define QSPI_CFG_IDLE_POS 31U
/**
* Device Read/Write Instruction registers description (offset 0x04 and 0x08).
* These values are the same for the Device Read Instruction register at offset
* 0x04 and the Device Write Instruction register at offset 0x08.
*/
#define DEVICE_READ_WRITE_INST_OPCODE_POS 0U
#define DEVICE_READ_INST_INST_TYPE_POS 8U /* Only applies to the Read
* register. */
#define DEVICE_READ_WRITE_INST_ADDR_TYPE_POS 12U
#define DEVICE_READ_WRITE_INST_DATA_TYPE_POS 16U
#define DEVICE_READ_WRITE_INST_MODE_QSPI 2U
#define DEVICE_READ_WRITE_INST_MODE_DSPI 1U
#define DEVICE_READ_WRITE_INST_MODE_SPI 0U
#define DEVICE_READ_WRITE_INST_MODE_BITS 2U
#define DEVICE_READ_WRITE_INST_DUMMY_CYCLES_POS 24U
#define DEVICE_READ_WRITE_INST_DUMMY_CYCLES_BITS 5U
#define DEVICE_READ_WRITE_INST_DUMMY_CYCLES_MAX 31U
/** Device Size Configuration register description (offset 0x14) */
#define DEVICE_SIZE_ADDR_BYTES_POS 0U
#define DEVICE_SIZE_ADDR_BYTES_MIN 1U
#define DEVICE_SIZE_ADDR_BYTES_MAX 16U
#define DEVICE_SIZE_ADDR_BYTES_BITS 4U
#define DEVICE_SIZE_PAGE_BYTES_POS 4U
#define DEVICE_SIZE_PAGE_BYTES_MAX 4095U
#define DEVICE_SIZE_PAGE_BYTES_BITS 12U
/** Flash Command Control register description (offset 0x90) */
#define FLASH_CMD_CTRL_EXECUTE_POS 0U
#define FLASH_CMD_CTRL_BUSY_POS 1U
#define FLASH_CMD_CTRL_DUMMY_CYCLES_POS 7U
#define FLASH_CMD_CTRL_DUMMY_CYCLES_MAX 31U
#define FLASH_CMD_CTRL_DUMMY_CYCLES_BITS 5U
#define FLASH_CMD_CTRL_WRITE_BYTES_POS 12U
#define FLASH_CMD_CTRL_WRITE_BYTES_MAX 8U
#define FLASH_CMD_CTRL_WRITE_BYTES_BITS 3U
#define FLASH_CMD_CTRL_WRITE_ENABLE_POS 15U
#define FLASH_CMD_CTRL_ADDR_BYTES_POS 16U
#define FLASH_CMD_CTRL_ADDR_BYTES_MAX 4U
#define FLASH_CMD_CTRL_ADDR_BYTES_BITS 2U
#define FLASH_CMD_CTRL_ADDR_ENABLE_POS 19U
#define FLASH_CMD_CTRL_READ_BYTES_POS 20U
#define FLASH_CMD_CTRL_READ_BYTES_MAX 8U
#define FLASH_CMD_CTRL_READ_BYTES_BITS 3U
#define FLASH_CMD_CTRL_READ_ENABLE_POS 23U
#define FLASH_CMD_CTRL_OPCODE_POS 24U
/** Default register values of the QSPI Flash controller */
#define QSPI_CFG_REG_RESET_VALUE (0x80080080U)
#define DEVICE_READ_INSTR_REG_RESET_VALUE (0x080220EBU)
#define DEVICE_WRITE_INSTR_REG_RESET_VALUE (0x00000002U)
#define DEVICE_SIZE_CFG_REG_RESET_VALUE (0x00101002U)
#define REMAP_ADDR_REG_RESET_VALUE (0x00000000U)
#define FLASH_CMD_CONTROL_REG_RESET_VALUE (0x00000000U)
#define FLASH_CMD_ADDRESS_REG_RESET_VALUE (0x00000000U)
#define FLASH_CMD_WRITE_DATA_REG_RESET_VALUE (0x00000000U)
/**
* \brief Change specific bits in a 32 bits word.
*
* \param[in,out] word Pointer of the word to change
* \param[in] bits bits_length bits to put at bits_pos in the word
* pointed
* \param[in] bits_length Number of bits to change
* \param[in] bits_pos Position of the bits to change
*
* \note This function will do nothing if the parameters given are incorret:
* * word is NULL
* * bits_length + bits_pos > 32
* * bits_length is 0
*/
static void change_bits_in_word(volatile uint32_t *word,
uint32_t bits,
uint32_t bits_length,
uint32_t bits_pos)
{
uint32_t mask;
if ((word == NULL) ||
((bits_length + bits_pos) > BITS_PER_WORD) ||
(bits_length == 0U)) {
/* Silently fail */
return;
}
/* Change all the bits */
if (bits_length == BITS_PER_WORD) {
*word = bits;
return;
}
mask = ((1U << bits_length) - 1);
/*
* We change the bits in three steps:
* - clear bits_length bits with zeroes at bits_pos in the word
* - mask bits in case it contains more than bits_length bits
* - set the new bits in the cleared word
* Because the data pointed by word is only read once, the data will still
* be coherent after an interruption that changes it.
*/
*word = ((*word & ~(mask << bits_pos)) | ((bits & mask) << bits_pos));
}
/**
* \brief Configure reads or writes commands for direct operations.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
* \param[in] opcode Read/write opcode that will be used for every
* direct read/write
* \param[in] dummy_cycles Number of dummy cycles to wait before triggering
* the command, this value must be between 0 and 31
* (both included)
* \param[in] is_reads_cfg true to configure direct reads, false to configure
* direct writes
*
* \return Returns error code as specified in \ref qspi_ip6514e_error_t
*
* \note The QSPI controller should be idle before calling this function.
*/
static enum qspi_ip6514e_error_t qspi_ip6514e_cfg_reads_writes(
struct qspi_ip6514e_dev_t* dev,
uint8_t opcode,
uint32_t dummy_cycles,
bool is_reads_cfg)
{
struct _qspi_ip6514e_reg_map_t *reg_map =
(struct _qspi_ip6514e_reg_map_t *)dev->cfg->base;
/*
* Select the good register address if we want to configure reads or writes.
*/
volatile uint32_t *device_read_write_inst_reg = is_reads_cfg ?
&(reg_map->device_read_inst) :
&(reg_map->device_write_inst);
uint32_t device_read_write_inst_reg_copy = *device_read_write_inst_reg;
/*
* Wait for the Serial Interface and QSPI pipeline to be IDLE when
* all low level synchronization has been done.
*/
while(!qspi_ip6514e_is_idle(dev));
if (dummy_cycles > DEVICE_READ_WRITE_INST_DUMMY_CYCLES_MAX) {
return QSPI_IP6514E_ERR_WRONG_ARGUMENT;
}
change_bits_in_word(&device_read_write_inst_reg_copy,
(uint32_t)opcode,
BITS_PER_BYTE,
DEVICE_READ_WRITE_INST_OPCODE_POS);
change_bits_in_word(&device_read_write_inst_reg_copy,
dummy_cycles,
DEVICE_READ_WRITE_INST_DUMMY_CYCLES_BITS,
DEVICE_READ_WRITE_INST_DUMMY_CYCLES_POS);
*device_read_write_inst_reg = device_read_write_inst_reg_copy;
return QSPI_IP6514E_ERR_NONE;
}
/**
* \brief Given the public SPI mode enumeration, returns the private value it
* maps to in the register field.
*
* \param[in] spi_mode Read/write opcode that will be used for every direct
* read/write
*
* \return Return the correct DEVICE_READ_WRITE_INST_MODE value.
*/
static uint32_t spi_mode_field_value(enum qspi_ip6514e_spi_mode_t spi_mode)
{
switch (spi_mode) {
case QSPI_IP6514E_SPI_MODE:
return DEVICE_READ_WRITE_INST_MODE_SPI;
case QSPI_IP6514E_DSPI_MODE:
return DEVICE_READ_WRITE_INST_MODE_DSPI;
case QSPI_IP6514E_QSPI_MODE:
return DEVICE_READ_WRITE_INST_MODE_QSPI;
default:
return ERROR_VALUE;
}
}
bool qspi_ip6514e_is_idle(struct qspi_ip6514e_dev_t* dev)
{
struct _qspi_ip6514e_reg_map_t *reg_map =
(struct _qspi_ip6514e_reg_map_t *)dev->cfg->base;
return GET_BIT(reg_map->qspi_cfg, QSPI_CFG_IDLE_POS);
}
bool qspi_ip6514e_is_enabled(struct qspi_ip6514e_dev_t* dev)
{
struct _qspi_ip6514e_reg_map_t *reg_map =
(struct _qspi_ip6514e_reg_map_t *)dev->cfg->base;
return GET_BIT(reg_map->qspi_cfg, QSPI_CFG_ENABLE_POS);
}
void qspi_ip6514e_disable(struct qspi_ip6514e_dev_t* dev)
{
struct _qspi_ip6514e_reg_map_t *reg_map =
(struct _qspi_ip6514e_reg_map_t *)dev->cfg->base;
CLR_BIT(reg_map->qspi_cfg, QSPI_CFG_ENABLE_POS);
}
void qspi_ip6514e_enable(struct qspi_ip6514e_dev_t* dev)
{
struct _qspi_ip6514e_reg_map_t *reg_map =
(struct _qspi_ip6514e_reg_map_t *)dev->cfg->base;
SET_BIT(reg_map->qspi_cfg, QSPI_CFG_ENABLE_POS);
}
enum qspi_ip6514e_error_t qspi_ip6514e_set_baud_rate_div(
struct qspi_ip6514e_dev_t* dev,
uint32_t div)
{
struct _qspi_ip6514e_reg_map_t *reg_map =
(struct _qspi_ip6514e_reg_map_t *)dev->cfg->base;
/*
* Wait for the Serial Interface and QSPI pipeline to be IDLE when
* all low level synchronization has been done.
*/
while(!qspi_ip6514e_is_idle(dev));
/* div should be an even number. */
if (((div & 1U) == 1) ||
(div < QSPI_CFG_BAUD_DIV_MIN) ||
(div > QSPI_CFG_BAUD_DIV_MAX)) {
return QSPI_IP6514E_ERR_WRONG_ARGUMENT;
}
/*
* The div value (between 2 and 32) needs to be stored in the register on a
* 4 bits field.
*/
change_bits_in_word(&(reg_map->qspi_cfg),
(div / 2) - 1,
QSPI_CFG_BAUD_DIV_BITS,
QSPI_CFG_BAUD_DIV_POS);
return QSPI_IP6514E_ERR_NONE;
}
enum qspi_ip6514e_error_t qspi_ip6514e_set_spi_mode(
struct qspi_ip6514e_dev_t* dev,
enum qspi_ip6514e_spi_mode_t inst_type,
enum qspi_ip6514e_spi_mode_t addr_type,
enum qspi_ip6514e_spi_mode_t data_type)
{
struct _qspi_ip6514e_reg_map_t *reg_map =
(struct _qspi_ip6514e_reg_map_t *)dev->cfg->base;
uint32_t inst_spi_mode, addr_spi_mode, data_spi_mode;
/*
* A local copy of the Device Read Instruction and Device Write Instruction
* registers is used to limit APB accesses.
*/
uint32_t device_read_inst_cpy = reg_map->device_read_inst;
uint32_t device_write_inst_cpy = reg_map->device_write_inst;
/*
* Wait for the Serial Interface and QSPI pipeline to be IDLE when
* all low level synchronization has been done.
*/
while(!qspi_ip6514e_is_idle(dev));
/*
* First check that the instruction mode is not SPI. If that is the case,
* the address and data mode register fields become DO NOT CARE.
*/
inst_spi_mode = spi_mode_field_value(inst_type);
if (inst_spi_mode == ERROR_VALUE) {
return QSPI_IP6514E_ERR_WRONG_ARGUMENT;
}
if (inst_type != QSPI_IP6514E_SPI_MODE) {
change_bits_in_word(&(reg_map->device_read_inst),
inst_spi_mode,
DEVICE_READ_WRITE_INST_MODE_BITS,
DEVICE_READ_INST_INST_TYPE_POS);
return QSPI_IP6514E_ERR_NONE;
}
/* Now check and set address and data modes. */
addr_spi_mode = spi_mode_field_value(addr_type);
data_spi_mode = spi_mode_field_value(data_type);
if ((addr_spi_mode == ERROR_VALUE) || (data_spi_mode == ERROR_VALUE)) {
return QSPI_IP6514E_ERR_WRONG_ARGUMENT;
}
/* Change the Device Read Instruction register. */
change_bits_in_word(&device_read_inst_cpy,
inst_spi_mode,
DEVICE_READ_WRITE_INST_MODE_BITS,
DEVICE_READ_INST_INST_TYPE_POS);
change_bits_in_word(&device_read_inst_cpy,
addr_spi_mode,
DEVICE_READ_WRITE_INST_MODE_BITS,
DEVICE_READ_WRITE_INST_ADDR_TYPE_POS);
change_bits_in_word(&device_read_inst_cpy,
data_spi_mode,
DEVICE_READ_WRITE_INST_MODE_BITS,
DEVICE_READ_WRITE_INST_DATA_TYPE_POS);
/* Change the Device Write Instruction register. */
change_bits_in_word(&device_write_inst_cpy,
addr_spi_mode,
DEVICE_READ_WRITE_INST_MODE_BITS,
DEVICE_READ_WRITE_INST_ADDR_TYPE_POS);
change_bits_in_word(&device_write_inst_cpy,
data_spi_mode,
DEVICE_READ_WRITE_INST_MODE_BITS,
DEVICE_READ_WRITE_INST_DATA_TYPE_POS);
/* Save the changes. */
reg_map->device_read_inst = device_read_inst_cpy;
reg_map->device_write_inst = device_write_inst_cpy;
return QSPI_IP6514E_ERR_NONE;
}
enum qspi_ip6514e_error_t qspi_ip6514e_cfg_reads(struct qspi_ip6514e_dev_t* dev,
uint8_t opcode,
uint32_t dummy_cycles)
{
return qspi_ip6514e_cfg_reads_writes(dev, opcode, dummy_cycles, CFG_READS);
}
enum qspi_ip6514e_error_t qspi_ip6514e_cfg_writes(
struct qspi_ip6514e_dev_t* dev,
uint8_t opcode,
uint32_t dummy_cycles)
{
return qspi_ip6514e_cfg_reads_writes(dev, opcode, dummy_cycles, CFG_WRITES);
}
enum qspi_ip6514e_error_t qspi_ip6514e_cfg_page_size(
struct qspi_ip6514e_dev_t* dev,
uint32_t page_size)
{
struct _qspi_ip6514e_reg_map_t *reg_map =
(struct _qspi_ip6514e_reg_map_t *)dev->cfg->base;
/*
* Wait for the Serial Interface and QSPI pipeline to be IDLE when
* all low level synchronization has been done.
*/
while(!qspi_ip6514e_is_idle(dev));
if (page_size > DEVICE_SIZE_PAGE_BYTES_MAX) {
return QSPI_IP6514E_ERR_WRONG_ARGUMENT;
}
change_bits_in_word(&(reg_map->device_size),
page_size,
DEVICE_SIZE_PAGE_BYTES_BITS,
DEVICE_SIZE_PAGE_BYTES_POS);
return QSPI_IP6514E_ERR_NONE;
}
enum qspi_ip6514e_error_t qspi_ip6514e_cfg_addr_bytes(
struct qspi_ip6514e_dev_t* dev,
uint32_t bytes_number)
{
struct _qspi_ip6514e_reg_map_t *reg_map =
(struct _qspi_ip6514e_reg_map_t *)dev->cfg->base;
/*
* Wait for the Serial Interface and QSPI pipeline to be IDLE when
* all low level synchronization has been done.
*/
while(!qspi_ip6514e_is_idle(dev));
if (bytes_number < DEVICE_SIZE_ADDR_BYTES_MIN ||
bytes_number > DEVICE_SIZE_ADDR_BYTES_MAX) {
return QSPI_IP6514E_ERR_WRONG_ARGUMENT;
}
change_bits_in_word(&(reg_map->device_size),
bytes_number - 1,
DEVICE_SIZE_ADDR_BYTES_BITS,
DEVICE_SIZE_ADDR_BYTES_POS);
return QSPI_IP6514E_ERR_NONE;
}
void qspi_ip6514e_remap_addr(struct qspi_ip6514e_dev_t* dev, uint32_t offset)
{
struct _qspi_ip6514e_reg_map_t *reg_map =
(struct _qspi_ip6514e_reg_map_t *)dev->cfg->base;
/* Save the enable state to restore it after. */
bool is_enabled = qspi_ip6514e_is_enabled(dev);
if (is_enabled) {
qspi_ip6514e_disable(dev);
}
reg_map->remap_addr = offset;
SET_BIT(reg_map->qspi_cfg, QSPI_CFG_ENABLE_ADDR_REMAP_POS);
if (is_enabled) {
qspi_ip6514e_enable(dev);
}
}
void qspi_ip6514e_disable_remap(struct qspi_ip6514e_dev_t* dev)
{
struct _qspi_ip6514e_reg_map_t *reg_map =
(struct _qspi_ip6514e_reg_map_t *)dev->cfg->base;
/* Save the enable state to restore it after. */
bool is_enabled = qspi_ip6514e_is_enabled(dev);
if (is_enabled) {
qspi_ip6514e_disable(dev);
}
CLR_BIT(reg_map->qspi_cfg, QSPI_CFG_ENABLE_ADDR_REMAP_POS);
if (is_enabled) {
qspi_ip6514e_enable(dev);
}
}
void qspi_ip6514e_reset_regs(struct qspi_ip6514e_dev_t* dev)
{
struct _qspi_ip6514e_reg_map_t *reg_map =
(struct _qspi_ip6514e_reg_map_t *)dev->cfg->base;
/* Restore the default value of the QSPI Configuration register. */
reg_map->qspi_cfg = QSPI_CFG_REG_RESET_VALUE;
/* Restore the default value of the Device R/W Instruction registers. */
reg_map->device_read_inst = DEVICE_READ_INSTR_REG_RESET_VALUE;
reg_map->device_write_inst = DEVICE_WRITE_INSTR_REG_RESET_VALUE;
/* Restore the default value of the Device Size Configuration register. */
reg_map->device_size = DEVICE_SIZE_CFG_REG_RESET_VALUE;
/* Restore the default value of the Remap Address register. */
reg_map->remap_addr = REMAP_ADDR_REG_RESET_VALUE;
/* Restore the default value of the Flash Command Control register. */
reg_map->flash_cmd_ctrl = FLASH_CMD_CONTROL_REG_RESET_VALUE;
/* Restore the default value of the Flash Command Address register. */
reg_map->flash_cmd_addr = FLASH_CMD_ADDRESS_REG_RESET_VALUE;
/* Restore the default value of the Flash Command Write Data registers. */
reg_map->flash_cmd_write_data_lower = FLASH_CMD_WRITE_DATA_REG_RESET_VALUE;
reg_map->flash_cmd_write_data_upper = FLASH_CMD_WRITE_DATA_REG_RESET_VALUE;
/*
* This function does not affect the Flash Command Read Data registers
* which are completely Read-Only.
*/
}
enum qspi_ip6514e_error_t qspi_ip6514e_send_cmd(struct qspi_ip6514e_dev_t* dev,
uint8_t opcode,
void *read_data,
uint32_t read_len,
const void *write_data,
uint32_t write_len,
uint32_t addr,
uint32_t addr_bytes_number,
uint32_t dummy_cycles)
{
struct _qspi_ip6514e_reg_map_t *reg_map =
(struct _qspi_ip6514e_reg_map_t *)dev->cfg->base;
/* To limit APB accesses, we set this reg up locally before */
uint32_t flash_cmd_ctrl = 0U;
bool read_requested = ((read_data != NULL) && (read_len != 0));
bool write_requested = ((write_data != NULL) && (write_len != 0));
bool addr_requested = (addr_bytes_number != 0);
/*
* To prevent unaligned and byte or halfbyte accesses to the APB registers,
* a word aligned buffer is used to temporary transfer the data before doing
* word accesses on these registers from that buffer.
*/
uint32_t data_regs[DATA_REG_NUMBER] = {0};
if (read_len > FLASH_CMD_CTRL_READ_BYTES_MAX) {
return QSPI_IP6514E_ERR_WRONG_ARGUMENT;
}
if (write_len > FLASH_CMD_CTRL_WRITE_BYTES_MAX) {
return QSPI_IP6514E_ERR_WRONG_ARGUMENT;
}
if (addr_bytes_number > FLASH_CMD_CTRL_ADDR_BYTES_MAX) {
return QSPI_IP6514E_ERR_WRONG_ARGUMENT;
}
if (dummy_cycles > FLASH_CMD_CTRL_DUMMY_CYCLES_MAX) {
return QSPI_IP6514E_ERR_WRONG_ARGUMENT;
}
if (read_requested && write_requested) {
return QSPI_IP6514E_ERR_WRONG_ARGUMENT;
}
change_bits_in_word(&flash_cmd_ctrl,
(uint32_t)opcode,
BITS_PER_BYTE,
FLASH_CMD_CTRL_OPCODE_POS);
/* Enable read if requested */
if (read_requested) {
SET_BIT(flash_cmd_ctrl, FLASH_CMD_CTRL_READ_ENABLE_POS);
change_bits_in_word(&flash_cmd_ctrl,
read_len - 1,
FLASH_CMD_CTRL_READ_BYTES_BITS,
FLASH_CMD_CTRL_READ_BYTES_POS);
}
/* Enable write if requested */
if (write_requested) {
SET_BIT(flash_cmd_ctrl, FLASH_CMD_CTRL_WRITE_ENABLE_POS);
change_bits_in_word(&flash_cmd_ctrl,
write_len - 1,
FLASH_CMD_CTRL_WRITE_BYTES_BITS,
FLASH_CMD_CTRL_WRITE_BYTES_POS);
if (IS_ADDR_ALIGNED(write_data) && IS_ADDR_ALIGNED(write_len)) {
/*
* Optimised case when write_data is word aligned and write_len is
* 4 or 8.
*/
reg_map->flash_cmd_write_data_lower = *(uint32_t *)write_data;
if (write_len == FLASH_CMD_CTRL_WRITE_BYTES_MAX) {
reg_map->flash_cmd_write_data_upper =
*((uint32_t *)write_data + 1);
}
} else {
/*
* data_regs is used as a buffer to only do unaligned access on the
* AHB bus and word aligned accesses to the APB registers.
*/
memcpy((void *)data_regs, write_data, write_len);
/*
* Only write_len bytes will be written even if both data registers
* are written.
*/
reg_map->flash_cmd_write_data_lower = data_regs[DATA_REG_LOWER];
reg_map->flash_cmd_write_data_upper = data_regs[DATA_REG_UPPER];
}
}
/* Enable the address if requested */
if (addr_requested) {
SET_BIT(flash_cmd_ctrl, FLASH_CMD_CTRL_ADDR_ENABLE_POS);
reg_map->flash_cmd_addr = addr;
change_bits_in_word(&flash_cmd_ctrl,
addr_bytes_number - 1,
FLASH_CMD_CTRL_ADDR_BYTES_BITS,
FLASH_CMD_CTRL_ADDR_BYTES_POS);
}
/* Put dummy cycles number */
change_bits_in_word(&flash_cmd_ctrl,
dummy_cycles,
FLASH_CMD_CTRL_DUMMY_CYCLES_BITS,
FLASH_CMD_CTRL_DUMMY_CYCLES_POS);
/* Copy the Flash Command Control register and execute the command */
reg_map->flash_cmd_ctrl = flash_cmd_ctrl;
SET_BIT(reg_map->flash_cmd_ctrl, FLASH_CMD_CTRL_EXECUTE_POS);
/* Wait for termination */
while (GET_BIT(reg_map->flash_cmd_ctrl, FLASH_CMD_CTRL_BUSY_POS));
/*
* Recolt the read data if it was requested. read_len validity has already
* been verified at this point.
*/
if (read_requested) {
if (IS_ADDR_ALIGNED(read_data) && IS_ADDR_ALIGNED(read_len)) {
/*
* Optimised case when read_data is word aligned and read_len is
* 4 or 8.
*/
*(uint32_t *)read_data = reg_map->flash_cmd_read_data_lower;
if (read_len == FLASH_CMD_CTRL_READ_BYTES_MAX) {
*((uint32_t *)read_data + 1) =
reg_map->flash_cmd_read_data_upper;
}
} else {
/*
* Only read_len bytes have been written even if both data registers
* are written.
*/
data_regs[DATA_REG_LOWER] = reg_map->flash_cmd_read_data_lower;
data_regs[DATA_REG_UPPER] = reg_map->flash_cmd_read_data_upper;
/*
* data_regs is used as a buffer to only do unaligned access on the
* AHB bus and word aligned accesses to the APB registers.
*/
memcpy(read_data, (void *)data_regs, read_len);
}
}
return QSPI_IP6514E_ERR_NONE;
}
void qspi_ip6514e_send_simple_cmd(struct qspi_ip6514e_dev_t* dev,
uint8_t opcode)
{
/*
* No read/write data, no address, no dummy cycles.
* Given the arguments, this function can not fail.
*/
(void)qspi_ip6514e_send_cmd(dev,
opcode,
ARG_PTR_NOT_USED,
ARG_NOT_USED,
ARG_PTR_NOT_USED,
ARG_NOT_USED,
ARG_NOT_USED,
ARG_NOT_USED,
0);
}
enum qspi_ip6514e_error_t qspi_ip6514e_send_read_cmd(
struct qspi_ip6514e_dev_t* dev,
uint8_t opcode,
void *read_data,
uint32_t read_len,
uint32_t addr,
uint32_t addr_bytes_number,
uint32_t dummy_cycles)
{
/* Read arguments are expected */
if (read_data == ARG_PTR_NOT_USED || read_len == ARG_NOT_USED) {
return QSPI_IP6514E_ERR_WRONG_ARGUMENT;
}
/* No write data */
return qspi_ip6514e_send_cmd(dev,
opcode,
read_data,
read_len,
ARG_PTR_NOT_USED,
ARG_NOT_USED,
addr,
addr_bytes_number,
dummy_cycles);
}
enum qspi_ip6514e_error_t qspi_ip6514e_send_write_cmd(
struct qspi_ip6514e_dev_t* dev,
uint8_t opcode,
const void *write_data,
uint32_t write_len,
uint32_t addr,
uint32_t addr_bytes_number,
uint32_t dummy_cycles)
{
/* Write arguments are expected */
if (write_data == ARG_PTR_NOT_USED || write_len == ARG_NOT_USED) {
return QSPI_IP6514E_ERR_WRONG_ARGUMENT;
}
/* No read data, no dummy cycles */
return qspi_ip6514e_send_cmd(dev,
opcode,
ARG_PTR_NOT_USED,
ARG_NOT_USED,
write_data,
write_len,
addr,
addr_bytes_number,
dummy_cycles);
}

View File

@ -0,0 +1,418 @@
/*
* Copyright (c) 2018 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file qspi_ip6514e_drv.h
* \brief Driver for Cadence QSPI Flash Controller IP.
* There are two ways to communicate with the flash memory device:
* - issue AHB requests for direct read and writes in the Flash memory
* mapped address zone. The commands used for those can be configured
* by the driver
* - send a command to the device to access his internal registers and
* do other operations like erasing a sector
* At reset, the QSPI controller will work in a default mode which will
* allow to do basic commands. It should be configured with the
* flash memory device specifications for optimal use for commands and
* direct reads/writes. Here is an example of configuration:
* - send command to activate QSPI mode on the flash memory device
* - send command to change dummy cycles on the flash memory device
* - check if any operation is ungoing
* - disable the QSPI controller
* - change the baud rate divisor
* - activate the QSPI mode on the controller
* - change the dummy cycles number and opcode for reads/writes
* - change the number of bytes per page
* - change the number of address bytes
* - activate the QSPI controller
*
* Warning: none of the functions declared here check if the dev
* argument points to NULL.
*/
#ifndef __QSPI_IP6514E_DRV_H__
#define __QSPI_IP6514E_DRV_H__
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Cadence QSPI IP6514E error enumeration types
*/
enum qspi_ip6514e_error_t {
QSPI_IP6514E_ERR_NONE,
QSPI_IP6514E_ERR_WRONG_ARGUMENT,
QSPI_IP6514E_ERR_CONTROLLER_NOT_DISABLED,
QSPI_IP6514E_ERR_READ_IN_PROGRESS,
QSPI_IP6514E_ERR_WRITE_IN_PROGRESS,
/* Any new error should be added to the enumeration type error of
* the corresponding Flash device library as well.
*/
};
/**
* \brief Cadence QSPI IP6514E SPI modes
*/
enum qspi_ip6514e_spi_mode_t {
QSPI_IP6514E_SPI_MODE,
/*!< Use 1 line for Instruction, Address and Data */
QSPI_IP6514E_DSPI_MODE,
/*!< Use 2 lines for Instruction, Address and Data */
QSPI_IP6514E_QSPI_MODE,
/*!< Use 4 lines for Instruction, Address and Data */
};
/**
* \brief Cadence QSPI IP6514E device configuration structure
*/
struct qspi_ip6514e_dev_cfg_t {
const uint32_t base; /*!< QSPI IP6514E base address */
/*
* If not all the AHB wires are connected to the QSPI Flash Controller the
* driver can still access all of the Flash memory. The bits of this value
* should be put to 1 for every wire that is connected. Set it to
* 0xFFFFFFFFU if all AHB address wires are connected to the
* QSPI Flash Controller.
*/
uint32_t addr_mask;
};
/**
* \brief Cadence QSPI IP6514E device structure
*/
struct qspi_ip6514e_dev_t {
const struct qspi_ip6514e_dev_cfg_t* const cfg;
/*!< QSPI IP6514E configuration */
};
/**
* \brief Check if the controller is idle.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
*
* \return true if the controller is idle, false otherwise.
*/
bool qspi_ip6514e_is_idle(struct qspi_ip6514e_dev_t* dev);
/**
* \brief Check if the controller is enabled.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
*
* \return true if the controller is enabled, false otherwise.
*/
bool qspi_ip6514e_is_enabled(struct qspi_ip6514e_dev_t* dev);
/**
* \brief Disable the QSPI controller.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
*/
void qspi_ip6514e_disable(struct qspi_ip6514e_dev_t* dev);
/**
* \brief Enable the QSPI controller.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
*/
void qspi_ip6514e_enable(struct qspi_ip6514e_dev_t* dev);
/**
* \brief Change the baud rate divisor.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
* \param[in] div Baud rate divisor value. It can only be an even number
* between 2 and 32 (both included).
*
* \return Returns error code as specified in \ref qspi_ip6514e_error_t
*
* \note The QSPI frequency is calculated dividing the QSPI controller clock by
* this divisor. Please check Flash memory device specifications to know
* the maximal frequency that can be used.
* \note The QSPI controller should be disabled before calling this function.
*/
enum qspi_ip6514e_error_t qspi_ip6514e_set_baud_rate_div(
struct qspi_ip6514e_dev_t* dev,
uint32_t div);
/**
* \brief Set SPI mode for instruction, address and data.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
* \param[in] inst_type SPI mode to use for the instruction part of the command
* \param[in] addr_type SPI mode to use for the address part of the command
* \param[in] data_type SPI mode to use for the data part of the command
*
* \return Returns error code as specified in \ref qspi_ip6514e_error_t
*
* \note The QSPI controller should be idle before calling this function.
* \note Changing this setting will affect commands and direct operations.
*/
enum qspi_ip6514e_error_t qspi_ip6514e_set_spi_mode(
struct qspi_ip6514e_dev_t* dev,
enum qspi_ip6514e_spi_mode_t inst_type,
enum qspi_ip6514e_spi_mode_t addr_type,
enum qspi_ip6514e_spi_mode_t data_type);
/**
* \brief Configure read commands for direct reads.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
* \param[in] opcode Read opcode that will be used for every direct read
* \param[in] dummy_cycles Number of dummy cycles to wait before triggering the
* command, this value must be between 0 and 31
* (both included)
*
* \return Returns error code as specified in \ref qspi_ip6514e_error_t
*
* \note The QSPI controller should be idle before calling this function.
*/
enum qspi_ip6514e_error_t qspi_ip6514e_cfg_reads(struct qspi_ip6514e_dev_t* dev,
uint8_t opcode,
uint32_t dummy_cycles);
/**
* \brief Configure write commands for direct writes.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
* \param[in] opcode Write opcode that will be used for every direct write
* \param[in] dummy_cycles Number of dummy cycles to wait before triggering the
* command, this value must be between 0 and 31
* (both included)
*
* \return Returns error code as specified in \ref qspi_ip6514e_error_t
*
* \note The QSPI controller should be idle before calling this function.
*/
enum qspi_ip6514e_error_t qspi_ip6514e_cfg_writes(
struct qspi_ip6514e_dev_t* dev,
uint8_t opcode,
uint32_t dummy_cycles);
/**
* \brief Change the number of bytes per device page.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
* \param[in] page_size Number of bytes per device page, must be between 0
* and 4095 (both included)
*
* \return Returns error code as specified in \ref qspi_ip6514e_error_t
*
* \note The QSPI controller should be idle before calling this function.
* \note This function will affect direct reads/writes.
*/
enum qspi_ip6514e_error_t qspi_ip6514e_cfg_page_size(
struct qspi_ip6514e_dev_t* dev,
uint32_t page_size);
/**
* \brief Change the number of device address bytes.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
* \param[in] bytes_number Number of device address bytes, must be between 1
* and 16 (both included)
*
* \return Returns error code as specified in \ref qspi_ip6514e_error_t
*
* \note The QSPI controller should be idle before calling this function.
* \note This function will affect direct reads/writes.
*/
enum qspi_ip6514e_error_t qspi_ip6514e_cfg_addr_bytes(
struct qspi_ip6514e_dev_t* dev,
uint32_t bytes_number);
/**
* \brief Remap the incoming AHB address with an offset for direct accesses.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
* \param[in] offset Offset that will be added to the incoming AHB address to
* access the Flash memory
*
* \note This function will only affect direct reads/writes.
* \note This function does not check if the resulting address is out of memory
* bounds.
*/
void qspi_ip6514e_remap_addr(struct qspi_ip6514e_dev_t* dev, uint32_t offset);
/**
* \brief Disable AHB address remapping for direct accesses.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
*
* \note This function will disable the controller if it is not already
* disabled and enable it again (if it was).
* \note This function will only affect direct reads/writes.
*/
void qspi_ip6514e_disable_remap(struct qspi_ip6514e_dev_t* dev);
/**
* \brief Restore the default value of the QSPI controller registers.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
*
* \note The QSPI controller should be disabled before calling this function.
*/
void qspi_ip6514e_reset_regs(struct qspi_ip6514e_dev_t* dev);
/**
* \brief Send a command to the flash memory device using the Software Triggered
* Instruction Generator (STIG).
*
* \param[in] dev QSPI IP6514E device struct
* \ref qspi_ip6514e_dev_t
* \param[in] opcode Opcode for the command.
* \param[out] read_data Pointer to a memory zone where the read_len
* bytes read will be written to. If no data is to
* be read for the command,
* this argument should be NULL.
* \param[in] read_len Number of bytes to read for the command. If
* no bytes are to be read, use 0 for argument
* otherwise between 1 and 8 bytes (both
* included) can be read.
* \param[in] write_data Pointer to a memory zone where are
* located the write_len bytes to write for
* this command. If no bytes are to be written,
* use NULL as argument.
* \param[in] write_len Number of bytes to write for the command. If
* no bytes are to be written, use 0 for
* argument otherwise between 1 and 8 bytes
* (both included) can be written.
* \param[in] addr Address used for the command
* \param[in] addr_bytes_number Number of address bytes for this command.
* If an address is not needed for the command,
* use 0 for argument, otherwise between 1 and
* 4 bytes (both included) can be used.
* \param[in] dummy_cycles Number of dummy cycles required for the
* command, between 0 and 31 (both included).
*
* \return Returns error code as specified in \ref qspi_ip6514e_error_t
*
* \note Check the flash memory device specifications for the possible opcodes
* that can be used and the other informations needed for this function.
* \note The SPI mode used for this command is the one set with the
* \ref qspi_ip6514e_activate_qspi_mode function or the default one.
*/
enum qspi_ip6514e_error_t qspi_ip6514e_send_cmd(struct qspi_ip6514e_dev_t* dev,
uint8_t opcode,
void *read_data,
uint32_t read_len,
const void *write_data,
uint32_t write_len,
uint32_t addr,
uint32_t addr_bytes_number,
uint32_t dummy_cycles);
/**
* \brief Send a simple command to the flash memory device using the Software
* Triggered Instruction Generator (STIG) with no data arguments.
* This command can be used for example to send the WRITE ENABLE command.
*
* \param[in] dev QSPI IP6514E device struct \ref qspi_ip6514e_dev_t
* \param[in] opcode Opcode for the command.
*
* \note Check the flash memory device specifications for the possible opcodes
* that can be used and the other informations needed for this function.
* \note The SPI mode used for this command is the one set with the
* \ref qspi_ip6514e_activate_qspi_mode function or the default one.
*/
void qspi_ip6514e_send_simple_cmd(struct qspi_ip6514e_dev_t* dev,
uint8_t opcode);
/**
* \brief Send a read command to the flash memory device using the Software
* Triggered Instruction Generator (STIG). This command can be used to
* read Flash memory data or registers.
*
* \param[in] dev QSPI IP6514E device struct
* \ref qspi_ip6514e_dev_t
* \param[in] opcode Opcode for the command.
* \param[out] read_data Pointer to a memory zone where the
* read_len bytes read will be written to.
* \param[in] read_len Number of bytes to read for the command.
* Between 1 and 8 bytes (both included) can be
* read.
* \param[in] addr Address used for the command
* \param[in] addr_bytes_number Number of address bytes for this command.
* If an address is not needed for the command,
* use 0 for argument, otherwise between 1 and
* 4 bytes (both included) can be used.
* \param[in] dummy_cycles Number of dummy cycles required for the
* command, between 0 and 31 (both included).
*
* \return Returns error code as specified in \ref qspi_ip6514e_error_t
*
* \note Check the flash memory device specifications for the possible opcodes
* that can be used and the other informations needed for this function.
* \note The SPI mode used for this command is the one set with the
* \ref qspi_ip6514e_activate_qspi_mode function or the default one.
*/
enum qspi_ip6514e_error_t qspi_ip6514e_send_read_cmd(
struct qspi_ip6514e_dev_t* dev,
uint8_t opcode,
void *read_data,
uint32_t read_len,
uint32_t addr,
uint32_t addr_bytes_number,
uint32_t dummy_cycles);
/**
* \brief Send a write command to the flash memory device using the Software
* Triggered Instruction Generator (STIG). This command can be used to
* write Flash memory or registers.
*
* \param[in] dev QSPI IP6514E device struct
* \ref qspi_ip6514e_dev_t
* \param[in] opcode Opcode for the command.
* \param[in] write_data Pointer to a memory zone where are
* located the write_len bytes to write for
* this command.
* \param[in] write_len Number of bytes to write for the command.
* Between 1 and 8 bytes (both included) can be
* written.
* \param[in] addr Address used for the command
* \param[in] addr_bytes_number Number of address bytes for this command.
* If an address is not needed for the command,
* use 0 for argument, otherwise between 1 and
* 4 bytes (both included) can be used.
* \param[in] dummy_cycles Number of dummy cycles required for the
* command, between 0 and 31 (both included).
*
* \return Returns error code as specified in \ref qspi_ip6514e_error_t
*
* \note Check the flash memory device specifications for the possible opcodes
* that can be used and the other informations needed for this function.
* \note The SPI mode used for this command is the one set with the
* \ref qspi_ip6514e_activate_qspi_mode function or the default one.
*/
enum qspi_ip6514e_error_t qspi_ip6514e_send_write_cmd(
struct qspi_ip6514e_dev_t* dev,
uint8_t opcode,
const void *write_data,
uint32_t write_len,
uint32_t addr,
uint32_t addr_bytes_number,
uint32_t dummy_cycles);
#ifdef __cplusplus
}
#endif
#endif /* __QSPI_IP6514E_DRV_H__ */

View File

@ -0,0 +1,227 @@
/*
* Copyright (c) 2016-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file timer_cmsdk_drv.c
* \brief Generic driver for CMSDK APB Timers.
* The timer is a 32-bit down-counter with the following features:
* - optional programmable external clock source
* - programmable interrupt source, triggered if counter reaches 0
* - automatic reload if counter reaches 0
*/
#include "timer_cmsdk_drv.h"
/** Setter bit manipulation macro */
#define SET_BIT(WORD, BIT_INDEX) ((WORD) |= (1U << (BIT_INDEX)))
/** Clearing bit manipulation macro */
#define CLR_BIT(WORD, BIT_INDEX) ((WORD) &= ~(1U << (BIT_INDEX)))
/** Getter bit manipulation macro */
#define GET_BIT(WORD, BIT_INDEX) (bool)(((WORD) & (1U << (BIT_INDEX))))
/**
* \brief Timer register map structure
*
*/
struct timer_cmsdk_reg_map_t {
volatile uint32_t ctrl; /* Offset: 0x000 (R/W) control register */
volatile uint32_t value; /* Offset: 0x004 (R/W) current value register */
volatile uint32_t reload; /* Offset: 0x008 (R/W) reload value register */
union {
volatile uint32_t intstatus; /* Offset: 0x00C (R/ ) interrupt
* status register
*/
volatile uint32_t intclear; /* Offset: 0x00C ( /W) interrupt
* clear register
*/
}intreg;
};
/**
* \brief CTRL register bit definitions
*
*/
enum ctrl_reg_bits_t {
CTRL_REG_ENUM_ENABLE_INDEX = 0,
CTRL_REG_ENUM_EXTERNAL_INPUT_ENABLE_INDEX = 1,
CTRL_REG_ENUM_EXTERNAL_INPUT_CLOCK_INDEX = 2,
CTRL_REG_ENUM_IRQ_ENABLE_INDEX = 3
};
/**
* \brief INTSTATUS/INTCLEAR register bit definitions
*
*/
enum interrupt_reg_bits_t {
INTERRUPT_REG_ENUM_STATUS_AND_CLEAR_INDEX = 0
};
void timer_cmsdk_init(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
if (dev->data->is_initialized == 0) {
register_map->ctrl = 0;
register_map->reload = TIMER_CMSDK_DEFAULT_RELOAD;
dev->data->is_initialized = 1;
}
}
bool timer_cmsdk_is_initialized(const struct timer_cmsdk_dev_t* dev)
{
return dev->data->is_initialized;
}
void timer_cmsdk_enable_external_input(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
SET_BIT(register_map->ctrl, CTRL_REG_ENUM_EXTERNAL_INPUT_ENABLE_INDEX);
}
void timer_cmsdk_disable_external_input(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
CLR_BIT(register_map->ctrl, CTRL_REG_ENUM_EXTERNAL_INPUT_ENABLE_INDEX);
}
bool timer_cmsdk_is_external_input_enabled(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
return GET_BIT(register_map->ctrl,
CTRL_REG_ENUM_EXTERNAL_INPUT_ENABLE_INDEX);
}
void timer_cmsdk_set_clock_to_internal(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
CLR_BIT(register_map->ctrl, CTRL_REG_ENUM_EXTERNAL_INPUT_CLOCK_INDEX);
}
void timer_cmsdk_set_clock_to_external(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
SET_BIT(register_map->ctrl, CTRL_REG_ENUM_EXTERNAL_INPUT_CLOCK_INDEX);
}
bool timer_cmsdk_is_clock_external(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
return GET_BIT(register_map->ctrl,
CTRL_REG_ENUM_EXTERNAL_INPUT_CLOCK_INDEX);
}
void timer_cmsdk_enable(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
SET_BIT(register_map->ctrl, CTRL_REG_ENUM_ENABLE_INDEX);
}
void timer_cmsdk_disable(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
CLR_BIT(register_map->ctrl, CTRL_REG_ENUM_ENABLE_INDEX);
}
bool timer_cmsdk_is_enabled(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
return GET_BIT(register_map->ctrl, CTRL_REG_ENUM_ENABLE_INDEX);
}
void timer_cmsdk_enable_interrupt(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
SET_BIT(register_map->ctrl, CTRL_REG_ENUM_IRQ_ENABLE_INDEX);
}
void timer_cmsdk_disable_interrupt(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
CLR_BIT(register_map->ctrl, CTRL_REG_ENUM_IRQ_ENABLE_INDEX);
}
bool timer_cmsdk_is_interrupt_enabled(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
return GET_BIT(register_map->ctrl, CTRL_REG_ENUM_IRQ_ENABLE_INDEX);
}
bool timer_cmsdk_is_interrupt_active(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
return GET_BIT(register_map->intreg.intstatus,
INTERRUPT_REG_ENUM_STATUS_AND_CLEAR_INDEX);
}
void timer_cmsdk_clear_interrupt(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
SET_BIT(register_map->intreg.intclear,
INTERRUPT_REG_ENUM_STATUS_AND_CLEAR_INDEX);
}
uint32_t timer_cmsdk_get_current_value(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
return register_map->value;
}
void timer_cmsdk_set_reload_value(const struct timer_cmsdk_dev_t* dev,
uint32_t reload)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
register_map->reload = reload;
}
void timer_cmsdk_reset(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
register_map->value = register_map->reload;
}
uint32_t timer_cmsdk_get_reload_value(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
return register_map->reload;
}
uint32_t timer_cmsdk_get_elapsed_value(const struct timer_cmsdk_dev_t* dev)
{
struct timer_cmsdk_reg_map_t* register_map =
(struct timer_cmsdk_reg_map_t*)dev->cfg->base;
return register_map->reload - register_map->value;
}

View File

@ -0,0 +1,256 @@
/*
* Copyright (c) 2016-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file timer_cmsdk_drv.h
* \brief Generic driver for CMSDK APB Timers.
* The timer is a 32-bit down-counter with the following features:
* - optional programmable external clock source
* - programmable interrupt source, triggered if counter reaches 0
* - automatic reload if counter reaches 0
*/
#ifndef __TIMER_CMSDK_DRV_H__
#define __TIMER_CMSDK_DRV_H__
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Maximum reload value */
#define TIMER_CMSDK_MAX_RELOAD UINT32_MAX /* max of 32-bit */
#define TIMER_CMSDK_DEFAULT_RELOAD TIMER_CMSDK_MAX_RELOAD
/** CMSDK timer device configuration structure */
struct timer_cmsdk_dev_cfg_t {
const uintptr_t base; /*!< Timer base address */
};
/** CMSDK timer device data structure */
struct timer_cmsdk_dev_data_t {
bool is_initialized; /*!< Indicates if the timer is initialized */
};
/* CMSDK timer device structure */
struct timer_cmsdk_dev_t {
const struct timer_cmsdk_dev_cfg_t* const cfg; /*!< Timer configuration */
struct timer_cmsdk_dev_data_t* const data; /*!< Timer data */
};
/**
* \brief Initializes timer to a known default state, which is:
* - timer disabled
* - timer interrupt disabled
* - clock source set to internal
* - external input disabled
* - reload value maxed out
* Init should be called prior to any other process and
* it's the caller's responsibility to follow proper call order.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*/
void timer_cmsdk_init(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Checks if a timer is initialized.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*
* \return true if initialized, false otherwise
*/
bool timer_cmsdk_is_initialized(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Enables external input, which could be used as clock source
* by calling \ref timer_cmsdk_set_clock_to_external.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*/
void timer_cmsdk_enable_external_input(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Disables external input.
* Make sure if the timer is explicitly wanted to be stopped or set
* the clock source to internal by \ref timer_cmsdk_set_clock_to_internal
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*/
void timer_cmsdk_disable_external_input(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Checks if external input is enabled.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*
* \return true if enabled, false otherwise
*/
bool timer_cmsdk_is_external_input_enabled(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Sets the clock source to internal.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*/
void timer_cmsdk_set_clock_to_internal(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Sets the clock source to external.
* Make sure external input is enabled correspondingly
* by \ref timer_cmsdk_enable_external_input.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*/
void timer_cmsdk_set_clock_to_external(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Checks if clock source is external input.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*
* \return true if external, false if internal
*/
bool timer_cmsdk_is_clock_external(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Enables timer operation.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*/
void timer_cmsdk_enable(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Disables the given hardware timer.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*/
void timer_cmsdk_disable(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Checks if a timer is enabled.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*
* \return true if enabled, false otherwise
*/
bool timer_cmsdk_is_enabled(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Enables timer interrupt.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*/
void timer_cmsdk_enable_interrupt(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Disables timer interrupt.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*/
void timer_cmsdk_disable_interrupt(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Checks if a timer interrupt is enabled.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*
* \return true if enabled, false otherwise
*/
bool timer_cmsdk_is_interrupt_enabled(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Gets timer interrupt status
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*
* * \return true if active, false otherwise
*/
bool timer_cmsdk_is_interrupt_active(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Clears timer interrupt
* The interrupt request is held until it is cleared.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*/
void timer_cmsdk_clear_interrupt(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Reads timer current value.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*
* \return Timer value
*/
uint32_t timer_cmsdk_get_current_value(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Sets the reload value of the selected timer.
*
* New reload value takes effect when:
* - timer is restarted
* - on timer underflow
* - when timer_cmsdk_reset is called
*
* \note In r1p0 technical reference manual it's incorrectly stated
* writing the reload value automatically sets the current value also.
* r1p1 technical reference manual includes the fix.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
* \param[in] reload Timer reload value to set.
* This is the start value of the 32-bit down counter,
* which automatically reloaded if 0 is reached.
*/
void timer_cmsdk_set_reload_value(const struct timer_cmsdk_dev_t* dev,
uint32_t reload);
/**
* \brief Resets the timer counter to the reload value instantly
* (i.e. without waiting for underflow).
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*/
void timer_cmsdk_reset(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Gets the reload value of the selected timer.
* This is the start value of the 32-bit down counter,
* which is automatically reloaded if 0 is reached by the counter.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*
* \return Reload value of the selected timer.
*/
uint32_t timer_cmsdk_get_reload_value(const struct timer_cmsdk_dev_t* dev);
/**
* \brief Reads the number of ticks elapsed in the current cycle.
*
* \param[in] dev Timer configuration \ref timer_cmsdk_dev_t
*
* \return Get elapsed number of ticks since last reload was set.
* Elapsed = (Reload value - Current value)
*/
uint32_t timer_cmsdk_get_elapsed_value(const struct timer_cmsdk_dev_t* dev);
#ifdef __cplusplus
}
#endif
#endif /* __TIMER_CMSDK_DRV_H__ */

View File

@ -0,0 +1,170 @@
/*
* Copyright (c) 2018 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file timer_gp_drv.c
*
* \brief Generic driver for general purpose timer.
*/
#include "timer_gp_drv.h"
/** Setter bit manipulation macro */
#define SET_BIT(WORD, BIT_INDEX) ((WORD) |= (1U << (BIT_INDEX)))
/** Clearing bit manipulation macro */
#define CLR_BIT(WORD, BIT_INDEX) ((WORD) &= ~(1U << (BIT_INDEX)))
/** Getter bit manipulation macro */
#define GET_BIT(WORD, BIT_INDEX) (bool)(((WORD) & (1U << (BIT_INDEX))))
/**
* \brief Timer register map structure
*
*/
struct timer_gp_reg_map_t {
volatile uint32_t reset; /*!< Offset: 0x000 (R/W) Control Reset */
volatile uint32_t irq_mask; /*!< Offset: 0x004 (R/W) Masked Interrupt */
volatile uint32_t irq_clear; /*!< Offset: 0x008 (R/W) Interrupt Clear */
volatile uint32_t reserved; /*!< Offset: 0x00C Reserved */
volatile uint32_t alarm0; /*!< Offset: 0x010 (R/W) Alarm0 data value */
volatile uint32_t alarm1; /*!< Offset: 0x014 (R/W) Alarm1 data value */
volatile uint32_t irq_status; /*!< Offset: 0x018 (R) Raw Interrupt status */
volatile uint32_t counter; /*!< Offset: 0x01C (R) Counter data value */
};
/**
* \brief Reset control register bit identifiers
*
*/
enum reset_reg_bits_t{
RESET_REG_INDEX = 0
/* 1-31: Reserved. Read as zero. Do No Modify (DNM). */
};
void timer_gp_init(const struct timer_gp_dev_t* dev)
{
if (dev->data->is_initialized == false) {
timer_gp_interrupt_disable(dev, TIMER_GP_ALARM_0);
timer_gp_interrupt_clear(dev, TIMER_GP_ALARM_0);
timer_gp_interrupt_disable(dev, TIMER_GP_ALARM_1);
timer_gp_interrupt_clear(dev, TIMER_GP_ALARM_1);
timer_gp_set_alarm_value(dev, TIMER_GP_ALARM_0, dev->data->alarm0_init);
timer_gp_set_alarm_value(dev, TIMER_GP_ALARM_1, dev->data->alarm1_init);
timer_gp_counter_reset(dev);
dev->data->is_initialized = true;
}
}
void timer_gp_counter_reset(const struct timer_gp_dev_t* dev)
{
struct timer_gp_reg_map_t* const register_map =
(struct timer_gp_reg_map_t*)dev->cfg->base;
SET_BIT(register_map->reset, RESET_REG_INDEX);
/* Reset bit is not self-clearing and some pulse width is required
* for successful reset, so we have to check whether the
* timer counter is set to reset value. Until this bit is asserted
* the timer won't be started.
* The timer is running only if the reset bit is cleared.*/
while (timer_gp_get_counter(dev) != TIMER_GP_DEFAULT_RESET)
;
CLR_BIT(register_map->reset, RESET_REG_INDEX);
}
uint32_t timer_gp_get_counter(const struct timer_gp_dev_t* dev)
{
struct timer_gp_reg_map_t* const register_map =
(struct timer_gp_reg_map_t*)dev->cfg->base;
return register_map->counter;
}
void timer_gp_interrupt_enable(const struct timer_gp_dev_t* dev,
const enum timer_gp_alarm_identifier_t alarm)
{
struct timer_gp_reg_map_t* const register_map =
(struct timer_gp_reg_map_t*)dev->cfg->base;
SET_BIT(register_map->irq_mask, alarm);
}
void timer_gp_interrupt_disable(const struct timer_gp_dev_t* dev,
const enum timer_gp_alarm_identifier_t alarm)
{
struct timer_gp_reg_map_t* const register_map =
(struct timer_gp_reg_map_t*)dev->cfg->base;
CLR_BIT(register_map->irq_mask, alarm);
}
bool timer_gp_interrupt_is_enabled(const struct timer_gp_dev_t* dev,
const enum timer_gp_alarm_identifier_t alarm)
{
struct timer_gp_reg_map_t* const register_map =
(struct timer_gp_reg_map_t*)dev->cfg->base;
return GET_BIT(register_map->irq_mask, alarm);
}
bool timer_gp_interrupt_is_active(const struct timer_gp_dev_t* dev,
const enum timer_gp_read_alarm_identifier_t alarm)
{
struct timer_gp_reg_map_t* const register_map =
(struct timer_gp_reg_map_t*)dev->cfg->base;
return GET_BIT(register_map->irq_status, alarm);
}
void timer_gp_interrupt_clear(const struct timer_gp_dev_t* dev,
const enum timer_gp_alarm_identifier_t alarm)
{
struct timer_gp_reg_map_t* const register_map =
(struct timer_gp_reg_map_t*)dev->cfg->base;
enum timer_gp_read_alarm_identifier_t read_alarm =
((alarm == TIMER_GP_ALARM_0) ?
(TIMER_GP_READ_ALARM_0) :
(TIMER_GP_READ_ALARM_1));
SET_BIT(register_map->irq_clear, alarm);
/* Clear bit is not self-clearing and some pulse width is required
* for successful interrupt clear, so we have to check whether the
* interrupt is cleared. */
while(timer_gp_interrupt_is_active(dev, read_alarm))
;
CLR_BIT(register_map->irq_clear, alarm);
}
void timer_gp_set_alarm_value(const struct timer_gp_dev_t* dev,
const enum timer_gp_alarm_identifier_t alarm,
const uint32_t value)
{
struct timer_gp_reg_map_t* const register_map =
(struct timer_gp_reg_map_t*)dev->cfg->base;
if (alarm == TIMER_GP_ALARM_0) {
register_map->alarm0 = value;
} else {
register_map->alarm1 = value;
}
}
uint32_t timer_gp_get_alarm_value(const struct timer_gp_dev_t* dev,
const enum timer_gp_alarm_identifier_t alarm)
{
struct timer_gp_reg_map_t* const register_map =
(struct timer_gp_reg_map_t*)dev->cfg->base;
if (alarm == TIMER_GP_ALARM_0) {
return register_map->alarm0;
} else {
return register_map->alarm1;
}
}

View File

@ -0,0 +1,203 @@
/*
* Copyright (c) 2018 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file timer_gp_drv.h
*
* \brief Generic driver for general purpose timer.
*
* \details
* The free running counter is a 32 bit size counter that counts
* up to 0xFFFFFFFF.
* At this maximum value it wraps around to 0x00000000 and continues
* incrementing.
* Software can reset the counter to default 1 by calling
* \ref timer_gp_counter_reset.
* The counter implements two compare interrupts. When the counter
* reaches compare value "alarm0" or "alarm1" value it can trigger a
* corresponding interrupt.
*/
#ifndef __TIMER_GP_DRV_H__
#define __TIMER_GP_DRV_H__
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TIMER_GP_MAX_VALUE UINT32_MAX /*!< max of 32-bit */
#define TIMER_GP_DEFAULT_RESET 1U
/*!< Counter's reset value will be set at HW level if reset bit is asserted */
/** GP timer device structure */
struct timer_gp_dev_cfg_t {
const uintptr_t base; /*!< Timer base address */
};
/** GP timer device data structure */
struct timer_gp_dev_data_t {
bool is_initialized;
uint32_t alarm0_init; /*!< Alarm0 value will be set by init */
uint32_t alarm1_init; /*!< Alarm1 value will be set by init */
};
/** GP timer device structure */
struct timer_gp_dev_t {
const struct timer_gp_dev_cfg_t* const cfg; /*!< Timer configuration */
struct timer_gp_dev_data_t* const data; /*!< Timer data */
};
/**
* \brief GP Timer alarm number identifiers
*
*/
enum timer_gp_alarm_identifier_t{
TIMER_GP_ALARM_0 = 0,
TIMER_GP_ALARM_1 = 1
};
/**
* \brief GP Timer read alarm number identifiers
*
*/
enum timer_gp_read_alarm_identifier_t{
TIMER_GP_READ_ALARM_0 = 0,
TIMER_GP_READ_ALARM_1 = 1,
TIMER_GP_READ_ALARM_COMBINED = 2
/*!< Combined is asserted if Alarm1 OR Alarm2 is asserted */
};
/**
* \brief Initializes timer to a known default state, which is:
* - interrupts disabled
* - alarm0 and alarm1 set to init value in \ref timer_gp_dev_data_t
* - timer reset to default reset value \ref TIMER_GP_DEFAULT_RESET
* Init should be called prior to any other process and
* it's the caller's responsibility to follow proper call order.
* More than one call results fall through.
*
* \param[in] dev Timer device struct \ref timer_gp_dev_t
*/
void timer_gp_init(const struct timer_gp_dev_t* dev);
/**
* \brief Resets the timer counter to 1.
*
* \param[in] dev Timer device struct \ref timer_gp_dev_t
*/
void timer_gp_counter_reset(const struct timer_gp_dev_t* dev);
/**
* \brief Read the 32bit free runnning counter's current value
*
* \param[in] dev Timer device struct \ref timer_gp_dev_t
*
* \return 32bit counter current value
*/
uint32_t timer_gp_get_counter(const struct timer_gp_dev_t* dev);
/**
* \brief Enable alarm interrupt of the given source
* Note: This function is not interrupt safe.
*
* \param[in] dev Timer device struct \ref timer_gp_dev_t
* \param[in] alarm Alarm source of the interrupt
* \ref timer_gp_alarm_identifier_t
*
*/
void timer_gp_interrupt_enable(const struct timer_gp_dev_t* dev,
const enum timer_gp_alarm_identifier_t alarm);
/**
* \brief Disable alarm interrupt of the given source
* Note: This function is not interrupt safe.
*
* \param[in] dev Timer device struct \ref timer_gp_dev_t
* \param[in] alarm Alarm source of the interrupt
* \ref timer_gp_alarm_identifier_t
*
*/
void timer_gp_interrupt_disable(const struct timer_gp_dev_t* dev,
const enum timer_gp_alarm_identifier_t alarm);
/**
* \brief Get alarm interrupt enabled status of the given source
*
* \param[in] dev Timer device struct \ref timer_gp_dev_t
* \param[in] alarm Alarm source of the interrupt
* \ref timer_gp_alarm_identifier_t
*
* \return true if enabled, false if not
*/
bool timer_gp_interrupt_is_enabled(const struct timer_gp_dev_t* dev,
const enum
timer_gp_alarm_identifier_t alarm);
/**
* \brief Get alarm interrupt pending status of the given source
*
* \param[in] dev Timer device struct \ref timer_gp_dev_t
* \param[in] alarm Alarm source of the interrupt
* \ref timer_gp_read_alarm_identifier_t
*
* \return true if active, false if not
*/
bool timer_gp_interrupt_is_active(const struct timer_gp_dev_t* dev,
const enum timer_gp_read_alarm_identifier_t alarm);
/**
* \brief Clear alarm interrupt of the given source
*
* \param[in] dev Timer device struct \ref timer_gp_dev_t
* \param[in] alarm Alarm source of the interrupt
* \ref timer_gp_alarm_identifier_t
*
*/
void timer_gp_interrupt_clear(const struct timer_gp_dev_t* dev,
const enum timer_gp_alarm_identifier_t alarm);
/**
* \brief Set alarm value of the given source
*
* \param[in] dev Timer device struct \ref timer_gp_dev_t
* \param[in] alarm Alarm source \ref timer_gp_alarm_identifier_t
* \param[in] value When the counter reaches this tick value
* corresponding interrupt status will be asserted.
*/
void timer_gp_set_alarm_value(const struct timer_gp_dev_t* dev,
const enum timer_gp_alarm_identifier_t alarm,
const uint32_t value);
/**
* \brief Get alarm value of the given source
*
* \param[in] dev Timer device struct \ref timer_gp_dev_t
* \param[in] alarm Alarm source \ref timer_gp_alarm_identifier_t
*
* \return value Counter value when the alarm is asserted.
*/
uint32_t timer_gp_get_alarm_value(const struct timer_gp_dev_t* dev,
const enum timer_gp_alarm_identifier_t alarm);
#ifdef __cplusplus
}
#endif
#endif /* __TIMER_GP_DRV_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,854 @@
/*
* Copyright (c) 2016-2018 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file uart_pl011_drv.h
* \brief Driver for ARM UART PL011.
*/
#ifndef __UART_PL011_DRV_H__
#define __UART_PL011_DRV_H__
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief ARM UART PL011 state types
*/
enum uart_pl011_state_t {
UART_PL011_UNINITIALIZED = 0x0u,
UART_PL011_INITIALIZED = 0x1u,
};
#define UART_PL011_UARTRSR_FE_ERR_OFF 0x0u
/*!< Receive Status Register Frame Error bit field offset */
#define UART_PL011_UARTRSR_PE_ERR_OFF 0x1u
/*!< Receive Status Register Parity Error bit field offset */
#define UART_PL011_UARTRSR_BE_ERR_OFF 0x2u
/*!< Receive Status Register Break Error bit field offset */
#define UART_PL011_UARTRSR_OE_ERR_OFF 0x3u
/*!< Receive Status Register Overrun Error bit field offset */
#define UART_PL011_RX_ERR_MASK ( \
0x1u<<UART_PL011_UARTRSR_FE_ERR_OFF \
| 0x1u<<UART_PL011_UARTRSR_PE_ERR_OFF \
| 0x1u<<UART_PL011_UARTRSR_BE_ERR_OFF \
| 0x1u<<UART_PL011_UARTRSR_OE_ERR_OFF)
/*!< Receive Status Register Error Mask */
#define UART_PL011_UARTFR_CTS_OFF 0x0u
/*!< Flag Register Clear to send bit field offset */
#define UART_PL011_UARTFR_DSR_OFF 0x1u
/*!< Flag Register Data set ready bit field offset */
#define UART_PL011_UARTFR_DCD_OFF 0x2u
/*!< Flag Register Data carrier detect bit field offset */
#define UART_PL011_UARTFR_BUSYBIT_OFF 0x3u
/*!< Flag Register Busy bit field offset */
#define UART_PL011_UARTFR_RX_FIFO_EMPTY_OFF 0x4u
/*!< Flag Register Receive fifo empty bit field offset */
#define UART_PL011_UARTFR_TX_FIFO_FULL_OFF 0x5u
/*!< Flag Register Transmit fifo full bit field offset */
#define UART_PL011_UARTFR_RX_FIFO_FULL_OFF 0x6u
/*!< Flag Register Receive fifo full bit field offset */
#define UART_PL011_UARTFR_TX_FIFO_EMPTY_OFF 0x7u
/*!< Flag Register Transmit fifo empty bit field offset */
#define UART_PL011_UARTFR_RI_OFF 0x8u
/*!< Flag Register Ring indicator bit field offset */
#define UART_PL011_UARTLCR_H_BRK_OFF 0x0u
/*!< Line Control Register Break bit field offset */
#define UART_PL011_UARTLCR_H_PEN_OFF 0x1u
/*!< Line Control Register Parity enable bit field offset */
#define UART_PL011_UARTLCR_H_EPS_OFF 0x2u
/*!< Line Control Register Even parity select bit field offset */
#define UART_PL011_UARTLCR_H_STP2_OFF 0x3u
/*!< Line Control Register 2 stop bit select bit field offset */
#define UART_PL011_UARTLCR_H_FEN_OFF 0x4u
/*!< Line Control Register Fifo enable bit field offset */
#define UART_PL011_UARTLCR_H_WLEN_OFF 0x5u
/*!< Line Control Register Word length bit field offset */
#define UART_PL011_UARTLCR_H_SPS_OFF 0x7u
/*!< Line Control Register Stick parity select bit field offset */
/**
* \brief Allowed word length options UART PL011
*/
enum uart_pl011_wlen_t {
UART_PL011_WLEN_5 = (0x0u<<UART_PL011_UARTLCR_H_WLEN_OFF),
UART_PL011_WLEN_6 = (0x1u<<UART_PL011_UARTLCR_H_WLEN_OFF),
UART_PL011_WLEN_7 = (0x2u<<UART_PL011_UARTLCR_H_WLEN_OFF),
UART_PL011_WLEN_8 = (0x3u<<UART_PL011_UARTLCR_H_WLEN_OFF),
};
/**
* \brief Allowed parity options UART PL011
*/
enum uart_pl011_parity_t {
UART_PL011_PARITY_DISABLED = (0x0u<<UART_PL011_UARTLCR_H_PEN_OFF),
UART_PL011_PARITY_ODD = (0x1u<<UART_PL011_UARTLCR_H_PEN_OFF
| 0x0u<<UART_PL011_UARTLCR_H_EPS_OFF
| 0x0u<<UART_PL011_UARTLCR_H_SPS_OFF),
UART_PL011_PARITY_EVEN = (0x1u<<UART_PL011_UARTLCR_H_PEN_OFF
| 0x1u<<UART_PL011_UARTLCR_H_EPS_OFF
| 0x0u<<UART_PL011_UARTLCR_H_SPS_OFF),
UART_PL011_PARITY_STICKY_ONE= (0x1u<<UART_PL011_UARTLCR_H_PEN_OFF
| 0x0u<<UART_PL011_UARTLCR_H_EPS_OFF
| 0x1u<<UART_PL011_UARTLCR_H_SPS_OFF),
UART_PL011_PARITY_STICKY_ZERO= (0x1u<<UART_PL011_UARTLCR_H_PEN_OFF
| 0x1u<<UART_PL011_UARTLCR_H_EPS_OFF
| 0x1u<<UART_PL011_UARTLCR_H_SPS_OFF),
};
/**
* \brief Allowed stop bits options UART PL011
*/
enum uart_pl011_stopbit_t {
UART_PL011_STOPBIT_1 = (0x0u<<UART_PL011_UARTLCR_H_STP2_OFF),
UART_PL011_STOPBIT_2 = (0x1u<<UART_PL011_UARTLCR_H_STP2_OFF),
};
#define UART_PL011_UARTCR_UARTEN_OFF 0x0u
/*!< Control Register Uart enable bit field offset */
#define UART_PL011_UARTCR_SIREN_OFF 0x1u
/*!< Control Register Sir enable bit field offset */
#define UART_PL011_UARTCR_SIRLP_OFF 0x2u
/*!< Control Register Sir low power bit field offset */
#define UART_PL011_UARTCR_LBE_OFF 0x7u
/*!< Control Register Loop back enable bit field offset */
#define UART_PL011_UARTCR_TXE_OFF 0x8u
/*!< Control Register Transmit enable bit field offset */
#define UART_PL011_UARTCR_RXE_OFF 0x9u
/*!< Control Register Receive enable bit field offset */
#define UART_PL011_UARTCR_DTR_OFF 0xAu
/*!< Control Register Data transmit ready bit field offset */
#define UART_PL011_UARTCR_RTS_OFF 0xBu
/*!< Control Register Request to send bit field offset */
#define UART_PL011_UARTCR_OUT1_OFF 0xCu
/*!< Control Register Out1 bit field offset */
#define UART_PL011_UARTCR_OUT2_OFF 0xDu
/*!< Control Register Out2 bit field offset */
#define UART_PL011_UARTCR_RTSE_OFF 0xEu
/*!< Control Register RTS hardware flow control enable bit field offset */
#define UART_PL011_UARTCR_CTSE_OFF 0xFu
/*!< Control Register CTS hardware flow control enable bit field offset */
#define UART_PL011_UARTIFLS_TX_OFF 0x0u
/*!< Interrupt FIFO Level Select Register Transmit bit field offset */
#define UART_PL011_UARTIFLS_RX_OFF 0x3u
/*!< Interrupt FIFO Level Select Register Receive bit field offset */
/**
* \brief UART Receive fifo levels
*/
enum uart_pl011_rx_fifo_lvl_t {
UART_PL011_RX_FIFO_LVL_1_8 = (0x0u<<UART_PL011_UARTIFLS_RX_OFF),
UART_PL011_RX_FIFO_LVL_1_4 = (0x1u<<UART_PL011_UARTIFLS_RX_OFF),
UART_PL011_RX_FIFO_LVL_1_2 = (0x2u<<UART_PL011_UARTIFLS_RX_OFF),
UART_PL011_RX_FIFO_LVL_3_4 = (0x3u<<UART_PL011_UARTIFLS_RX_OFF),
UART_PL011_RX_FIFO_LVL_7_8 = (0x4u<<UART_PL011_UARTIFLS_RX_OFF),
};
/**
* \brief UART Transmit fifo levels
*/
enum uart_pl011_tx_fifo_lvl_t {
UART_PL011_TX_FIFO_LVL_1_8 = (0x0u<<UART_PL011_UARTIFLS_TX_OFF),
UART_PL011_TX_FIFO_LVL_1_4 = (0x1u<<UART_PL011_UARTIFLS_TX_OFF),
UART_PL011_TX_FIFO_LVL_1_2 = (0x2u<<UART_PL011_UARTIFLS_TX_OFF),
UART_PL011_TX_FIFO_LVL_3_4 = (0x3u<<UART_PL011_UARTIFLS_TX_OFF),
UART_PL011_TX_FIFO_LVL_7_8 = (0x4u<<UART_PL011_UARTIFLS_TX_OFF),
};
#define UART_PL011_UARTDMACR_RXEN_OFF 0x0u
/*!< DMA Control Register Receive DMA enable bit field offset */
#define UART_PL011_UARTDMACR_TXEN_OFF 0x1u
/*!< DMA Control Register Transmit DMA enable bit field offset */
#define UART_PL011_UARTDMACR_ON_ERR_OFF 0x2u
/*!< DMA Control Register DMA on error bit field offset */
/**
* \brief Transmit DMA Enable
*/
enum uart_pl011_tx_dma_t {
UART_PL011_TX_DMA_DISABLE = (0x0u<<UART_PL011_UARTDMACR_TXEN_OFF),
UART_PL011_TX_DMA_ENABLE = (0x1u<<UART_PL011_UARTDMACR_TXEN_OFF),
};
/**
* \brief Receive DMA Enable
*/
enum uart_pl011_rx_dma_t {
UART_PL011_RX_DMA_DISABLE = (0x0u<<UART_PL011_UARTDMACR_RXEN_OFF),
UART_PL011_RX_DMA_ENABLE = (0x1u<<UART_PL011_UARTDMACR_RXEN_OFF),
UART_PL011_RX_DMA_ON_ERR_EN= (0x1u<<UART_PL011_UARTDMACR_RXEN_OFF
| 0x1u<<UART_PL011_UARTDMACR_ON_ERR_OFF),
};
#define UART_PL011_INTR_RI_OFF 0x0u
/*!< Ring indicator interrupt bit field offset */
#define UART_PL011_INTR_CTS_OFF 0x1u
/*!< Clear to send interrupt bit field offset */
#define UART_PL011_INTR_DCD_OFF 0x2u
/*!< Data carrier detect interrupt bit field offset */
#define UART_PL011_INTR_DSR_OFF 0x3u
/*!< Data set ready interrupt bit field offset */
#define UART_PL011_INTR_RX_OFF 0x4u
/*!< Receive interrupt bit field offset */
#define UART_PL011_INTR_TX_OFF 0x5u
/*!< Transmit interrupt bit field offset */
#define UART_PL011_INTR_RT_OFF 0x6u
/*!< Receive timeout interrupt bit field offset */
#define UART_PL011_INTR_FE_OFF 0x7u
/*!< Frame error interrupt bit field offset */
#define UART_PL011_INTR_PE_OFF 0x8u
/*!< Parity error interrupt bit field offset */
#define UART_PL011_INTR_BE_OFF 0x9u
/*!< Break error interrupt bit field offset */
#define UART_PL011_INTR_OE_OFF 0xAu
/*!< Overrun error interrupt bit field offset */
/**
* \brief ARM UART PL011 Interrupt data structure
*/
enum uart_pl011_intr_t {
UART_PL011_RI_INTR_MASK = (0x1u<<UART_PL011_INTR_RI_OFF),
UART_PL011_CTS_INTR_MASK = (0x1u<<UART_PL011_INTR_CTS_OFF),
UART_PL011_DCD_INTR_MASK = (0x1u<<UART_PL011_INTR_DCD_OFF),
UART_PL011_DSR_INTR_MASK = (0x1u<<UART_PL011_INTR_DSR_OFF),
UART_PL011_RX_INTR_MASK = (0x1u<<UART_PL011_INTR_RX_OFF),
UART_PL011_TX_INTR_MASK = (0x1u<<UART_PL011_INTR_TX_OFF),
UART_PL011_RT_INTR_MASK = (0x1u<<UART_PL011_INTR_RT_OFF),
UART_PL011_FE_INTR_MASK = (0x1u<<UART_PL011_INTR_FE_OFF),
UART_PL011_PE_INTR_MASK = (0x1u<<UART_PL011_INTR_PE_OFF),
UART_PL011_BE_INTR_MASK = (0x1u<<UART_PL011_INTR_BE_OFF),
UART_PL011_OE_INTR_MASK = (0x1u<<UART_PL011_INTR_OE_OFF),
};
/**
* \brief ARM UART PL011 error enumeration types
*/
enum uart_pl011_error_t {
UART_PL011_ERR_NONE = (0x0u),
UART_PL011_ERR_RX_FRAME = (0x1u<<UART_PL011_UARTRSR_FE_ERR_OFF),
UART_PL011_ERR_RX_PARITY = (0x1u<<UART_PL011_UARTRSR_PE_ERR_OFF),
UART_PL011_ERR_RX_BREAK = (0x1u<<UART_PL011_UARTRSR_BE_ERR_OFF),
UART_PL011_ERR_RX_OVERFLOW = (0x1u<<UART_PL011_UARTRSR_OE_ERR_OFF),
UART_PL011_ERR_INVALID_ARG = (UART_PL011_RX_ERR_MASK + 1),
UART_PL011_ERR_NOT_READY,
UART_PL011_ERR_INVALID_BAUD,
UART_PL011_ERR_NOT_INIT,
};
/**
* \brief ARM UART PL011 device configuration structure
*/
struct uart_pl011_dev_cfg_t {
const uint32_t base; /*!< UART PL011 base address */
const uint32_t def_baudrate; /*!< Default baudrate */
const enum uart_pl011_wlen_t def_wlen; /*!< Default word length */
const enum uart_pl011_parity_t def_parity; /*!< Default parity */
const enum uart_pl011_stopbit_t def_stopbit; /*!< Default stop bits */
};
/**
* \brief ARM UART PL011 device data structure
*/
struct uart_pl011_dev_data_t {
enum uart_pl011_state_t state; /*!< UART State */
uint32_t uart_clk; /*!< UART clock */
uint32_t baudrate; /*!< Baudrate */
};
/**
* \brief ARM UART PL011 device structure
*/
struct uart_pl011_dev_t {
const struct uart_pl011_dev_cfg_t* const cfg;
/*!< UART PL011 configuration */
struct uart_pl011_dev_data_t* const data;
/*!< UART PL011 data */
};
/**
* \brief Initializes UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
* \param[in] uart_clk UART clock used by the device.
*
* It uses the default baudrate to configure UART.
*
* \return Returns error code as specified in \ref uart_pl011_error_t
*
* \note This API should be called before calling any of the below UART APIs.
* \note This function doesn't check if dev is NULL.
*/
enum uart_pl011_error_t uart_pl011_init(struct uart_pl011_dev_t* dev,
uint32_t uart_clk);
/**
* \brief Uninitializes UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_uninit(struct uart_pl011_dev_t* dev);
/**
* \brief Returns the UART PL011 operational state.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
* \return Returns the UART operational state
*
* \note This function doesn't check if dev is NULL.
*/
enum uart_pl011_state_t uart_pl011_get_state(struct uart_pl011_dev_t* dev);
/**
* \brief Sets the UART baudrate.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
* \param[in] baudrate New baudrate.
*
* \return Returns error code as specified in \ref uart_pl011_error_t
*
* \note This function doesn't check if dev is NULL.
*/
enum uart_pl011_error_t uart_pl011_set_baudrate(
struct uart_pl011_dev_t* dev, uint32_t baudrate);
/**
* \brief Gets the UART baudrate.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \return Returns the UART baudrate.
*
* \note The UART should be in valid state before calling this API
* \ref uart_pl011_get_state should return UART_PL011_INITIALIZED
* \note This function doesn't check if dev is NULL.
*/
uint32_t uart_pl011_get_baudrate(struct uart_pl011_dev_t* dev);
/**
* \brief Enables UART interrupts
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
* \param[in] mask Bit mask for enabling/disabling interrupts
* \ref uart_pl011_intr_t
*
* \note User is responsible to configure the interrupt vector and
* the interrupt controller.
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_enable_intr(struct uart_pl011_dev_t* dev,
enum uart_pl011_intr_t mask);
/**
* \brief Disables UART interrupts
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
* \param[in] mask Bit mask for enabling/disabling interrupts
* \ref uart_pl011_intr_t
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_disable_intr(struct uart_pl011_dev_t* dev,
enum uart_pl011_intr_t mask);
/**
* \brief Clears UART Interrupt
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
* \param[in] mask Bit mask for clearing interrupts \ref uart_pl011_intr_t
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_clear_intr(struct uart_pl011_dev_t* dev,
enum uart_pl011_intr_t mask);
/**
* \brief Returns the UART Masked interrupt status
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \return Masked interrupt status \ref uart_pl011_intr_t
*
* \note This function doesn't check if dev is NULL.
*/
enum uart_pl011_intr_t uart_pl011_get_masked_intr_status(
struct uart_pl011_dev_t* dev);
/**
* \brief Returns the UART Raw interrupt status
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \return Raw interrupt status \ref uart_pl011_intr_t
*
* \note This function doesn't check if dev is NULL.
*/
enum uart_pl011_intr_t uart_pl011_get_raw_intr_status(
struct uart_pl011_dev_t* dev);
/**
* \brief Sets receive fifo levels
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
* \param[in] rx_lvl Receive fifo levels \ref uart_pl011_rx_fifo_lvl_t
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_set_rx_fifo_lvl(struct uart_pl011_dev_t* dev,
enum uart_pl011_rx_fifo_lvl_t rx_lvl);
/**
* \brief Sets transmit fifo levels
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
* \param[in] tx_lvl Transmit fifo levels \ref uart_pl011_tx_fifo_lvl_t
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_set_tx_fifo_lvl(struct uart_pl011_dev_t* dev,
enum uart_pl011_tx_fifo_lvl_t tx_lvl);
/**
* \brief Enables/Disables transmit UART DMA
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
* \param[in] enable To enable/disable the UART transmit DMA
* \ref uart_pl011_tx_dma_t
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_set_tx_dma(struct uart_pl011_dev_t* dev,
enum uart_pl011_tx_dma_t enable);
/**
* \brief Enables/Disables receive UART DMA
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
* \param[in] enable To enable/disable the UART receive DMA
* \ref uart_pl011_rx_dma_t
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_set_rx_dma(struct uart_pl011_dev_t* dev,
enum uart_pl011_rx_dma_t enable);
/**
* \brief Check if the UART dev is readable
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \return Returns bool, true if UART is readable, false otherwise
*
* \note This function doesn't check if dev is NULL.
*/
bool uart_pl011_is_readable(struct uart_pl011_dev_t* dev);
/**
* \brief Reads one byte from UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
* \param[out] byte Pointer to byte that is populated with the data to be read
*
* \return Error status (if any) as specified in
* \ref uart_pl011_error_t
*
* \note This API should only be called when the device is readable
* \ref uart_pl011_is_readable
* \note For better performance, this function doesn't check if dev and byte
* pointer are NULL, and if the driver is initialized.
*/
enum uart_pl011_error_t uart_pl011_read(struct uart_pl011_dev_t* dev,
uint8_t* byte);
/**
* \brief Check if the UART dev is writable
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \return Returns bool, true if UART is writable, false otherwise
*
* \note This function doesn't check if dev is NULL.
*/
bool uart_pl011_is_writable(struct uart_pl011_dev_t* dev);
/**
* \brief Writes a byte to UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
* \param[in] byte One byte to write.
*
* \note This API should only be called when the device is writable
* \ref uart_pl011_is_writable
* \note For better performance, this function doesn't check if dev is NULL and
* if the driver is initialized to have better performance.
*/
void uart_pl011_write(struct uart_pl011_dev_t* dev, uint8_t byte);
/**
* \brief Sets the UART format.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
* \param[in] word_len UART word length \ref uart_pl011_wlen_t
* \param[in] parity UART parity \ref uart_pl011_parity_t
* \param[in] stop_bits UART stop bits \ref uart_pl011_stopbit_t
*
* \return Returns error code as specified in \ref uart_pl011_error_t
*
* \note This function doesn't check if dev is NULL.
*/
enum uart_pl011_error_t uart_pl011_set_format(struct uart_pl011_dev_t* dev,
enum uart_pl011_wlen_t word_len,
enum uart_pl011_parity_t parity,
enum uart_pl011_stopbit_t stop_bits);
/**
* \brief Enables the UART fifo.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_enable_fifo(struct uart_pl011_dev_t* dev);
/**
* \brief Disables the UART fifo.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_disable_fifo(struct uart_pl011_dev_t* dev);
/**
* \brief Enables break transmission from UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \note For better performance, this function doesn't check if dev is NULL and
* if the driver is initialized to have better performance.
*/
void uart_pl011_enable_break(struct uart_pl011_dev_t* dev);
/**
* \brief Disables break transmission from UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \note For better performance, this function doesn't check if dev is NULL and
* if the driver is initialized to have better performance.
*/
void uart_pl011_disable_break(struct uart_pl011_dev_t* dev);
/**
* \brief Enables CTS flow control in UART PL011
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_enable_cts_flowcontrol(struct uart_pl011_dev_t* dev);
/**
* \brief Disables CTS flow control in UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_disable_cts_flowcontrol(struct uart_pl011_dev_t* dev);
/**
* \brief Enables RTS flow control in UART PL011
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_enable_rts_flowcontrol(struct uart_pl011_dev_t* dev);
/**
* \brief Disables RTS flow control in UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_disable_rts_flowcontrol(struct uart_pl011_dev_t* dev);
/**
* \brief Enables Data carrier detect in UART PL011
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
* \note For DTE nUARTOut1 can be used as Data carrier detect (DCD).
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_enable_dcd(struct uart_pl011_dev_t* dev);
/**
* \brief Disables Data carrier detect in UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
* \note For DTE nUARTOut1 can be used as Data carrier detect (DCD).
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_disable_dcd(struct uart_pl011_dev_t* dev);
/**
* \brief Enables RTS signal for UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \note For better performance, this function doesn't check if dev is NULL and
* if the driver is initialized to have better performance.
*/
void uart_pl011_set_rts(struct uart_pl011_dev_t* dev);
/**
* \brief Disables RTS signal for UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \note For better performance, this function doesn't check if dev is NULL and
* if the driver is initialized to have better performance.
*/
void uart_pl011_clear_rts(struct uart_pl011_dev_t* dev);
/**
* \brief Enables DTR signal for UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \note For better performance, this function doesn't check if dev is NULL and
* if the driver is initialized to have better performance.
*/
void uart_pl011_set_dtr(struct uart_pl011_dev_t* dev);
/**
* \brief Disables DTR signal for UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \note For better performance, this function doesn't check if dev is NULL and
* if the driver is initialized to have better performance.
*/
void uart_pl011_clear_dtr(struct uart_pl011_dev_t* dev);
/**
* \brief Enables reception in UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_enable_receive(struct uart_pl011_dev_t* dev);
/**
* \brief Disables reception in UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_disable_receive(struct uart_pl011_dev_t* dev);
/**
* \brief Enables transmission in UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_enable_transmit(struct uart_pl011_dev_t* dev);
/**
* \brief Disables transmission in UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_disable_transmit(struct uart_pl011_dev_t* dev);
/**
* \brief Enables loopback in UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \note For better performance, this function doesn't check if dev is NULL and
* if the driver is initialized to have better performance.
*/
void uart_pl011_set_loopback(struct uart_pl011_dev_t* dev);
/**
* \brief Disables loopback in UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \note For better performance, this function doesn't check if dev is NULL and
* if the driver is initialized to have better performance.
*/
void uart_pl011_clear_loopback(struct uart_pl011_dev_t* dev);
/**
* \brief Enables IrDA Sir low power mode in UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \note For better performance, this function doesn't check if dev is NULL and
* if the driver is initialized to have better performance.
*/
void uart_pl011_enable_sirlp(struct uart_pl011_dev_t* dev);
/**
* \brief Disables IrDA Sir in UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \note For better performance, this function doesn't check if dev is NULL and
* if the driver is initialized to have better performance.
*/
void uart_pl011_disable_sirlp(struct uart_pl011_dev_t* dev);
/**
* \brief Enables IrDA Sir in UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \note For better performance, this function doesn't check if dev is NULL and
* if the driver is initialized to have better performance.
*/
void uart_pl011_enable_sir(struct uart_pl011_dev_t* dev);
/**
* \brief Disables IrDA Sir in UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
*
* \note For better performance, this function doesn't check if dev is NULL and
* if the driver is initialized to have better performance.
*/
void uart_pl011_disable_sir(struct uart_pl011_dev_t* dev);
/**
* \brief Enables in UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_enable(struct uart_pl011_dev_t* dev);
/**
* \brief Disables in UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
*
* \note This function doesn't check if dev is NULL.
*/
void uart_pl011_disable(struct uart_pl011_dev_t* dev);
/**
* \brief Gets the Clear to send status in UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
* \return Returns bool, true when the modem status input is 0, false otherwise
*
* \note This bit is the complement of the UART clear to send (nUARTCTS) modem
* status input.
* \note This function doesn't check if dev is NULL.
*/
bool uart_pl011_get_cts_status(struct uart_pl011_dev_t* dev);
/**
* \brief Gets the Data set ready status in UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
* \return Returns bool, true when the modem status input is 0, false otherwise
*
* \note This bit is the complement of the UART UART data set ready (nUARTDSR)
* modem status input.
* \note This function doesn't check if dev is NULL.
*/
bool uart_pl011_get_dsr_status(struct uart_pl011_dev_t* dev);
/**
* \brief Gets the Data carrier detect status in UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
* \return Returns bool, true when the modem status input is 0, false otherwise
*
* \note This bit is the complement of the UART data carrier detect (nUARTDCD)
* modem status input.
* \note This function doesn't check if dev is NULL.
*/
bool uart_pl011_get_dcd_status(struct uart_pl011_dev_t* dev);
/**
* \brief Gets the Ring indicator status in UART PL011.
*
* \param[in] dev UART PL011 device struct \ref uart_pl011_dev_t
*
* \return Returns bool, true when the modem status input is 0, false otherwise
*
* \note This bit is the complement of the UART ring indicator (nUARTRI) modem
* status input.
* \note This function doesn't check if dev is NULL.
*/
bool uart_pl011_get_ri_status(struct uart_pl011_dev_t* dev);
/**
* \brief Sets the Low power Divisor in UART dev.
*
* \param[in] dev UART device struct \ref uart_pl011_dev_t
* \param[in] value Low power divisor value to be set
*
* \return Returns error code as specified in \ref uart_pl011_error_t
*
* \note For better performance, this function doesn't check if dev is NULL
*/
enum uart_pl011_error_t uart_pl011_set_sirlp_divisor(
struct uart_pl011_dev_t* dev, uint32_t value);
#ifdef __cplusplus
}
#endif
#endif /* __UART_PL011_DRV_H__ */

View File

@ -0,0 +1,179 @@
/*
* Copyright (c) 2017-2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This file is derivative of CMSIS V5.01 Device\_Template_Vendor\Vendor\Device\Include\Device.h
*/
#ifndef __PLATFORM_BASE_ADDRESS_H__
#define __PLATFORM_BASE_ADDRESS_H__
#ifdef __cplusplus
extern "C" {
#endif
/* =========================================================================================================================== */
/* ================ Device Specific Peripheral Address Map ================ */
/* =========================================================================================================================== */
/** @addtogroup Device_Peripheral_peripheralAddr
* @{
*/
/* Non-Secure Peripheral and SRAM base address */
#define MUSCA_S1_CODE_SRAM_NS_BASE (0x00000000UL) /*!< (Non-Secure Code SRAM ) Base Address */
#define MUSCA_S1_QSPI_FLASH_NS_BASE (0x00200000UL) /*!< (Non-Secure QSPI FLASH ) Base Address */
#define MUSCA_S1_MRAM_NS_BASE (0x0A000000UL) /*!< (Non-Secure MRAM ) Base Address */
#define MUSCA_S1_OTP_NS_BASE (0x0E000000UL) /*!< (Non-Secure OTP ) Base Address */
#define MUSCA_S1_SRAM_NS_BASE (0x20000000UL) /*!< (Non-Secure Internal SRAM ) Base Address */
#define MUSCA_S1_BASE_ELEMENT_NS_BASE (0x40000000UL) /*!< (Non-Secure Base Peripherals ) Base Address */
#define MUSCA_S1_CMSDK_TIMER0_NS_BASE (0x40000000UL) /*!< (Non-Secure CMSDK Timer0 ) Base Address */
#define MUSCA_S1_CMSDK_TIMER1_NS_BASE (0x40001000UL) /*!< (Non-Secure CMSDK Timer1 ) Base Address */
#define MUSCA_S1_CMSDK_DUALTIMER_NS_BASE (0x40002000UL) /*!< (Non-Secure CMSDK Dual Timer ) Base Address */
#define MUSCA_S1_MHU0_NS_BASE (0x40003000UL) /*!< (Non-Secure MHU0 ) Base Address */
#define MUSCA_S1_MHU1_NS_BASE (0x40004000UL) /*!< (Non-Secure MHU1 ) Base Address */
#define MUSCA_S1_CPU_ELEMENT_NS_BASE (0x40010000UL) /*!< (Non-Secure CPU Peripherals ) Base Address */
#define MUSCA_S1_SYSTEM_INFO_NS_BASE (0x40020000UL) /*!< (Non-Secure System Info ) Base Address */
#define MUSCA_S1_CMSDK_S32KTIMER_NS_BASE (0x4002F000UL) /*!< (Non-Secure CMSDK S32K Timer ) Base Address */
#define MUSCA_S1_NSPCTRL_NS_BASE (0x40080000UL) /*!< (Non-Secure Privilege Ctrl Blk) Base Address */
#define MUSCA_S1_CMSDK_WATCHDOG_NS_BASE (0x40081000UL) /*!< (Non-Secure CMSDK Watchdog ) Base Address */
#define MUSCA_S1_UART0_NS_BASE (0x40101000UL) /*!< (Non-Secure UART0 ) Base Address */
#define MUSCA_S1_UART1_NS_BASE (0x40102000UL) /*!< (Non-Secure UART1 ) Base Address */
#define MUSCA_S1_SPI0_NS_BASE (0x40103000UL) /*!< (Non-Secure SPI0 ) Base Address */
#define MUSCA_S1_I2C0_NS_BASE (0x40104000UL) /*!< (Non-Secure I2C0 ) Base Address */
#define MUSCA_S1_I2C1_NS_BASE (0x40105000UL) /*!< (Non-Secure I2C1 ) Base Address */
#define MUSCA_S1_I2S_NS_BASE (0x40106000UL) /*!< (Non-Secure I2S ) Base Address */
#define MUSCA_S1_PWM0_NS_BASE (0x40107000UL) /*!< (Non-Secure PWM0 ) Base Address */
#define MUSCA_S1_RTC_NS_BASE (0x40108000UL) /*!< (Non-Secure RTC ) Base Address */
#define MUSCA_S1_PVT_NS_BASE (0x40109000UL) /*!< (Non-Secure PVT sensors ) Base Address */
#define MUSCA_S1_QSPI_REG_NS_BASE (0x4010A000UL) /*!< (Non-Secure QSPI registers ) Base Address */
#define MUSCA_S1_TIMER_NS_BASE (0x4010B000UL) /*!< (Non-Secure Timer ) Base Address */
#define MUSCA_S1_SCC_NS_BASE (0x4010C000UL) /*!< (Non-Secure SCC ) Base Address */
#define MUSCA_S1_PWM1_NS_BASE (0x4010E000UL) /*!< (Non-Secure PWM1 ) Base Address */
#define MUSCA_S1_PWM2_NS_BASE (0x4010F000UL) /*!< (Non-Secure PWM2 ) Base Address */
#define MUSCA_S1_GPIO_NS_BASE (0x40110000UL) /*!< (Non-Secure GPIO ) Base Address */
#define MUSCA_S1_QSPI_MPC_NS_BASE (0x40120000UL) /*!< (Non-Secure QSPI MPC ) Base Address */
#define MUSCA_S1_CODE_SRAM_MPC_NS_BASE (0x40130000UL) /*!< (Non-Secure Code SRAM MPC ) Base Address */
#define MUSCA_S1_MRAM_MPC_NS_BASE (0x40140000UL) /*!< (Non-Secure MRAM MPC ) Base Address */
#define MUSCA_S1_DEFAULT_SLAVE_NS_BASE (0x60000000UL) /*!< (Non-Secure Unused AHB ) Base Address */
/* Secure Peripheral and SRAM base address */
#define MUSCA_S1_CODE_SRAM_S_BASE (0x10000000UL) /*!< (Secure Code SRAM ) Base Address */
#define MUSCA_S1_QSPI_FLASH_S_BASE (0x10200000UL) /*!< (Secure QSPI FLASH ) Base Address */
#define MUSCA_S1_MRAM_S_BASE (0x1A000000UL) /*!< (Secure MRAM ) Base Address */
#define MUSCA_S1_OTP_S_BASE (0x1E000000UL) /*!< (Secure OTP ) Base Address */
#define MUSCA_S1_SRAM_S_BASE (0x30000000UL) /*!< (Secure Internal SRAM ) Base Address */
#define MUSCA_S1_BASE_ELEMENT_S_BASE (0x50000000UL) /*!< (Secure Base Peripherals ) Base Address */
#define MUSCA_S1_MHU0_S_BASE (0x50003000UL) /*!< (Secure MHU0 ) Base Address */
#define MUSCA_S1_MHU1_S_BASE (0x50004000UL) /*!< (Secure MHU1 ) Base Address */
#define MUSCA_S1_CPU_ELEMENT_S_BASE (0x50010000UL) /*!< (Secure CPU Peripherals ) Base Address */
#define MUSCA_S1_SYSTEM_INFO_S_BASE (0x50020000UL) /*!< (Secure System Info ) Base Address */
#define MUSCA_S1_SYSTEM_CTRL_S_BASE (0x50021000UL) /*!< (Secure System Control ) Base Address */
#define MUSCA_S1_CMSDK_S32KTIMER_S_BASE (0x5002F000UL) /*!< (Secure CMSDK S32K Timer ) Base Address */
#define MUSCA_S1_CMSDK_TIMER0_S_BASE (0x50000000UL) /*!< (Secure CMSDK Timer0 ) Base Address */
#define MUSCA_S1_CMSDK_TIMER1_S_BASE (0x50001000UL) /*!< (Secure CMSDK Timer1 ) Base Address */
#define MUSCA_S1_CMSDK_DUALTIMER_S_BASE (0x50002000UL) /*!< (Secure CMSDK Dual Timer ) Base Address */
#define MUSCA_S1_SPCTRL_S_BASE (0x50080000UL) /*!< (Secure Privilege Ctrl Blk) Base Address */
#define MUSCA_S1_CMSDK_WATCHDOG_S_BASE (0x50081000UL) /*!< (Secure CMSDK Watchdog ) Base Address */
#define MUSCA_S1_MPC_SRAM0_S_BASE (0x50083000UL) /*!< (Secure MPC SRAM Bank 0 ) Base Address */
#define MUSCA_S1_MPC_SRAM1_S_BASE (0x50084000UL) /*!< (Secure MPC SRAM Bank 1 ) Base Address */
#define MUSCA_S1_MPC_SRAM2_S_BASE (0x50085000UL) /*!< (Secure MPC SRAM Bank 2 ) Base Address */
#define MUSCA_S1_MPC_SRAM3_S_BASE (0x50086000UL) /*!< (Secure MPC SRAM Bank 3 ) Base Address */
#define MUSCA_S1_UART0_S_BASE (0x50101000UL) /*!< (Secure UART0 ) Base Address */
#define MUSCA_S1_UART1_S_BASE (0x50102000UL) /*!< (Secure UART1 ) Base Address */
#define MUSCA_S1_SPI0_S_BASE (0x50103000UL) /*!< (Secure SPI0 ) Base Address */
#define MUSCA_S1_I2C0_S_BASE (0x50104000UL) /*!< (Secure I2C0 ) Base Address */
#define MUSCA_S1_I2C1_S_BASE (0x50105000UL) /*!< (Secure I2C1 ) Base Address */
#define MUSCA_S1_I2S_S_BASE (0x50106000UL) /*!< (Secure I2S ) Base Address */
#define MUSCA_S1_PWM0_S_BASE (0x50107000UL) /*!< (Secure PWM0 ) Base Address */
#define MUSCA_S1_RTC_S_BASE (0x50108000UL) /*!< (Secure RTC ) Base Address */
#define MUSCA_S1_PVT_S_BASE (0x50109000UL) /*!< (Secure PVT sensors ) Base Address */
#define MUSCA_S1_QSPI_REG_S_BASE (0x5010A000UL) /*!< (Secure QSPI registers ) Base Address */
#define MUSCA_S1_TIMER_S_BASE (0x5010B000UL) /*!< (Secure Timer ) Base Address */
#define MUSCA_S1_SCC_S_BASE (0x5010C000UL) /*!< (Secure SCC ) Base Address */
#define MUSCA_S1_PWM1_S_BASE (0x5010E000UL) /*!< (Secure PWM1 ) Base Address */
#define MUSCA_S1_PWM2_S_BASE (0x5010F000UL) /*!< (Secure PWM2 ) Base Address */
#define MUSCA_S1_GPIO_S_BASE (0x50110000UL) /*!< (Secure GPIO ) Base Address */
#define MUSCA_S1_QSPI_MPC_S_BASE (0x50120000UL) /*!< (Secure QSPI MPC ) Base Address */
#define MUSCA_S1_CODE_SRAM_MPC_S_BASE (0x50130000UL) /*!< (Secure Code SRAM MPC ) Base Address */
#define MUSCA_S1_MRAM_MPC_S_BASE (0x50140000UL) /*!< (Secure MRAM MPC ) Base Address */
#define MUSCA_S1_DEFAULT_SLAVE_S_BASE (0x70000000UL) /*!< (Secure Unused AHB ) Base Address */
/* SRAM MPC ranges and limits */
/* Internal memory */
#define MPC_ISRAM0_RANGE_BASE_NS 0x20000000
#define MPC_ISRAM0_RANGE_LIMIT_NS 0x2001FFFF
#define MPC_ISRAM0_RANGE_OFFSET_NS 0x00000000
#define MPC_ISRAM0_RANGE_BASE_S 0x30000000
#define MPC_ISRAM0_RANGE_LIMIT_S 0x3001FFFF
#define MPC_ISRAM0_RANGE_OFFSET_S 0x00000000
#define MPC_ISRAM1_RANGE_BASE_NS 0x20020000
#define MPC_ISRAM1_RANGE_LIMIT_NS 0x2003FFFF
#define MPC_ISRAM1_RANGE_OFFSET_NS 0x00000000
#define MPC_ISRAM1_RANGE_BASE_S 0x30020000
#define MPC_ISRAM1_RANGE_LIMIT_S 0x3003FFFF
#define MPC_ISRAM1_RANGE_OFFSET_S 0x00000000
#define MPC_ISRAM2_RANGE_BASE_NS 0x20040000
#define MPC_ISRAM2_RANGE_LIMIT_NS 0x2005FFFF
#define MPC_ISRAM2_RANGE_OFFSET_NS 0x00000000
#define MPC_ISRAM2_RANGE_BASE_S 0x30040000
#define MPC_ISRAM2_RANGE_LIMIT_S 0x3005FFFF
#define MPC_ISRAM2_RANGE_OFFSET_S 0x00000000
#define MPC_ISRAM3_RANGE_BASE_NS 0x20060000
#define MPC_ISRAM3_RANGE_LIMIT_NS 0x2007FFFF
#define MPC_ISRAM3_RANGE_OFFSET_NS 0x00000000
#define MPC_ISRAM3_RANGE_BASE_S 0x30060000
#define MPC_ISRAM3_RANGE_LIMIT_S 0x3007FFFF
#define MPC_ISRAM3_RANGE_OFFSET_S 0x00000000
/* Code SRAM memory */
#define MPC_CODE_SRAM_RANGE_BASE_NS (0x00000000)
#define MPC_CODE_SRAM_RANGE_LIMIT_NS (0x001FFFFF)
#define MPC_CODE_SRAM_RANGE_OFFSET_NS (0x00000000)
#define MPC_CODE_SRAM_RANGE_BASE_S (0x10000000)
#define MPC_CODE_SRAM_RANGE_LIMIT_S (0x101FFFFF)
#define MPC_CODE_SRAM_RANGE_OFFSET_S (0x00000000)
/* QSPI Flash memory */
#define MPC_QSPI_RANGE_BASE_NS (0x00200000)
#define MPC_QSPI_RANGE_LIMIT_NS (0x011FFFFF)
#define MPC_QSPI_RANGE_OFFSET_NS (0x00200000)
#define MPC_QSPI_RANGE_BASE_S (0x10200000)
#define MPC_QSPI_RANGE_LIMIT_S (0x111FFFFF)
#define MPC_QSPI_RANGE_OFFSET_S (0x00200000)
/* MRAM memory */
#define MPC_MRAM_RANGE_BASE_NS (0x0A000000)
#define MPC_MRAM_RANGE_LIMIT_NS (0x0A1FFFFF)
#define MPC_MRAM_RANGE_OFFSET_NS (0x00000000)
#define MPC_MRAM_RANGE_BASE_S (0x1A000000)
#define MPC_MRAM_RANGE_LIMIT_S (0x1A1FFFFF)
#define MPC_MRAM_RANGE_OFFSET_S (0x00000000)
/** @} */ /* End of group Device_Peripheral_peripheralAddr */
#ifdef __cplusplus
}
#endif
#endif /* __PLATFORM_BASE_ADDRESS_H__ */

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2018-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __PLATFORM_DESCRIPTION_H__
#define __PLATFORM_DESCRIPTION_H__
#include "platform_base_address.h"
#include "platform_pins.h"
#include "platform_regs.h"
#include "cmsis.h"
#endif /* __PLATFORM_DESCRIPTION_H__ */

View File

@ -0,0 +1,135 @@
/*
* Copyright (c) 2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __PLATFORM_IRQ_H__
#define __PLATFORM_IRQ_H__
#ifdef __cplusplus
extern "C" {
#endif
/* ======================================================================= */
/* ================== Interrupt Number Definition ===================== */
/* ======================================================================= */
typedef enum IRQn
{
/* =============== Core Specific Interrupt Numbers ====================== */
NonMaskableInt_IRQn = -14, /* -14 Non Maskable Interrupt */
HardFault_IRQn = -13, /* -13 HardFault Interrupt */
MemoryManagement_IRQn = -12, /* -12 Memory Management Interrupt */
BusFault_IRQn = -11, /* -11 Bus Fault Interrupt */
UsageFault_IRQn = -10, /* -10 Usage Fault Interrupt */
SecureFault_IRQn = -9, /* -9 Secure Fault Interrupt */
SVCall_IRQn = -5, /* -5 SV Call Interrupt */
DebugMonitor_IRQn = -4, /* -4 Debug Monitor Interrupt */
PendSV_IRQn = -2, /* -2 Pend SV Interrupt */
SysTick_IRQn = -1, /* -1 System Tick Interrupt */
/* ============= Musca Specific SSE-200 Interrupt Numbers =============== */
NS_WATCHDOG_RESET_IRQn = 0, /* Non-Secure Watchdog Reset Request
* Interrupt */
NS_WATCHDOG_IRQn = 1, /* Non-Secure Watchdog Interrupt */
S32K_TIMER_IRQn = 2, /* S32K Timer Interrupt */
TIMER0_IRQn = 3, /* CMSDK Timer 0 Interrupt */
TIMER1_IRQn = 4, /* CMSDK Timer 1 Interrupt */
DUALTIMER_IRQn = 5, /* CMSDK Dual Timer Interrupt */
MHU0_IRQn = 6, /* Message Handling Unit 0 Interrupt */
MHU1_IRQn = 7, /* Message Handling Unit 1 Interrupt */
CRYPTOCELL_IRQn = 8, /* CryptoCell-312 Interrupt */
S_MPC_COMBINED_IRQn = 9, /* Secure Combined MPC Interrupt */
S_PPC_COMBINED_IRQn = 10, /* Secure Combined PPC Interrupt */
S_MSC_COMBINED_IRQn = 11, /* Secure Combined MSC Interrupt */
S_BRIDGE_ERR_IRQn = 12, /* Secure Bridge Error Combined
* Interrupt */
I_CACHE_INV_ERR_IRQn = 13, /* Instruction Cache Invalidation
* Interrupt */
/* Reserved = 14, Reserved */
SYS_PPU_IRQn = 15, /* System PPU Interrupt */
CPU0_PPU_IRQn = 16, /* CPU0 PPU Interrupt */
CPU1_PPU_IRQn = 17, /* CPU1 PPU Interrupt */
CPU0_DGB_PPU_IRQn = 18, /* CPU0 Debug PPU Interrupt */
CPU1_DGB_PPU_IRQn = 19, /* CPU1 Debug PPU Interrupt */
CRYPTOCELL_PPU_IRQn = 20, /* CryptoCell PPU Interrupt */
/* Reserved = 21, Reserved */
RAM0_PPU_IRQn = 22, /* RAM 0 PPU Interrupt */
RAM1_PPU_IRQn = 23, /* RAM 1 PPU Interrupt */
RAM2_PPU_IRQn = 24, /* RAM 2 PPU Interrupt */
RAM3_PPU_IRQn = 25, /* RAM 3 PPU Interrupt */
DEBUG_PPU_IRQn = 26, /* Debug PPU Interrupt */
/* Reserved = 27, Reserved */
CPU0_CTI_IRQn = 28, /* CPU0 CTI Interrupt */
CPU1_CTI_IRQn = 29, /* CPU1 CTI Interrupt */
/* Reserved = 30, Reserved */
/* Reserved = 31, Reserved */
/* ============ Musca Specific Expansion Interrupt Numbers ============== */
/* None = 32, Not used. Tied to 0 */
GpTimer_IRQn = 33, /* General Purpose Timer Interrupt */
I2C0_IRQn = 34, /* I2C0 Interrupt */
I2C1_IRQn = 35, /* I2C1 Interrupt */
I2S_IRQn = 36, /* I2S Interrupt */
SPI_IRQn = 37, /* SPI Interrupt */
QSPI_IRQn = 38, /* QSPI Interrupt */
UART0_Rx_IRQn = 39, /* UART0 receive FIFO interrupt */
UART0_Tx_IRQn = 40, /* UART0 transmit FIFO interrupt */
UART0_RxTimeout_IRQn = 41, /* UART0 receive timeout interrupt */
UART0_ModemStatus_IRQn = 42, /* UART0 modem status interrupt */
UART0_Error_IRQn = 43, /* UART0 error interrupt */
UART0_IRQn = 44, /* UART0 interrupt */
UART1_Rx_IRQn = 45, /* UART1 receive FIFO interrupt */
UART1_Tx_IRQn = 46, /* UART1 transmit FIFO interrupt */
UART1_RxTimeout_IRQn = 47, /* UART1 receive timeout interrupt */
UART1_ModemStatus_IRQn = 48, /* UART1 modem status interrupt */
UART1_Error_IRQn = 49, /* UART1 error interrupt */
UART1_IRQn = 50, /* UART1 interrupt */
GPIO_0_IRQn = 51, /* GPIO 0 interrupt */
GPIO_1_IRQn = 52, /* GPIO 1 interrupt */
GPIO_2_IRQn = 53, /* GPIO 2 interrupt */
GPIO_3_IRQn = 54, /* GPIO 3 interrupt */
GPIO_4_IRQn = 55, /* GPIO 4 interrupt */
GPIO_5_IRQn = 56, /* GPIO 5 interrupt */
GPIO_6_IRQn = 57, /* GPIO 6 interrupt */
GPIO_7_IRQn = 58, /* GPIO 7 interrupt */
GPIO_8_IRQn = 59, /* GPIO 8 interrupt */
GPIO_9_IRQn = 60, /* GPIO 9 interrupt */
GPIO_10_IRQn = 61, /* GPIO 10 interrupt */
GPIO_11_IRQn = 62, /* GPIO 11 interrupt */
GPIO_12_IRQn = 63, /* GPIO 12 interrupt */
GPIO_13_IRQn = 64, /* GPIO 13 interrupt */
GPIO_14_IRQn = 65, /* GPIO 14 interrupt */
GPIO_15_IRQn = 66, /* GPIO 15 interrupt */
Combined_IRQn = 67, /* Combined interrupt */
PVT_IRQn = 68, /* PVT sensor interrupt */
/* Reserved = 69, Reserved */
PWM_0_IRQn = 70, /* PWM0 interrupt */
RTC_IRQn = 71, /* RTC interrupt */
GpTimer1_IRQn = 72, /* General Purpose Timer Alarm1
* Interrupt */
GpTimer0_IRQn = 73, /* General Purpose Timer Alarm0
* Interrupt */
PWM_1_IRQn = 74, /* PWM1 interrupt */
PWM_2_IRQn = 75, /* PWM2 interrupt */
IOMUX_IRQn = 76, /* IOMUX interrupt */
} IRQn_Type;
#ifdef __cplusplus
}
#endif
#endif /* __PLATFORM_IRQ_H__ */

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2016-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file platform_pins.h
* \brief This file defines all the pins for this platform.
*/
#ifndef __PLATFORM_PINS__
#define __PLATFORM_PINS__
/* AHB GPIO pin names */
enum arm_gpio_pin_name_t {
AHB_GPIO0_0 = 0U,
AHB_GPIO0_1,
AHB_GPIO0_2,
AHB_GPIO0_3,
AHB_GPIO0_4,
AHB_GPIO0_5,
AHB_GPIO0_6,
AHB_GPIO0_7,
AHB_GPIO0_8,
AHB_GPIO0_9,
AHB_GPIO0_10,
AHB_GPIO0_11,
AHB_GPIO0_12,
AHB_GPIO0_13,
AHB_GPIO0_14,
AHB_GPIO0_15,
};
#endif /* __PLATFORM_PINS__ */

View File

@ -0,0 +1,341 @@
/*
* Copyright (c) 2016-2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MUSCA_S1_PLATFORM_REGS__
#define __MUSCA_S1_PLATFORM_REGS__
#include <stdint.h>
#include "platform_base_address.h"
/* sysinfo memory mapped register access structure */
struct sysinfo_t {
volatile uint32_t sysversion; /* (R/ ) 0x000 System version */
volatile uint32_t sysconfig; /* (R/ ) 0x004 System configuration */
volatile uint32_t reserved0[1010]; /* 0x010-0xFCC Reserved */
volatile uint32_t pidr4; /* (R/ ) 0xFD0 Peripheral ID 4 */
volatile uint32_t reserved1[3]; /* 0xFD4-0xFDC Reserved */
volatile uint32_t pidr0; /* (R/ ) 0xFE0 Peripheral ID 0 */
volatile uint32_t pidr1; /* (R/ ) 0xFE4 Peripheral ID 1 */
volatile uint32_t pidr2; /* (R/ ) 0xFE8 Peripheral ID 2 */
volatile uint32_t pidr3; /* (R/ ) 0xFEC Peripheral ID 3 */
volatile uint32_t cidr0; /* (R/ ) 0xFF0 Component ID 0 */
volatile uint32_t cidr1; /* (R/ ) 0xFF4 Component ID 1 */
volatile uint32_t cidr2; /* (R/ ) 0xFF8 Component ID 2 */
volatile uint32_t cidr3; /* (R/ ) 0xFFC Component ID 3 */
};
/* Secure System Control (SYSCTRL) Alias */
#define CMSDK_SYSCTRL_BASE_S MUSCA_S1_SYSTEM_CTRL_S_BASE
/* sysctrl memory mapped register access structure */
struct sysctrl_t {
/* (R/ ) 0x000 Secure Debug Configuration Status Register*/
volatile uint32_t secdbgstat;
/* ( /W) 0x004 Secure Debug Configuration Set Register */
volatile uint32_t secdbgset;
/* ( /W) 0x008 Secure Debug Configuration Clear Register */
volatile uint32_t secdbgclr;
/* (R/W) 0x00C System Control Security Control Register */
volatile uint32_t scsecctrl;
/* (R/W) 0x010 Fast Clock Divider Configuration Register */
volatile uint32_t fclk_div;
/* (R/W) 0x014 System Clock Divider Configuration Register */
volatile uint32_t sysclk_div;
/* (R/W) 0x018 Clock Forces */
volatile uint32_t clockforce;
/* 0x01C-0x0FC Reserved */
volatile uint32_t reserved0[57];
/* (R/W) 0x100 Reset syndrome */
volatile uint32_t resetsyndrome;
/* (R/W) 0x104 Reset MASK */
volatile uint32_t resetmask;
/* ( /W) 0x108 Software Reset */
volatile uint32_t swreset;
/* (R/W) 0x10C General Purpose Retention Register */
volatile uint32_t gretreg;
/* (R/W) 0x110 Initial Secure Reset Vector Register For CPU 0 */
volatile uint32_t initsvtor0;
/* (R/W) 0x114 Initial Secure Reset Vector Register For CPU 1*/
volatile uint32_t initsvtor1;
/* (R/W) 0x118 CPU Boot wait control after reset */
volatile uint32_t cpuwait;
/* (R/W) 0x11C NMI Enable */
volatile uint32_t nmi_enable;
/* (R/W) 0x120 CPU WIC Request and Acknowledgement */
volatile uint32_t wicctrl;
/* (R/W) 0x124 External Wakeup Control */
volatile uint32_t ewctrl;
/* 0x128-0x1FC Reserved */
volatile uint32_t reserved2[54];
/* (R/W) 0x200 Power Control Dependency Matrix
* PD_SYS Power Domain Sensitivity.*/
volatile uint32_t pdcm_pd_sys_sense;
/* 0x204-0x208 Reserved */
volatile uint32_t reserved3[2];
/* (R/W) 0x20C Power Control Dependency Matrix
* PD_SRAM0 Power Domain Sensitivity.*/
volatile uint32_t pdcm_pd_sram0_sense;
/* (R/W) 0x210 Power Control Dependency Matrix
* PD_SRAM1 Power Domain Sensitivity.*/
volatile uint32_t pdcm_pd_sram1_sense;
/* 0x214(R/W) Power Control Dependency Matrix
* PD_SRAM2 Power Domain Sensitivity.*/
volatile uint32_t pdcm_pd_sram2_sense;
/* (R/W) 0x218 Power Control Dependency Matrix
* PD_SRAM3 Power Domain Sensitivity.*/
volatile uint32_t pdcm_pd_sram3_sense;
/* 0x21C-0xFCC Reserved */
volatile uint32_t reserved4[877];
/* (R/ ) 0xFD0 Peripheral ID 4 */
volatile uint32_t pidr4;
/* 0xFD4-0xFDC Reserved */
volatile uint32_t reserved5[3];
/* (R/ ) 0xFE0 Peripheral ID 0 */
volatile uint32_t pidr0;
/* (R/ ) 0xFE4 Peripheral ID 1 */
volatile uint32_t pidr1;
/* (R/ ) 0xFE8 Peripheral ID 2 */
volatile uint32_t pidr2;
/* (R/ ) 0xFEC Peripheral ID 3 */
volatile uint32_t pidr3;
/* (R/ ) 0xFF0 Component ID 0 */
volatile uint32_t cidr0;
/* (R/ ) 0xFF4 Component ID 1 */
volatile uint32_t cidr1;
/* (R/ ) 0xFF8 Component ID 2 */
volatile uint32_t cidr2;
/* (R/ ) 0xFFC Component ID 3 */
volatile uint32_t cidr3;
};
/* Secure Privilege Control */
#define CMSDK_SPCTRL ((struct spctrl_def*)MUSCA_S1_SPCTRL_S_BASE)
/* SPCTRL memory mapped register access structure */
struct spctrl_def {
/* (R/W) 0x000 Secure Configuration Control Register */
volatile uint32_t spcsecctrl;
/* (R/W) 0x004 Bus Access wait control after reset.*/
volatile uint32_t buswait;
/* 0x008-0x00C Reserved */
volatile uint32_t reserved1[2];
/* (R/W) 0x010Security Violation Response Configuration register.*/
volatile uint32_t secrespcfg;
/* (R/W) 0x014 Non Secure Callable Configuration for IDAU. */
volatile uint32_t nsccfg;
/* 0x018 Reserved */
volatile uint32_t reserved2;
/* (R/W) 0x01C Secure MPC Interrupt Status. */
volatile uint32_t secmpcintstat;
/* (R/W) 0x020 Secure PPC Interrupt Status. */
volatile uint32_t secppcintstat;
/* (R/W) 0x024 Secure PPC Interrupt Clear. */
volatile uint32_t secppcintclr;
/* (R/W) 0x28 Secure PPC Interrupt Enable. */
volatile uint32_t secppcinten;
/* 0x02C-0x03C Reserved */
volatile uint32_t reserved3[5];
/* (R/W) 0x040 Bridge Buffer Error Interrupt Status. */
volatile uint32_t brgintstat;
/* (R/W) 0x044 Bridge Buffer Error Interrupt Clear. */
volatile uint32_t brgintclr;
/* (R/W) 0x048 Bridge Buffer Error Interrupt Enable. */
volatile uint32_t brginten;
/* 0x04C-0x05C Reserved */
volatile uint32_t reserved4[5];
/* (R/W) 0x060 Expansion 0 Non_Secure Access
* AHB slave Peripheral Protection Control */
volatile uint32_t ahbnsppcexp0;
/* 0x064-0x06C Reserved */
volatile uint32_t reserved5[3];
/* (R/W) 0x070 Non-Secure Access
* APB slave Peripheral Protection Control #0 */
volatile uint32_t apbnsppc0;
/* (R/W) 0x074 Non-Secure Access
* APB slave Peripheral Protection Control #1 */
volatile uint32_t apbnsppc1;
/* 0x078-0x07C Reserved */
volatile uint32_t reserved6[2];
/* (R/W) 0x080 Expansion 0 Non_Secure Access
* APB slave Peripheral Protection Control */
volatile uint32_t apbnsppcexp0;
/* (R/W) 0x084 Expansion 1 Non_Secure Access
* APB slave Peripheral Protection Control */
volatile uint32_t apbnsppcexp1;
/* 0x088-0x08C Reserved */
volatile uint32_t reserved7[2];
/* (R/W) 0x090 Secure Unprivileged Access
* AHB slave Peripheral Protection Control #0. */
volatile uint32_t ahbspppc0;
/* 0x094-0x09C Reserved */
volatile uint32_t reserved8[3];
/* (R/W) 0x0A0 Expansion 0 Secure Unprivileged Access
* AHB slave Peripheral Protection Control. */
volatile uint32_t ahbspppcexp0;
/* 0x0A4-0x0AC Reserved */
volatile uint32_t reserved9[3];
/* (R/W) 0x0B0 Secure Unprivileged Access
* APB slave Peripheral Protection Control #0 */
volatile uint32_t apbspppc0;
/* (R/W) 0x0B4 Secure Unprivileged Access
* APB slave Peripheral Protection Control #1 */
volatile uint32_t apbspppc1;
/* 0x0B8-0x0BC Reserved */
volatile uint32_t reserved10[2];
/* (R/W) 0x0C0 Expansion 0 Secure Unprivileged Access
* APB slave Peripheral Protection Control */
volatile uint32_t apbspppcexp0;
/* (R/W) 0x0C4 Expansion 1 Secure Unprivileged Access
* APB slave Peripheral Protection Control */
volatile uint32_t apbspppcexp1;
/* 0x0C8-0xFCC Reserved */
volatile uint32_t reserved11[962];
/* (R/W) 0xFD0 Peripheral ID 4 */
volatile uint32_t pid4;
/* 0xFD4-0xFDC Reserved */
volatile uint32_t reserved12[3];
/* (R/W) 0xFE0 Peripheral ID 0 */
volatile uint32_t pid0;
/* (R/W) 0xFE4 Peripheral ID 1 */
volatile uint32_t pid1;
/* (R/W) 0xFE8 Peripheral ID 2 */
volatile uint32_t pid2;
/* (R/W) 0xFEC Peripheral ID 3 */
volatile uint32_t pid3;
/* (R/W) 0xFF0 Component ID 0 */
volatile uint32_t cid0;
/* (R/W) 0xFF4 Component ID 1 */
volatile uint32_t cid1;
/* (R/W) 0xFF8 Component ID 2 */
volatile uint32_t cid2;
/* (R/W) 0xFFC Component ID 3 */
volatile uint32_t cid3;
};
/* Secure PPC interrupt position mask */
#define CMSDK_APB_PPC0_INT_POS_MASK (1UL << 0)
#define CMSDK_APB_PPC1_INT_POS_MASK (1UL << 1)
#define CMSDK_APB_PPCEXP0_INT_POS_MASK (1UL << 4)
#define CMSDK_APB_PPCEXP1_INT_POS_MASK (1UL << 5)
#define CMSDK_APB_PPCEXP2_INT_POS_MASK (1UL << 6)
#define CMSDK_APB_PPCEXP3_INT_POS_MASK (1UL << 7)
#define CMSDK_AHB_PPCEXP0_INT_POS_MASK (1UL << 20)
#define CMSDK_AHB_PPCEXP1_INT_POS_MASK (1UL << 21)
#define CMSDK_AHB_PPCEXP2_INT_POS_MASK (1UL << 22)
#define CMSDK_AHB_PPCEXP3_INT_POS_MASK (1UL << 23)
/* Non-Secure Privilege Control */
#define CMSDK_NSPCTRL ((struct nspctrl_def*)MUSCA_S1_NSPCTRL_NS_BASE)
/* NSPCTRL memory mapped register access structure */
struct nspctrl_def {
/* 0x000-0x09C Reserved */
volatile uint32_t reserved1[40];
/* (R/W) 0x0A0 Expansion 0 Non-Secure Unprivileged Access
* AHB slave Peripheral Protection Control */
volatile uint32_t ahbnspppcexp0;
/* 0x0A4-0x0AC Reserved */
volatile uint32_t reserved2[3];
/* (R/W) 0x0B0 Non-Secure Unprivileged Access
* APB slave Peripheral Protection Control #0 */
volatile uint32_t apbnspppc0;
/* (R/W) 0x0B4 Non-Secure Unprivileged Access
* APB slave Peripheral Protection Control #1 */
volatile uint32_t apbnspppc1;
/* 0x0B8-0x0BC Reserved */
volatile uint32_t reserved3[2];
/* (R/W) 0x0C0 Expansion 0 Non-Secure Unprivileged Access
* APB slave Peripheral Protection Control */
volatile uint32_t apbnspppcexp0;
/* (R/W) 0x0C4 Expansion 1 Non-Secure Unprivileged Access
* APB slave Peripheral Protection Control */
volatile uint32_t apbnspppcexp1;
/* 0x0C8-0xFCC Reserved */
volatile uint32_t reserved4[962];
/* (R/W) 0xFD0 Peripheral ID 4 */
volatile uint32_t pidr4;
/* 0xFD4-0xFDC Reserved */
volatile uint32_t reserved5[3];
/* (R/W) 0xFE0 Peripheral ID 0 */
volatile uint32_t pidr0;
/* (R/W) 0xFE4 Peripheral ID 1 */
volatile uint32_t pidr1;
/* (R/W) 0xFE8 Peripheral ID 2 */
volatile uint32_t pidr2;
/* (R/W) 0xFEC Peripheral ID 3 */
volatile uint32_t pidr3;
/* (R/W) 0xFF0 Component ID 0 */
volatile uint32_t cidr0;
/* (R/W) 0xFF4 Component ID 1 */
volatile uint32_t cidr1;
/* (R/W) 0xFF8 Component ID 2 */
volatile uint32_t cidr2;
/* (R/W) 0xFFC Component ID 3 */
volatile uint32_t cidr3;
};
/* ARM APB PPC0 peripherals definition */
#define CMSDK_TIMER0_APB_PPC_POS 0U
#define CMSDK_TIMER1_APB_PPC_POS 1U
#define CMSDK_DTIMER_APB_PPC_POS 2U
#define CMSDK_MHU0_APB_PPC_POS 3U
#define CMSDK_MHU1_APB_PPC_POS 4U
/* The bits 31:5 are reserved */
/* ARM APB PPC1 peripherals definition */
#define CMSDK_S32K_TIMER_PPC_POS 0U
/* The bits 31:1 are reserved */
/* ARM AHB PPC0 peripherals definition */
/* The bits 31:0 are reserved */
/* ARM AHB PPCEXP0 peripherals definition */
#define MUSCA_S1_GPIO_AHB_PPC_POS 1U
/* The bits 31:1 are reserved */
/* ARM AHB PPCEXP1 peripherals definition */
/* The bits 31:0 are reserved */
/* ARM AHB PPCEXP2 peripherals definition */
/* The bits 31:0 are reserved */
/* ARM AHB PPCEXP3 peripherals definition */
/* The bits 31:0 are reserved */
/* ARM APB PPCEXP0 peripherals definition */
#define MUSCA_S1_QSPI_MPC_APB_PPC_POS 0U
#define MUSCA_S1_SRAM_MPC_APB_PPC_POS 1U
#define MUSCA_S1_MRAM_MPC_APB_PPC_POS 2U
/* ARM APB PPCEXP1 peripherals definition */
#define MUSCA_S1_UART0_APB_PPC_POS 0U
#define MUSCA_S1_UART1_APB_PPC_POS 1U
#define MUSCA_S1_SPI_APB_PPC_POS 2U
#define MUSCA_S1_I2C0_APB_PPC_POS 3U
#define MUSCA_S1_I2C1_APB_PPC_POS 4U
#define MUSCA_S1_I2S_APB_PPC_POS 5U
#define MUSCA_S1_PWM0_APB_PPC_POS 6U
#define MUSCA_S1_RTC_APB_PPC_POS 7U
#define MUSCA_S1_PVT_APB_PPC_POS 8U
#define MUSCA_S1_QSPI_APB_PPC_POS 9U
#define MUSCA_S1_GPTIMER_APB_PPC_POS 10U
#define MUSCA_S1_SCC_APB_PPC_POS 11U
#define MUSCA_S1_PWM1_APB_PPC_POS 12U
#define MUSCA_S1_PWM2_APB_PPC_POS 13U
#endif /* __MUSCA_S1_PLATFORM_REGS__ */

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2009-2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is derivative of CMSIS V5.01 \Device\ARM\ARMCM33\Source\system_ARMCM33.c
* https://github.com/ARM-software/CMSIS_5/tree/5.0.1
* Git SHA: 8a1d9d6ee18b143ae5befefa14d89fb5b3f99c75
*/
#include <stdint.h>
#include "system_core_init.h"
#include "platform_description.h"
/*----------------------------------------------------------------------------
Define clocks
*----------------------------------------------------------------------------*/
#define XTAL (50000000UL)
#define SYSTEM_CLOCK (XTAL)
#define SYSTEM_REFCLK (32768UL)
/*----------------------------------------------------------------------------
Externals
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
System Core Clock Variable
*----------------------------------------------------------------------------*/
uint32_t SystemCoreClock = SYSTEM_CLOCK;
uint32_t PeripheralClock = SYSTEM_CLOCK;
uint32_t RefClock = SYSTEM_REFCLK;
/*----------------------------------------------------------------------------
System Core Clock update function
*----------------------------------------------------------------------------*/
void SystemCoreClockUpdate (void)
{
SystemCoreClock = SYSTEM_CLOCK;
PeripheralClock = SYSTEM_CLOCK;
RefClock = SYSTEM_REFCLK;
}
/*----------------------------------------------------------------------------
System initialization function
*----------------------------------------------------------------------------*/
void SystemInit (void)
{
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
extern uint32_t __Vectors;
SCB->VTOR = (uint32_t) &__Vectors;
#endif
#if defined (__FPU_USED) && (__FPU_USED == 1U)
SCB->CPACR |= ((3U << 10U*2U) | /* set CP10 Full Access */
(3U << 11U*2U) ); /* set CP11 Full Access */
#endif
#ifdef UNALIGNED_SUPPORT_DISABLE
SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
#endif
SystemCoreClock = SYSTEM_CLOCK;
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2017-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is derivative of CMSIS V5.01 \Device\ARM\ARMCM33\Include\system_ARMCM33.h
* Git SHA: 8a1d9d6ee18b143ae5befefa14d89fb5b3f99c75
*
*/
#ifndef __SYSTEM_CORE_INIT_H__
#define __SYSTEM_CORE_INIT_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
extern uint32_t PeripheralClock; /*!< Peripheral Clock Frequency */
extern uint32_t RefClock; /*!< External Reference Clock Frequency */
/**
\brief Setup the microcontroller system.
Initialize the System and update the SystemCoreClock variable.
It should be called from Reset Handler within the first few steps.
The minimal feature set should be initialised for successful exit
from Reset Handler to main entry point.
*/
extern void SystemInit (void);
/**
\brief Update SystemCoreClock variable.
Updates the SystemCoreClock with current core Clock retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_CORE_INIT_H__ */

View File

@ -0,0 +1,136 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "device.h"
#include "flash_layout.h"
#include "flash_api.h"
#if DEVICE_FLASH
int32_t flash_init(flash_t *obj)
{
(void)(obj);
enum mt25ql_error_t err = MT25QL_ERR_NONE;
qspi_ip6514e_enable(FLASH_DEV.controller);
/* Configure QSPI Flash controller to operate in single SPI mode and
* to use fast Flash commands */
err = mt25ql_config_mode(&FLASH_DEV, MT25QL_FUNC_STATE_FAST);
if (err != MT25QL_ERR_NONE) {
return -1;
}
return 0;
}
int32_t flash_free(flash_t *obj)
{
(void)(obj);
enum mt25ql_error_t err = MT25QL_ERR_NONE;
/* Restores the QSPI Flash controller and MT25QL to reset state */
err = mt25ql_restore_reset_state(&FLASH_DEV);
if (err != MT25QL_ERR_NONE) {
return -1;
}
return 0;
}
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
{
(void)(obj);
enum mt25ql_error_t err = MT25QL_ERR_NONE;
address -= FLASH_DEV.direct_access_start_addr;
err = mt25ql_erase(&FLASH_DEV, address, MT25QL_ERASE_SUBSECTOR_4K);
if (err != MT25QL_ERR_NONE) {
return -1;
}
return 0;
}
int32_t flash_read(flash_t *obj, uint32_t address,
uint8_t *data, uint32_t size)
{
(void)obj;
enum mt25ql_error_t err = MT25QL_ERR_NONE;
address -= FLASH_DEV.direct_access_start_addr;
err = mt25ql_command_read(&FLASH_DEV, address, data, size);
if (err != MT25QL_ERR_NONE) {
return -1;
}
return 0;
}
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
{
(void)(obj);
enum mt25ql_error_t err = MT25QL_ERR_NONE;
address -= FLASH_DEV.direct_access_start_addr;
err = mt25ql_command_write(&FLASH_DEV, address, data, size);
if (err != MT25QL_ERR_NONE) {
return -1;
}
return 0;
}
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
{
(void)(obj);
if ((address >= NS_QSPI_ALIAS_BASE) && (address < NS_QSPI_ALIAS_BASE + QSPI_FLASH_TOTAL_SIZE)) {
return SUBSECTOR_4KB;
}
return MBED_FLASH_INVALID_SIZE;
}
uint32_t flash_get_page_size(const flash_t *obj)
{
(void)(obj);
return FLASH_PAGE_SIZE;
}
uint32_t flash_get_start_address(const flash_t *obj)
{
(void)(obj);
return NS_QSPI_ALIAS_BASE;
}
uint32_t flash_get_size(const flash_t *obj)
{
(void)(obj);
return QSPI_FLASH_TOTAL_SIZE;
}
uint8_t flash_get_erase_value(const flash_t *obj)
{
(void)obj;
return 0xFF;
}
#endif // DEVICE_FLASH

View File

@ -0,0 +1,141 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This file implements APIS defined in hal/gpio_api.h
* Note: Due to a HW limitation, GPIO in Musca-S1 is Secure only, so secure
* service should be used for GPIO in NS domain.
*/
#include <stddef.h>
#include "gpio_api.h"
#include "pinmap.h"
#include "objects.h"
#include "mbed_error.h"
#include "mbed_assert.h"
#include "rtx_lib.h"
#include "tfm_platform_api.h"
#include "tfm_ioctl_api.h"
#define RETURN_VOID_true return;
#define RETURN_VOID_false return 0;
#define IRQ_MODE_CHECK(is_func_void) \
/* Secure service can't be called in interrupt context. */ \
if (IsIrqMode()) { \
MBED_WARNING(MBED_MAKE_ERROR(MBED_MODULE_HAL, \
MBED_ERROR_INVALID_OPERATION), \
"GPIO secure service can't be called in interrupt context\n"); \
RETURN_VOID_ ## is_func_void \
}
uint32_t gpio_set(PinName pin)
{
pin_function(pin, (int)PRIMARY_FUNC);
/* Return the correct mask of the given PIN */
return (1 << GPIO_PIN_NUMBER(pin));
}
void gpio_init(gpio_t *obj, PinName pin)
{
obj->pin_num = (uint32_t)NC;
uint32_t result = 0;
enum tfm_platform_err_t ret = TFM_PLATFORM_ERR_SUCCESS;
if (pin >= PA0 && pin <= PA15) {
IRQ_MODE_CHECK(true);
ret = tfm_platform_gpio_init(&result);
if (ret || result) {
return;
}
obj->pin_num = pin;
/* GPIO is input by default */
obj->direction = PIN_INPUT;
return;
}
}
void gpio_mode(gpio_t *obj, PinMode mode)
{
pin_mode(obj->pin_num, mode);
}
void gpio_dir(gpio_t *obj, PinDirection direction)
{
uint32_t pin_dir = (direction == PIN_INPUT ? 0 : 1);
uint32_t result = 0;
enum tfm_platform_err_t ret = TFM_PLATFORM_ERR_SUCCESS;
IRQ_MODE_CHECK(true);
ret = tfm_platform_gpio_pin_config(obj->pin_num, pin_dir, &result);
if (ret || result) {
error("gpio_dir failed, error %d, gpio error %d", ret, result);
}
obj->direction = direction;
}
int gpio_is_connected(const gpio_t *obj)
{
if (obj->pin_num == (uint32_t)NC) {
return 0;
} else {
return 1;
}
}
void gpio_write(gpio_t *obj, int value)
{
enum tfm_platform_err_t ret = TFM_PLATFORM_ERR_SUCCESS;
uint32_t result = 0;
IRQ_MODE_CHECK(true);
ret = tfm_platform_gpio_pin_write(obj->pin_num, (uint32_t)value, &result);
if (ret || result) {
error("Can not write pin %d; error %d, gpio error %d",
obj->pin_num, ret, result);
}
}
int gpio_read(gpio_t *obj)
{
enum tfm_platform_err_t ret = TFM_PLATFORM_ERR_SUCCESS;
uint32_t result = 0;
uint32_t data = 0;
IRQ_MODE_CHECK(false);
ret = tfm_platform_gpio_pin_read(obj->pin_num, &data, &result);
/* The valid return values of this API are 0 and 1 */
if (ret || result) {
return 0;
} else {
return data;
}
}

View File

@ -0,0 +1,71 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This file implements APIS defined in hal/gpio_irq_api.h
* Note: Due to a HW limitation, GPIO in Musca-S1 is Secure only, in NS domain,
* GPIO platform service is used. The current implementation of GPIO
* platform service does not support IRQ handling.
*/
#include <stddef.h>
#include "gpio_irq_api.h"
#include "objects.h"
#include "mbed_error.h"
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler,
uint32_t id)
{
/* Due to a HW limitation, GPIO in Musca-S1 is Secure only, in NS domain,
* GPIO platform service is used. The current implementation of GPIO
* platform service does not support IRQ handling.
*/
return 0;
}
void gpio_irq_free(gpio_irq_t *obj)
{
/* Due to a HW limitation, GPIO in Musca-S1 is Secure only, in NS domain,
* GPIO platform service is used. The current implementation of GPIO
* platform service does not support IRQ handling.
*/
}
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
{
/* Due to a HW limitation, GPIO in Musca-S1 is Secure only, in NS domain,
* GPIO platform service is used. The current implementation of GPIO
* platform service does not support IRQ handling.
*/
}
void gpio_irq_enable(gpio_irq_t *obj)
{
/* Due to a HW limitation, GPIO in Musca-S1 is Secure only, in NS domain,
* GPIO platform service is used. The current implementation of GPIO
* platform service does not support IRQ handling.
*/
}
void gpio_irq_disable(gpio_irq_t *obj)
{
/* Due to a HW limitation, GPIO in Musca-S1 is Secure only, in NS domain,
* GPIO platform service is used. The current implementation of GPIO
* platform service does not support IRQ handling.
*/
}

View File

@ -0,0 +1,51 @@
/* mbed Microcontroller Library
* Copyright (c) 2019-2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_GPIO_OBJECT_H
#define MBED_GPIO_OBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
#define GPIO_PIN_NUMBER(pin) ((pin) & 0xF)
#define PINS_NUMBER (16)
/**
* \brief Object to store GPIO specific data through the configuration
*/
typedef struct gpio_s {
struct gpio_cmsdk_dev_t *gpio_dev;
uint32_t pin_num;
PinDirection direction;
} gpio_t;
struct gpio_irq_s {
/** GPIO is not available in Musca-S1 in non-secure domain, so this dummy
* structure is needed for successful build.
*/
uint32_t dummy;
};
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,427 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "i2c_api.h"
#include "mbed_error.h"
#include "i2c_ip6510_drv.h"
#include "objects.h"
#include "pinmap.h"
#include "PeripheralNames.h"
/* Return error codes for the i2c_byte_write api */
#define BYTE_TRANSFER_ERR_NACK (0)
#define BYTE_TRANSFER_ERR_NONE (1)
#define BYTE_TRANSFER_ERR_TIMEOUT (2)
/* Macros for frequency configuration */
#define I2C_SPEED_100KHZ (100000)
#define I2C_SPEED_400KHZ (400000)
#if DEVICE_I2CSLAVE
/* Return values for slave addressing specified in mbed I2C slave driver */
#define I2C_SLAVE_READ_ADDRESS (1)
#define I2C_SLAVE_WRITE_ALL_ADDRESS (2)
#define I2C_SLAVE_WRITE_ADDRESS (3)
#define I2C_SLAVE_NOT_ADDRESSED (0)
#endif
extern const PinMap PinMap_I2C_SDA[];
extern const PinMap PinMap_I2C_SCL[];
/* Extend the return values defined in i2c_api.h */
enum {
I2C_ERROR_NONE = 0,
/* I2C_ERROR_NO_SLAVE = -1,
* I2C_ERROR_BUS_BUSY = -2, */
I2C_ERROR_GENERAL = -3
};
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
{
enum i2c_ip6510_error_t ret;
/* Determine the I2C to use */
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
I2CName i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
if (i2c == (I2CName)NC) {
error("I2C pinout mapping failed, invalid pins.");
return;
}
/* Initialize the parent object */
switch (i2c) {
#ifdef I2C0_IP6510_DEV
case I2C_0:
obj->dev = &I2C0_IP6510_DEV;
break;
#endif
#ifdef I2C1_IP6510_DEV
case I2C_1:
obj->dev = &I2C1_IP6510_DEV;
break;
#endif
default:
error("Failed to initialize I2C, bad reference.");
return;
}
obj->last_address = 0U;
obj->sda = sda;
obj->scl = scl;
obj->byte_state = BYTE_TRANSFER_STATE_NONE;
/* If already init, uninit */
if (i2c_ip6510_get_state(obj->dev) == I2C_IP6510_INITIALIZED) {
i2c_ip6510_uninit(obj->dev);
}
/* Set the GPIO pins */
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
/* Initialize peripheral */
ret = i2c_ip6510_init(obj->dev, SystemCoreClock);
i2c_ip6510_set_speed(obj->dev, I2C_IP6510_SPEED_100KHZ);
i2c_ip6510_set_timeout(obj->dev, 0xFFU);
if (ret != I2C_IP6510_ERR_NONE) {
error("Failed to initialize I2C, error occured in native driver.");
return;
}
}
void i2c_frequency(i2c_t *obj, int hz)
{
/* The peripheral only supports 100k and 400k clock in master mode */
switch (hz) {
case I2C_SPEED_100KHZ:
i2c_ip6510_set_speed(obj->dev, I2C_IP6510_SPEED_100KHZ);
break;
case I2C_SPEED_400KHZ:
i2c_ip6510_set_speed(obj->dev, I2C_IP6510_SPEED_400KHZ);
break;
default:
error("Invalid I2C frequency.");
return;
}
}
void i2c_reset(i2c_t *obj)
{
i2c_ip6510_uninit(obj->dev);
i2c_init(obj, obj->sda, obj->scl);
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
{
enum i2c_ip6510_error_t ret;
/* Shifted 8 bit address is used in upper layer */
address = ((uint32_t)address)>>1;
ret = i2c_ip6510_master_read(obj->dev, (uint16_t)address, (uint8_t*)data,
stop, (uint32_t*)(&length));
if (ret != I2C_IP6510_ERR_NONE) {
return I2C_ERROR_GENERAL;
}
return length;
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
{
enum i2c_ip6510_error_t ret;
/* Shifted 8 bit address is used in upper layer */
address = ((uint32_t)address)>>1;
/* Parameter checking */
if (data == NULL || length == 0) {
ret = i2c_ip6510_monitor_slave(obj->dev, (uint16_t)address);
if (ret != I2C_IP6510_ERR_NONE) {
return I2C_ERROR_NO_SLAVE;
}
return length;
}
ret = i2c_ip6510_master_write(obj->dev, (uint16_t)address, (uint8_t*)data,
stop, (uint32_t*)(&length));
if (ret != I2C_IP6510_ERR_NONE) {
return I2C_ERROR_GENERAL;
}
return length;
}
int i2c_start(i2c_t *obj)
{
/** \note The peripheral does not support building up the transaction by
* instructions. The functionality is achieved with a software
* state machine.
* The i2c transaction is started later, when the address and the
* first data byte is written.
*/
obj->byte_state = BYTE_TRANSFER_STATE_START;
obj->last_address = 0U;
i2c_ip6510_hold_enable(obj->dev);
return I2C_ERROR_NONE;
}
int i2c_stop(i2c_t *obj)
{
/* Both the master and slave api calls this function */
if (i2c_ip6510_get_device_mode(obj->dev) == I2C_IP6510_MASTER_MODE) {
/** \note The peripheral does not support building up the transaction by
* instructions. The functionality is achieved with a software
* state machine.
* STOP condition is generated on hold disable.
*/
i2c_ip6510_hold_disable(obj->dev);
/* If there was only one byte written (the slave address) before calling
* stop, the state machine is in ADDRESS state. Writing just the address
* is equal to a slave monitoring
*/
if (obj->byte_state == BYTE_TRANSFER_STATE_ADDRESS) {
/* Return value is not needed because signalling to the caller is
* not defined
*/
(void)i2c_ip6510_monitor_slave(obj->dev, obj->last_address);
}
obj->byte_state = BYTE_TRANSFER_STATE_NONE;
obj->last_address = 0U;
} else {
/* In slave mode the the I2C controller only writes and reads data from
* the I2C bus. The function just clears the interrupts for
* further adressing detection.
*/
i2c_ip6510_clear_irq(obj->dev, I2C_IP6510_ALL_INTR_MASK);
}
return I2C_ERROR_NONE;
}
int i2c_byte_read(i2c_t *obj, int last)
{
uint8_t read_byte = 0U;
uint32_t slave_read_cntr = 1U;
/* Both the master and slave api calls this function */
if (i2c_ip6510_get_device_mode(obj->dev) == I2C_IP6510_MASTER_MODE) {
/** \note The peripheral does not support building up the transaction by
* instructions. The functionality is achieved with a software
* state machine.
*/
switch (obj->byte_state) {
case BYTE_TRANSFER_STATE_ADDRESS:
obj->byte_state = BYTE_TRANSFER_STATE_DATA;
i2c_ip6510_master_byte_read(
obj->dev, obj->last_address, last, true, &read_byte);
return read_byte;
case BYTE_TRANSFER_STATE_DATA:
i2c_ip6510_master_byte_read(
obj->dev, obj->last_address, last, false, &read_byte);
return read_byte;
case BYTE_TRANSFER_STATE_NONE:
case BYTE_TRANSFER_STATE_START:
default:
/* Reading is invalid in these states */
return I2C_ERROR_GENERAL;
}
} else {
/* In slave mode the driver only writes and reads data from the
* I2C controller, no need to track states.
*/
i2c_ip6510_slave_read(
obj->dev, &read_byte, &slave_read_cntr);
return read_byte;
}
}
int i2c_byte_write(i2c_t *obj, int data)
{
enum i2c_ip6510_error_t ret = I2C_IP6510_ERR_NONE;
uint32_t slave_write_cntr = 1U;
/* Both the master and slave api calls this function */
if (i2c_ip6510_get_device_mode(obj->dev) == I2C_IP6510_MASTER_MODE) {
/** \note The peripheral does not support building up the transaction by
* instructions. The functionality is achieved with a software
* state machine.
*/
switch (obj->byte_state) {
case BYTE_TRANSFER_STATE_NONE:
/* Writing is invalid before start symbol
* BYTE_TRANSFER_ERR_TIMEOUT is the only error code mbed defines,
* this is the only way to signal an error
*/
return BYTE_TRANSFER_ERR_TIMEOUT;
case BYTE_TRANSFER_STATE_START:
obj->byte_state = BYTE_TRANSFER_STATE_ADDRESS;
obj->last_address = ((uint32_t)data)>>1;
return BYTE_TRANSFER_ERR_NONE;
case BYTE_TRANSFER_STATE_ADDRESS:
obj->byte_state = BYTE_TRANSFER_STATE_DATA;
ret = i2c_ip6510_master_byte_write(
obj->dev, obj->last_address, (uint8_t*)&data, true);
break;
case BYTE_TRANSFER_STATE_DATA:
ret = i2c_ip6510_master_byte_write(
obj->dev, obj->last_address, (uint8_t*)&data, false);
break;
default:
return BYTE_TRANSFER_ERR_TIMEOUT;
}
} else {
/* In slave mode the driver only writes and reads data from the
* I2C controller, no need to track states.
*/
ret = i2c_ip6510_slave_write(
obj->dev, (uint8_t*)&data, &slave_write_cntr);
}
if (ret != I2C_IP6510_ERR_NONE) {
/* No need to reset the state machine. The host might try to resend
* the data byte. Also the start and stop functions reset the states.
*/
if (ret == I2C_IP6510_ERR_NACK) {
return BYTE_TRANSFER_ERR_NACK;
}
return BYTE_TRANSFER_ERR_TIMEOUT;
}
return BYTE_TRANSFER_ERR_NONE;
}
#if DEVICE_I2CSLAVE
void i2c_slave_mode(i2c_t *obj, int enable_slave)
{
if (!enable_slave) {
/* Check if master mode is already set */
if (i2c_ip6510_get_device_mode(obj->dev) != I2C_IP6510_MASTER_MODE) {
/* Set Master Mode */
i2c_ip6510_set_master_mode(obj->dev);
}
} else {
/* Check if slave mode is already set */
if (i2c_ip6510_get_device_mode(obj->dev) != I2C_IP6510_SLAVE_MODE) {
/* Set Slave Mode */
i2c_ip6510_set_slave_mode(obj->dev, obj->last_address);
}
}
}
int i2c_slave_receive(i2c_t *obj)
{
uint32_t irq_status = i2c_ip6510_get_irq_status(obj->dev);
enum i2c_ip6510_transf_dir_t dir = i2c_ip6510_get_slave_tranf_dir(obj->dev);
uint32_t transfer_size = i2c_ip6510_get_transfer_size(obj->dev);
if (irq_status & I2C_IP6510_INTR_DATA_MASK) {
if (dir == I2C_IP6510_TRANSMITTER) {
/* Slave is adressed for writing */
return I2C_SLAVE_WRITE_ADDRESS;
}
if ((dir == I2C_IP6510_RECEIVER) && (transfer_size != 0U)) {
/* Slave is adressed for reading */
return I2C_SLAVE_READ_ADDRESS;
}
}
if ((irq_status & I2C_IP6510_INTR_COMP_MASK)
&& (dir == I2C_IP6510_RECEIVER) && (transfer_size != 0U)) {
/* An I2C transfer is complete with less then FIFO_SIZE-2 bytes */
return I2C_SLAVE_READ_ADDRESS;
}
return I2C_SLAVE_NOT_ADDRESSED;
}
int i2c_slave_read(i2c_t *obj, char *data, int length)
{
enum i2c_ip6510_error_t ret;
ret = i2c_ip6510_slave_read(
obj->dev, (uint8_t*)data, (uint32_t*)&length);
i2c_ip6510_clear_irq(obj->dev, I2C_IP6510_ALL_INTR_MASK);
if (ret != I2C_IP6510_ERR_NONE) {
return 0;
}
return length;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length)
{
enum i2c_ip6510_error_t ret;
ret = i2c_ip6510_slave_write(
obj->dev, (uint8_t*)data, (uint32_t*)&length);
i2c_ip6510_clear_irq(obj->dev, I2C_IP6510_ALL_INTR_MASK);
if (ret != I2C_IP6510_ERR_NONE) {
return 0;
}
return length;
}
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
{
/* Shifted 8 bit address is used in upper layer */
i2c_ip6510_set_slave_mode(obj->dev, ((uint16_t)address)>>1);
obj->last_address = address>>1;
}
const PinMap *i2c_slave_sda_pinmap()
{
return PinMap_I2C_SDA;
}
const PinMap *i2c_slave_scl_pinmap()
{
return PinMap_I2C_SCL;
}
#endif
const PinMap *i2c_master_sda_pinmap()
{
return PinMap_I2C_SDA;
}
const PinMap *i2c_master_scl_pinmap()
{
return PinMap_I2C_SCL;
}

View File

@ -0,0 +1,91 @@
/* mbed Microcontroller Library
* Copyright (c) 2019 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Low-power elapsed time measure and interval ticker,
* using General Purpose Timer \ref timer_gp_dev_t.
*/
#include "cmsis.h"
#include "device_cfg.h"
#include "timer_gp_drv.h"
#include "lp_ticker_api.h"
/* Check if the module configuration is right. These definitions
are usually located in device_cfg.h */
#ifndef GP_TIMER_DEV
#error "Configuration macro GP_TIMER_DEV is undefined!"
#endif
void lp_ticker_init(void)
{
timer_gp_init(&GP_TIMER_DEV);
NVIC_EnableIRQ(GP_TIMER_ALARM0_IRQ);
timer_gp_interrupt_disable(&GP_TIMER_DEV, GP_TIMER_ALARM_NR);
}
void lp_ticker_free(void)
{
/* This function should stop the ticker from counting, but GP Timer cannot
* be stopped.
*/
timer_gp_interrupt_disable(&GP_TIMER_DEV, GP_TIMER_ALARM_NR);
}
uint32_t lp_ticker_read(void)
{
return timer_gp_get_counter(&GP_TIMER_DEV);
}
void lp_ticker_set_interrupt(timestamp_t timestamp)
{
timer_gp_set_alarm_value(&GP_TIMER_DEV, GP_TIMER_ALARM_NR, (uint32_t)timestamp);
timer_gp_interrupt_enable(&GP_TIMER_DEV, GP_TIMER_ALARM_NR);
}
void lp_ticker_disable_interrupt(void)
{
timer_gp_interrupt_disable(&GP_TIMER_DEV, GP_TIMER_ALARM_NR);
}
void lp_ticker_clear_interrupt(void)
{
timer_gp_interrupt_clear(&GP_TIMER_DEV, GP_TIMER_ALARM_NR);
}
void lp_ticker_fire_interrupt(void)
{
NVIC_SetPendingIRQ(GP_TIMER_ALARM0_IRQ);
}
const ticker_info_t* lp_ticker_get_info(void)
{
static const ticker_info_t info = {
GP_TIMER_FREQ_HZ,
GP_TIMER_BIT_WIDTH
};
return &info;
}
#ifndef GP_TIMER_IRQ0_HANDLER
#error "GP_TIMER_IRQ0_HANDLER should be defined, check device_cfg.h!"
#endif
void GP_TIMER_IRQ0_HANDLER(void)
{
lp_ticker_irq_handler();
}

View File

@ -0,0 +1,139 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2019 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_error.h"
#include "mbed_serial_platform.h"
#include "serial_api.h"
#define UART_DEVICES_NUMBER 2
struct uart_irq_t uart_irq[UART_DEVICES_NUMBER];
const PinMap PinMap_UART_TX[] = {
{UART0_TX, UART_0, ALTERNATE_FUNC_1},
{UART1_TX, UART_1, PRIMARY_FUNC},
{NC, NC, 0}
};
const PinMap PinMap_UART_RX[] = {
{UART0_RX, UART_0, ALTERNATE_FUNC_1},
{UART1_RX, UART_1, PRIMARY_FUNC},
{NC, NC, 0}
};
const PinMap *serial_tx_pinmap()
{
return PinMap_UART_TX;
}
const PinMap *serial_rx_pinmap()
{
return PinMap_UART_RX;
}
#ifdef UART0_PL011_DEV
#ifndef uart0_tx_irq_handler
#error "uart0_tx_irq_handler should be defined, check device_cfg.h!"
#endif
void uart0_tx_irq_handler(void)
{
uart_pl011_clear_intr(&UART0_PL011_DEV, UART_PL011_TX_INTR_MASK);
if(uart_irq[UART_0].handler != 0) {
uart_irq[UART_0].handler(uart_irq[UART_0].id, TxIrq);
}
}
#ifndef uart0_rx_irq_handler
#error "uart0_rx_irq_handler should be defined, check device_cfg.h!"
#endif
void uart0_rx_irq_handler(void)
{
uart_pl011_clear_intr(&UART0_PL011_DEV, UART_PL011_RX_INTR_MASK);
if(uart_irq[UART_0].handler != 0) {
uart_irq[UART_0].handler(uart_irq[UART_0].id, RxIrq);
}
}
#ifndef uart0_rx_timeout_irq_handler
#error "uart0_rx_timeout_irq_handler should be defined, check device_cfg.h!"
#endif
void uart0_rx_timeout_irq_handler(void)
{
if(uart_irq[UART_0].handler != 0) {
uart_irq[UART_0].handler(uart_irq[UART_0].id, RxIrq);
}
}
#endif
#ifdef UART1_PL011_DEV
#ifndef uart1_tx_irq_handler
#error "uart1_tx_irq_handler should be defined, check device_cfg.h!"
#endif
void uart1_tx_irq_handler(void)
{
uart_pl011_clear_intr(&UART1_PL011_DEV, UART_PL011_TX_INTR_MASK);
if(uart_irq[UART_1].handler != 0) {
uart_irq[UART_1].handler(uart_irq[UART_1].id, TxIrq);
}
}
#ifndef uart1_rx_irq_handler
#error "uart1_rx_irq_handler should be defined, check device_cfg.h!"
#endif
void uart1_rx_irq_handler(void)
{
uart_pl011_clear_intr(&UART1_PL011_DEV, UART_PL011_RX_INTR_MASK);
if(uart_irq[UART_1].handler != 0) {
uart_irq[UART_1].handler(uart_irq[UART_1].id, RxIrq);
}
}
#ifndef uart1_rx_timeout_irq_handler
#error "uart1_rx_timeout_irq_handler should be defined, check device_cfg.h!"
#endif
void uart1_rx_timeout_irq_handler(void)
{
if(uart_irq[UART_1].handler != 0) {
uart_irq[UART_1].handler(uart_irq[UART_1].id, RxIrq);
}
}
#endif
void mbed_uart_platform_init(serial_t *obj, UARTName uart)
{
switch (uart) {
#ifdef UART0_PL011_DEV
case UART_0:
obj->uart_dev = &UART0_PL011_DEV;
obj->tx_irq = UART0_Tx_IRQn;
obj->rx_irq = UART0_Rx_IRQn;
obj->rx_timeout_irq = UART0_RxTimeout_IRQn;
break;
#endif
#ifdef UART1_PL011_DEV
case UART_1:
obj->uart_dev = &UART1_PL011_DEV;
obj->tx_irq = UART1_Tx_IRQn;
obj->rx_irq = UART1_Rx_IRQn;
obj->rx_timeout_irq = UART1_RxTimeout_IRQn;
break;
#endif
default:
error("serial_init: No uart selected");
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2018-2019 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MBED_SERIAL_PLATFORM_H__
#define __MBED_SERIAL_PLATFORM_H__
#include "serial_api.h"
#ifdef __cplusplus
extern "C" {
#endif
struct uart_irq_t {
uart_irq_handler handler;
uint32_t id;
};
/* Handlers registered */
extern struct uart_irq_t uart_irq[];
void mbed_uart_platform_init(serial_t *obj, UARTName uart);
#ifdef __cplusplus
}
#endif
#endif /* __SERIAL_PLATFORM_H__ */

Binary file not shown.

View File

@ -0,0 +1,76 @@
/* mbed Microcontroller Library
* Copyright (c) 2019-2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_OBJECTS_H
#define MBED_OBJECTS_H
#include "cmsis.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#include "platform_description.h"
#include "device_definition.h"
#include "gpio_object.h"
#ifdef __cplusplus
extern "C" {
#endif
struct serial_s {
struct uart_pl011_dev_t *uart_dev;
UARTName uart_index; /* UART device number */
IRQn_Type tx_irq;
IRQn_Type rx_irq;
IRQn_Type rx_timeout_irq;
};
#if DEVICE_FLASH
struct flash_s {
uint8_t dummy;
};
#endif // DEVICE_FLASH
#if DEVICE_TRNG
struct trng_s {
/* nothing to be stored for now */
void *dummy;
};
#endif // DEVICE_TRNG
#if DEVICE_I2C || DEVICE_I2CSLAVE
enum byte_transfer_states {
BYTE_TRANSFER_STATE_NONE = 0,
BYTE_TRANSFER_STATE_START,
BYTE_TRANSFER_STATE_ADDRESS,
BYTE_TRANSFER_STATE_DATA,
};
struct i2c_s {
struct i2c_ip6510_dev_t *dev;
uint16_t last_address;
PinName sda;
PinName scl;
enum byte_transfer_states byte_state;
};
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,239 @@
/*
* Copyright (c) 2018-2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __FLASH_LAYOUT_H__
#define __FLASH_LAYOUT_H__
/* Flash layout on Musca-S1 with BL2(multiple image boot, boot from MRAM):
* 0x0A00_0000 BL2 - MCUBoot(128 KB)
* 0x0A02_0000 Secure image primary (320 KB)
* 0x0A07_0000 Non-secure image primary (512 KB)
* 0x0A0F_0000 Secure image secondary (320 KB)
* 0x0A14_0000 Non-secure image secondary (512 KB)
* 0x0A1C_0000 Scratch Area (16 KB)
* 0x0A1C_4000 Secure Storage Area (20 KB)
* 0x0A1C_9000 Internal Trusted Storage Area (16 KB)
* 0x0A1C_D000 NV counters area (4 KB)
* 0x0A1C_E000 Unused
*
* Flash layout on Musca-S1 with BL2(single image boot):
* 0x0A00_0000 BL2 - MCUBoot(128 KB)
* 0x0A02_0000 Primary image area (896 KB):
* 0x0A02_0000 Secure image primary (384 KB)
* 0x0A08_0000 Non-secure image primary (512 KB)
* 0x0A10_0000 Secondary image area (896 KB):
* 0x0A10_0000 Secure image secondary (384 KB)
* 0x0A16_0000 Non-secure image secondary (512 KB)
* 0x0A1E_0000 Secure Storage Area (20 KB)
* 0x0A1E_5000 Internal Trusted Storage Area (16 KB)
* 0x0A1E_9000 NV counters area (4 KB)
* 0x0A1E_A000 TF-M key area (256 bytes) This area is referred to in
* /lib/ext/cryptocell-312-runtime/shared/hw/include/musca_s1/ \
* dx_reg_base_host.h Do not change one without changing the other.
* 0x0A1E_A100 Unused
*
* Flash layout on Musca-S1 without BL2:
* 0x0A00_0000 Secure image
* 0x0A07_0000 Non-secure image
*/
/* This header file is included from linker scatter file as well, where only a
* limited C constructs are allowed. Therefore it is not possible to include
* here the platform_base_address.h to access flash related defines. To resolve
* this some of the values are redefined here with different names, these are
* marked with comment.
*/
/* Size of a Secure and of a Non-secure image */
#define FLASH_S_PARTITION_SIZE (0x60000) /* S partition: 384 KB */
#define FLASH_NS_PARTITION_SIZE (0x80000) /* NS partition: 512 KB */
#define FLASH_MAX_PARTITION_SIZE ((FLASH_S_PARTITION_SIZE > \
FLASH_NS_PARTITION_SIZE) ? \
FLASH_S_PARTITION_SIZE : \
FLASH_NS_PARTITION_SIZE)
/* Sector size of the flash hardware */
#define FLASH_AREA_IMAGE_SECTOR_SIZE (0x1000) /* 4KB */
#define FLASH_TOTAL_SIZE (0x200000) /* MRAM size 2MB */
/* Flash layout info for BL2 bootloader */
#define FLASH_BASE_ADDRESS (0x1A000000) /* MRAM base address */
/* Offset and size definitions of the flash partitions that are handled by the
* bootloader. The image swapping is done between IMAGE_PRIMARY and
* IMAGE_SECONDARY, SCRATCH is used as a temporary storage during image
* swapping.
*/
#define FLASH_AREA_BL2_OFFSET (0x0)
#define FLASH_AREA_BL2_SIZE (0x20000) /* 128KB */
#if !defined(MCUBOOT_IMAGE_NUMBER) || (MCUBOOT_IMAGE_NUMBER == 1)
/* Secure + Non-secure image primary slot */
#define FLASH_AREA_0_ID (1)
#define FLASH_AREA_0_OFFSET (FLASH_AREA_BL2_OFFSET + FLASH_AREA_BL2_SIZE)
#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE + \
FLASH_NS_PARTITION_SIZE)
/* Secure + Non-secure secondary slot */
#define FLASH_AREA_2_ID (FLASH_AREA_0_ID + 1)
#define FLASH_AREA_2_OFFSET (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE)
#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE + \
FLASH_NS_PARTITION_SIZE)
/* Scratch area */
#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_2_ID + 1)
#define FLASH_AREA_SCRATCH_OFFSET (FLASH_AREA_2_OFFSET + FLASH_AREA_2_SIZE)
#define FLASH_AREA_SCRATCH_SIZE (4 * FLASH_AREA_IMAGE_SECTOR_SIZE)
/* The maximum number of status entries supported by the bootloader. */
#define MCUBOOT_STATUS_MAX_ENTRIES ((FLASH_S_PARTITION_SIZE + \
FLASH_NS_PARTITION_SIZE) / \
FLASH_AREA_SCRATCH_SIZE)
/* Maximum number of image sectors supported by the bootloader. */
#define MCUBOOT_MAX_IMG_SECTORS ((FLASH_S_PARTITION_SIZE + \
FLASH_NS_PARTITION_SIZE) / \
FLASH_AREA_IMAGE_SECTOR_SIZE)
#elif (MCUBOOT_IMAGE_NUMBER == 2)
/* Secure image primary slot */
#define FLASH_AREA_0_ID (1)
#define FLASH_AREA_0_OFFSET (FLASH_AREA_BL2_OFFSET + FLASH_AREA_BL2_SIZE)
#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE)
/* Non-secure image primary slot */
#define FLASH_AREA_1_ID (FLASH_AREA_0_ID + 1)
#define FLASH_AREA_1_OFFSET (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE)
#define FLASH_AREA_1_SIZE (FLASH_NS_PARTITION_SIZE)
/* Secure image secondary slot */
#define FLASH_AREA_2_ID (FLASH_AREA_1_ID + 1)
#define FLASH_AREA_2_OFFSET (FLASH_AREA_1_OFFSET + FLASH_AREA_1_SIZE)
#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE)
/* Non-secure image secondary slot */
#define FLASH_AREA_3_ID (FLASH_AREA_2_ID + 1)
#define FLASH_AREA_3_OFFSET (FLASH_AREA_2_OFFSET + FLASH_AREA_2_SIZE)
#define FLASH_AREA_3_SIZE (FLASH_NS_PARTITION_SIZE)
/* Scratch area */
#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_3_ID + 1)
#define FLASH_AREA_SCRATCH_OFFSET (FLASH_AREA_3_OFFSET + FLASH_AREA_3_SIZE)
#define FLASH_AREA_SCRATCH_SIZE (4 * FLASH_AREA_IMAGE_SECTOR_SIZE)
/* The maximum number of status entries supported by the bootloader. */
#define MCUBOOT_STATUS_MAX_ENTRIES (FLASH_MAX_PARTITION_SIZE / \
FLASH_AREA_SCRATCH_SIZE)
/* Maximum number of image sectors supported by the bootloader. */
#define MCUBOOT_MAX_IMG_SECTORS (FLASH_MAX_PARTITION_SIZE / \
FLASH_AREA_IMAGE_SECTOR_SIZE)
#else /* MCUBOOT_IMAGE_NUMBER > 2 */
#error "Only MCUBOOT_IMAGE_NUMBER 1 and 2 are supported!"
#endif /* MCUBOOT_IMAGE_NUMBER */
/* Note: FLASH_SST_AREA_OFFSET, FLASH_ITS_AREA_OFFSET and
* FLASH_NV_COUNTERS_AREA_OFFSET point to offsets in flash, but reads and writes
* to these addresses are redirected to Code SRAM by Driver_Flash.c.
*/
#define FLASH_SST_AREA_OFFSET (FLASH_AREA_SCRATCH_OFFSET + \
FLASH_AREA_SCRATCH_SIZE)
#define FLASH_SST_AREA_SIZE (0x5000) /* 20 KB */
/* Internal Trusted Storage (ITS) Service definitions */
#define FLASH_ITS_AREA_OFFSET (FLASH_SST_AREA_OFFSET + \
FLASH_SST_AREA_SIZE)
#define FLASH_ITS_AREA_SIZE (0x4000) /* 16 KB */
/* NV Counters definitions */
#define FLASH_NV_COUNTERS_AREA_OFFSET (FLASH_ITS_AREA_OFFSET + \
FLASH_ITS_AREA_SIZE)
#define FLASH_NV_COUNTERS_AREA_SIZE (FLASH_AREA_IMAGE_SECTOR_SIZE)
/* TF-M crypto key area definitions */
#define FLASH_TFM_CRYPTO_KEY_AREA_OFFSET (FLASH_NV_COUNTERS_AREA_OFFSET + \
FLASH_NV_COUNTERS_AREA_SIZE)
#define FLASH_TFM_CRYPTO_KEY_AREA_SIZE (0x100)
/* Offset and size definition in flash area used by assemble.py */
#define SECURE_IMAGE_OFFSET (0x0)
#define SECURE_IMAGE_MAX_SIZE FLASH_S_PARTITION_SIZE
#define NON_SECURE_IMAGE_OFFSET (SECURE_IMAGE_OFFSET + \
SECURE_IMAGE_MAX_SIZE)
#define NON_SECURE_IMAGE_MAX_SIZE FLASH_NS_PARTITION_SIZE
/* Flash device name used by BL2
* Name is defined in flash driver file: Driver_Flash_MRAM.c
*/
#define FLASH_DEV_NAME Driver_FLASH0
/* Secure Storage (SST) Service definitions
* Note: Further documentation of these definitions can be found in the
* TF-M SST Integration Guide.
*/
#define SST_FLASH_DEV_NAME Driver_FLASH0
/* In this target the CMSIS driver requires only the offset from the base
* address instead of the full memory address.
*/
#define SST_FLASH_AREA_ADDR FLASH_SST_AREA_OFFSET
/* Dedicated flash area for SST */
#define SST_FLASH_AREA_SIZE FLASH_SST_AREA_SIZE
#define SST_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE
/* Number of SST_SECTOR_SIZE per block */
#define SST_SECTORS_PER_BLOCK (0x1)
/* Specifies the smallest flash programmable unit in bytes */
#define SST_FLASH_PROGRAM_UNIT (0x1)
/* The maximum asset size to be stored in the SST area */
#define SST_MAX_ASSET_SIZE (2048)
/* The maximum number of assets to be stored in the SST area */
#define SST_NUM_ASSETS (10)
/* Internal Trusted Storage (ITS) Service definitions
* Note: Further documentation of these definitions can be found in the
* TF-M ITS Integration Guide. The ITS should be in the internal flash, but is
* allocated in the external flash just for development platforms that don't
* have internal flash available.
*/
#define ITS_FLASH_DEV_NAME Driver_FLASH0
/* In this target the CMSIS driver requires only the offset from the base
* address instead of the full memory address.
*/
#define ITS_FLASH_AREA_ADDR FLASH_ITS_AREA_OFFSET
/* Dedicated flash area for ITS */
#define ITS_FLASH_AREA_SIZE FLASH_ITS_AREA_SIZE
#define ITS_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE
/* Number of ITS_SECTOR_SIZE per block */
#define ITS_SECTORS_PER_BLOCK (0x1)
/* Specifies the smallest flash programmable unit in bytes */
#define ITS_FLASH_PROGRAM_UNIT (0x1)
/* The maximum asset size to be stored in the ITS area */
#define ITS_MAX_ASSET_SIZE (512)
/* The maximum number of assets to be stored in the ITS area */
#define ITS_NUM_ASSETS (10)
/* NV Counters definitions */
#define TFM_NV_COUNTERS_AREA_ADDR FLASH_NV_COUNTERS_AREA_OFFSET
#define TFM_NV_COUNTERS_AREA_SIZE (0x18) /* 24 Bytes */
#define TFM_NV_COUNTERS_SECTOR_ADDR FLASH_NV_COUNTERS_AREA_OFFSET
#define TFM_NV_COUNTERS_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE
/* Use MRAM to store Code data */
#define S_ROM_ALIAS_BASE (0x1A000000)
#define NS_ROM_ALIAS_BASE (0x0A000000)
/* FIXME: Use SRAM2 memory to store RW data */
#define S_RAM_ALIAS_BASE (0x30000000)
#define NS_RAM_ALIAS_BASE (0x20000000)
#define TOTAL_ROM_SIZE FLASH_TOTAL_SIZE
#define TOTAL_RAM_SIZE (0x80000) /* 512 KB */
#endif /* __FLASH_LAYOUT_H__ */

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
enum image_attributes {
RE_SECURE_IMAGE_OFFSET = (0x0),
RE_SECURE_IMAGE_MAX_SIZE = (0x60000),
RE_NON_SECURE_IMAGE_OFFSET = ((0x0) + (0x60000)),
RE_NON_SECURE_IMAGE_MAX_SIZE = (0x80000),
RE_SIGN_BIN_SIZE = ((0x80000)),
};

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
enum image_attributes {
RE_SECURE_IMAGE_OFFSET = (0x0),
RE_SECURE_IMAGE_MAX_SIZE = (0x60000),
RE_NON_SECURE_IMAGE_OFFSET = ((0x0) + (0x60000)),
RE_NON_SECURE_IMAGE_MAX_SIZE = (0x80000),
RE_SIGN_BIN_SIZE = ((0x60000)),
};

View File

@ -0,0 +1,160 @@
/*
* Copyright (c) 2017-2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __REGION_DEFS_H__
#define __REGION_DEFS_H__
#include "flash_layout.h"
#define BL2_HEAP_SIZE (0x0001000)
#define BL2_MSP_STACK_SIZE (0x0001800)
#define S_HEAP_SIZE (0x0001000)
#define S_MSP_STACK_SIZE_INIT (0x0000400)
#define S_MSP_STACK_SIZE (0x0000800)
#define S_PSP_STACK_SIZE (0x0000800)
#define NS_HEAP_SIZE (0x0001000)
#define NS_MSP_STACK_SIZE (0x00000A0)
#define NS_PSP_STACK_SIZE (0x0000140)
/* This size of buffer is big enough to store an attestation
* token produced by initial attestation service
*/
#define PSA_INITIAL_ATTEST_TOKEN_MAX_SIZE (0x250)
/*
* MRAM MPC granularity is 4 KB on Musca. Alignment
* of partitions is defined in accordance with this constraint.
*/
#ifdef BL2
#ifndef LINK_TO_SECONDARY_PARTITION
#define S_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_0_OFFSET)
#define S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_2_OFFSET)
#else
#define S_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_2_OFFSET)
#define S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_0_OFFSET)
#endif /* !LINK_TO_SECONDARY_PARTITION */
#else
#define S_IMAGE_PRIMARY_PARTITION_OFFSET (0x0)
#endif /* BL2 */
#ifndef LINK_TO_SECONDARY_PARTITION
#define NS_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_0_OFFSET \
+ FLASH_S_PARTITION_SIZE)
#else
#define NS_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_2_OFFSET \
+ FLASH_S_PARTITION_SIZE)
#endif /* !LINK_TO_SECONDARY_PARTITION */
/* Boot partition structure if MCUBoot is used:
* 0x0_0000 Bootloader header
* 0x0_0400 Image area
* 0x1_FC00 Trailer
*/
/* IMAGE_CODE_SIZE is the space available for the software binary image.
* It is less than the FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE
* because we reserve space for the image header and trailer introduced
* by the bootloader.
*/
#ifdef BL2
#define BL2_HEADER_SIZE (0x400) /* 1 KB */
#define BL2_TRAILER_SIZE (0x800) /* 2 KB */
#else
/* No header if no bootloader, but keep IMAGE_CODE_SIZE the same */
#define BL2_HEADER_SIZE (0x0)
#define BL2_TRAILER_SIZE (0xC00)
#endif /* BL2 */
#define IMAGE_S_CODE_SIZE \
(FLASH_S_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE)
#define IMAGE_NS_CODE_SIZE \
(FLASH_NS_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE)
#define CMSE_VENEER_REGION_SIZE (0x340)
/* Alias definitions for secure and non-secure areas*/
#define S_ROM_ALIAS(x) (S_ROM_ALIAS_BASE + (x))
#define NS_ROM_ALIAS(x) (NS_ROM_ALIAS_BASE + (x))
#define S_RAM_ALIAS(x) (S_RAM_ALIAS_BASE + (x))
#define NS_RAM_ALIAS(x) (NS_RAM_ALIAS_BASE + (x))
/* Secure regions */
#define S_IMAGE_PRIMARY_AREA_OFFSET \
(S_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
#define S_CODE_START (S_ROM_ALIAS(S_IMAGE_PRIMARY_AREA_OFFSET))
#define S_CODE_SIZE (IMAGE_S_CODE_SIZE - CMSE_VENEER_REGION_SIZE)
#define S_CODE_LIMIT (S_CODE_START + S_CODE_SIZE - 1)
#define S_DATA_START (S_RAM_ALIAS(0x0))
#define S_DATA_SIZE (TOTAL_RAM_SIZE / 2)
#define S_DATA_LIMIT (S_DATA_START + S_DATA_SIZE - 1)
/* CMSE Veneers region */
#define CMSE_VENEER_REGION_START (S_CODE_LIMIT + 1)
/* Non-secure regions */
#define NS_IMAGE_PRIMARY_AREA_OFFSET \
(NS_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
#define NS_CODE_START (NS_ROM_ALIAS(NS_IMAGE_PRIMARY_AREA_OFFSET))
#define NS_CODE_SIZE (IMAGE_NS_CODE_SIZE)
#define NS_CODE_LIMIT (NS_CODE_START + NS_CODE_SIZE - 1)
#define NS_DATA_START (NS_RAM_ALIAS(TOTAL_RAM_SIZE / 2))
#define NS_DATA_SIZE (TOTAL_RAM_SIZE / 2)
#define NS_DATA_LIMIT (NS_DATA_START + NS_DATA_SIZE - 1)
/* NS partition information is used for MPC and SAU configuration */
#define NS_PARTITION_START \
(NS_ROM_ALIAS(NS_IMAGE_PRIMARY_PARTITION_OFFSET))
#define NS_PARTITION_SIZE (FLASH_NS_PARTITION_SIZE)
/* Secondary partition for new images in case of firmware upgrade */
#define SECONDARY_PARTITION_START \
(NS_ROM_ALIAS(S_IMAGE_SECONDARY_PARTITION_OFFSET))
#define SECONDARY_PARTITION_SIZE (FLASH_S_PARTITION_SIZE + \
FLASH_NS_PARTITION_SIZE)
/* Code SRAM area */
#define TOTAL_CODE_SRAM_SIZE (0x00080000) /* 512 KB */
#define S_CODE_SRAM_ALIAS_BASE (0x1A400000)
#define NS_CODE_SRAM_ALIAS_BASE (0x0A400000)
#ifdef BL2
/* Bootloader regions */
#define BL2_CODE_START (S_ROM_ALIAS(FLASH_AREA_BL2_OFFSET))
#define BL2_CODE_SIZE (FLASH_AREA_BL2_SIZE)
#define BL2_CODE_LIMIT (BL2_CODE_START + BL2_CODE_SIZE - 1)
#define BL2_DATA_START (S_RAM_ALIAS(0x0))
#define BL2_DATA_SIZE (TOTAL_RAM_SIZE)
#define BL2_DATA_LIMIT (BL2_DATA_START + BL2_DATA_SIZE - 1)
#endif /* BL2 */
/* Shared data area between bootloader and runtime firmware.
* Shared data area is allocated at the beginning of the RAM, it is overlapping
* with TF-M Secure code's MSP stack
*/
#define BOOT_TFM_SHARED_DATA_BASE S_RAM_ALIAS_BASE
#define BOOT_TFM_SHARED_DATA_SIZE (0x400)
#define BOOT_TFM_SHARED_DATA_LIMIT (BOOT_TFM_SHARED_DATA_BASE + \
BOOT_TFM_SHARED_DATA_SIZE - 1)
#endif /* __REGION_DEFS_H__ */

View File

@ -0,0 +1,123 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This file implements APIS defined in hal/pinmap.h
*
* Pin functions are not available in interrupt context, because the
* NS side is only allowed to call TF-M secure functions (veneers) from
* the NS Thread mode.
*
*/
#include "mbed_assert.h"
#include "mbed_error.h"
#include "device_definition.h"
#include "objects.h"
#include "pinmap.h"
#include "musca_s1_scc_drv.h"
#include "tfm_ioctl_api.h"
#if DEVICE_I2C || DEVICE_I2CSLAVE
const PinMap PinMap_I2C_SDA[] = {
{I2C0_SDA, I2C_0, ALTERNATE_FUNC_1},
{I2C1_SDA, I2C_1, PRIMARY_FUNC},
{NC, NC, 0}
};
const PinMap PinMap_I2C_SCL[] = {
{I2C0_SCL, I2C_0, ALTERNATE_FUNC_1},
{I2C1_SCL, I2C_1, PRIMARY_FUNC},
{NC, NC, 0}
};
#endif // DEVICE_I2C || DEVICE_I2CSLAVE
/**
* \brief Translates between different pin mode enums
*
* \param[in] mode Pin mode to translate \ref PinMode
*
* \return Translated pin mode \ref pinmode_select_t
*/
static enum pinmode_select_t translate_pinmode(PinMode mode)
{
switch (mode) {
case PullNone:
return PINMODE_NONE;
case PullDown:
return PINMODE_PULL_DOWN;
case PullUp:
return PINMODE_PULL_UP;
default:
return PINMODE_NONE;
}
}
/**
* \brief Configures the GPIO pin and sets the alternate function
*
* \param[in] pin GPIO pin number \ref PinName
* \param[in] function Alternate function to set \ref PinFunction
*/
void pin_function(PinName pin, int function)
{
enum gpio_altfunc_t flags;
uint32_t result = 0;
enum tfm_platform_err_t ret = TFM_PLATFORM_ERR_SUCCESS;
MBED_ASSERT(pin != NC);
switch (function) {
case PRIMARY_FUNC:
flags = GPIO_MAIN_FUNC;
break;
case ALTERNATE_FUNC_1:
flags = GPIO_ALTFUNC_1;
break;
case ALTERNATE_FUNC_2:
flags = GPIO_ALTFUNC_2;
break;
default:
return;
}
ret = tfm_platform_set_pin_alt_func(flags, (1u<<pin), &result);
if (ret != TFM_PLATFORM_ERR_SUCCESS) {
error("tfm_platform_set_pin_alt_func failed for pin %d", pin);
}
}
/**
* \brief Sets pin mode for the given GPIO pin
*
* \param[in] pin GPIO pin number \ref PinName
* \param[in] mode Pin mode to set \ref PinMode
*/
void pin_mode(PinName pin, PinMode mode)
{
uint32_t result = 0;
enum tfm_platform_err_t ret = TFM_PLATFORM_ERR_SUCCESS;
MBED_ASSERT(pin != NC);
ret = tfm_platform_set_pin_mode((1u<<pin), translate_pinmode(mode),
&result);
if (ret != TFM_PLATFORM_ERR_SUCCESS) {
error("tfm_platform_set_pin_mode failed for pin %d", pin);
}
}

Binary file not shown.

View File

@ -0,0 +1,217 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2019 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include "mbed_error.h"
#include "objects.h"
#include "pinmap.h"
#include "serial_api.h"
#include "mbed_serial_platform.h"
#define STDIO_UART_NOT_INITED 0
#define STDIO_UART_INITED 1
extern const PinMap PinMap_UART_TX[];
extern const PinMap PinMap_UART_RX[];
/* Global variables needed for mbed */
int stdio_uart_inited = STDIO_UART_NOT_INITED;
serial_t stdio_uart;
void serial_init(serial_t *obj, PinName tx, PinName rx)
{
/* Determine the UART to use */
UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
if (uart == (UARTName)NC) {
error("Serial pinout mapping failed");
}
mbed_uart_platform_init(obj, uart);
obj->uart_index = uart;
/* Pinout the chosen uart */
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
uart_pl011_init(obj->uart_dev, SystemCoreClock);
uart_pl011_set_baudrate(obj->uart_dev,
MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
uart_pl011_enable(obj->uart_dev);
if (uart == STDIO_UART) {
stdio_uart_inited = STDIO_UART_INITED;
memcpy(&stdio_uart, obj, sizeof(serial_t));
}
}
void serial_free(serial_t *obj)
{
uart_pl011_uninit(obj->uart_dev);
}
void serial_baud(serial_t *obj, int baudrate)
{
if(uart_pl011_set_baudrate(obj->uart_dev,baudrate) != UART_PL011_ERR_NONE) {
error("serial_baud: invalid baudrate");
}
}
void serial_format(serial_t *obj, int data_bits, SerialParity parity,
int stop_bits)
{
enum uart_pl011_wlen_t uart_word_len = UART_PL011_WLEN_8;
enum uart_pl011_parity_t uart_parity = UART_PL011_PARITY_DISABLED;
enum uart_pl011_stopbit_t uart_stop_bits = UART_PL011_STOPBIT_1;
switch (data_bits) {
case 5:
uart_word_len = UART_PL011_WLEN_5;
break;
case 6:
uart_word_len = UART_PL011_WLEN_6;
break;
case 7:
uart_word_len = UART_PL011_WLEN_7;
break;
case 8:
uart_word_len = UART_PL011_WLEN_8;
break;
default:
error("serial_format: unexpected data bits");
}
switch (parity) {
case ParityNone:
uart_parity = UART_PL011_PARITY_DISABLED;
break;
case ParityOdd:
uart_parity = UART_PL011_PARITY_ODD;
break;
case ParityEven:
uart_parity = UART_PL011_PARITY_EVEN;
break;
case ParityForced1:
uart_parity = UART_PL011_PARITY_STICKY_ONE;
break;
case ParityForced0:
uart_parity = UART_PL011_PARITY_STICKY_ZERO;
break;
default:
error("serial_format: unexpected parity");
}
switch (stop_bits) {
case 1:
uart_stop_bits = UART_PL011_STOPBIT_1;
break;
case 2:
uart_stop_bits = UART_PL011_STOPBIT_2;
break;
default:
error("serial_format: unexpected stop bit");
}
(void)uart_pl011_set_format(obj->uart_dev,
uart_word_len, uart_parity, uart_stop_bits);
}
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
{
uart_irq[obj->uart_index].handler = handler;
uart_irq[obj->uart_index].id = id;
}
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
{
switch(irq) {
case RxIrq:
if (enable) {
NVIC_EnableIRQ(obj->rx_irq);
uart_pl011_enable_intr(obj->uart_dev, UART_PL011_RX_INTR_MASK);
NVIC_EnableIRQ(obj->rx_timeout_irq);
uart_pl011_enable_intr(obj->uart_dev, UART_PL011_RT_INTR_MASK);
} else {
uart_pl011_disable_intr(obj->uart_dev, UART_PL011_RX_INTR_MASK);
NVIC_DisableIRQ(obj->rx_irq);
uart_pl011_disable_intr(obj->uart_dev, UART_PL011_RT_INTR_MASK);
NVIC_DisableIRQ(obj->rx_timeout_irq);
}
break;
case TxIrq:
if (enable) {
NVIC_EnableIRQ(obj->tx_irq);
uart_pl011_enable_intr(obj->uart_dev, UART_PL011_TX_INTR_MASK);
} else {
uart_pl011_disable_intr(obj->uart_dev, UART_PL011_TX_INTR_MASK);
NVIC_DisableIRQ(obj->tx_irq);
}
break;
default : return;
}
}
int serial_readable(serial_t *obj)
{
return (int)uart_pl011_is_readable(obj->uart_dev);
}
int serial_writable(serial_t *obj)
{
return (int)uart_pl011_is_writable(obj->uart_dev);
}
int serial_getc(serial_t *obj)
{
uint8_t byte = 0;
while(!uart_pl011_is_readable(obj->uart_dev));
(void)uart_pl011_read(obj->uart_dev, &byte);
return byte;
}
void serial_putc(serial_t *obj, int c)
{
while(!uart_pl011_is_writable(obj->uart_dev));
uart_pl011_write(obj->uart_dev, (uint8_t)c);
}
void serial_clear(serial_t *obj)
{
uart_pl011_write(obj->uart_dev, (uint8_t)0);
}
void serial_pinout_tx(PinName tx)
{
pinmap_pinout(tx, PinMap_UART_TX);
}
void serial_break_set(serial_t *obj)
{
uart_pl011_enable_break(obj->uart_dev);
}
void serial_break_clear(serial_t *obj)
{
uart_pl011_disable_break(obj->uart_dev);
}
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow,
PinName txflow)
{
error("serial_set_flow_control: Flow control is not supported in MUSCA");
}

View File

@ -0,0 +1,48 @@
/* mbed Microcontroller Library
* Copyright (c) 2019-2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "device_cfg.h"
#include "sleep_api.h"
#include "timer_cmsdk_drv.h"
#if DEVICE_SLEEP
void hal_sleep(void)
{
__WFI();
}
/* Since there is no power management implemented in Musca, Deep Sleep could
* be supported only by additional software components, registering and managing
* the currently configured IPs. This would also mean a huge implementation
* overhead, that is not intended to be added. Therefore, Deep Sleep is almost
* identical to Sleep, representing a "Waiting For Interrupt" state, and
* disabling the Microsec ticker in addition.
*/
void hal_deepsleep(void)
{
#ifdef USEC_TIMER_DEV
timer_cmsdk_disable(&USEC_TIMER_DEV);
#endif
__WFI();
#ifdef USEC_TIMER_DEV
timer_cmsdk_enable(&USEC_TIMER_DEV);
#endif
}
#endif

View File

@ -0,0 +1,251 @@
/*
* Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __TFM_IOCTL_API__
#define __TFM_IOCTL_API__
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include "tfm_api.h"
#include "tfm_platform_api.h"
#ifdef __cplusplus
extern "C" {
#endif
enum tfm_platform_ioctl_request_types_t {
TFM_PLATFORM_IOCTL_PIN_SERVICE,
TFM_PLATFORM_IOCTL_GPIO_SERVICE,
};
/*!
* \enum tfm_gpio_service_type_t
*
* \brief GPIO service types (supported types may vary based on the platform)
*/
enum tfm_gpio_service_type_t {
TFM_GPIO_SERVICE_TYPE_INIT = 0, /*!< Init */
TFM_GPIO_SERVICE_TYPE_PIN_CONFIG, /*!< Pin config */
TFM_GPIO_SERVICE_TYPE_PIN_WRITE, /*!< Pin write */
TFM_GPIO_SERVICE_TYPE_PIN_READ, /*!< Pin read */
TFM_GPIO_SERVICE_TYPE_PORT_CONFIG, /*!< Port config */
TFM_GPIO_SERVICE_TYPE_PORT_WRITE, /*!< Port write */
TFM_GPIO_SERVICE_TYPE_PORT_READ, /*!< Port read */
TFM_GPIO_SERVICE_TYPE_MAX = INT_MAX /*!< Max to force enum max size */
};
/*!
* \struct tfm_gpio_service_args_t
*
* \brief Argument list for each platform GPIO service
*/
struct tfm_gpio_service_args_t {
enum tfm_gpio_service_type_t type;
union {
struct gpio_config_args { /*!< TFM_GPIO_SERVICE_TYPE_PIN_CONFIG ||
TFM_GPIO_SERVICE_TYPE_PORT_CONFIG */
uint32_t pin_num_or_mask;
uint32_t direction;
} gpio_config;
struct gpio_write_args { /*!< TFM_GPIO_SERVICE_TYPE_PIN_WRITE ||
TFM_GPIO_SERVICE_TYPE_PORT_WRITE */
uint32_t pin_num_or_mask;
uint32_t value;
} gpio_write;
struct gpio_read_args { /*!< TFM_GPIO_SERVICE_TYPE_PIN_READ ||
TFM_GPIO_SERVICE_TYPE_PORT_READ */
uint32_t pin_num_or_mask;
} gpio_read;
} u;
};
/*!
* \struct tfm_gpio_service_out_t
*
* \brief Output list for each GPIO platform service
*/
struct tfm_gpio_service_out_t {
union {
uint32_t result; /*!< Generic result */
struct gpio_read_result { /*!< TFM_GPIO_SERVICE_TYPE_PIN_READ ||
TFM_GPIO_SERVICE_TYPE_PORT_READ */
uint32_t result;
uint32_t data;
} gpio_read_result;
} u;
};
/*!
* \enum tfm_pin_service_type_t
*
* \brief Pin service types
*/
enum tfm_pin_service_type_t {
TFM_PIN_SERVICE_TYPE_SET_ALTFUNC = 0, /*!< Set alternate function type */
TFM_PIN_SERVICE_TYPE_SET_DEFAULT_IN, /*!< Set default in function type */
TFM_PIN_SERVICE_TYPE_SET_PIN_MODE, /*!< Set pin mode function type */
TFM_PIN_SERVICE_TYPE_MAX = INT_MAX /*!< Max to force enum max size */
};
/*!
* \struct tfm_pin_service_args_t
*
* \brief Argument list for each platform pin service
*/
struct tfm_pin_service_args_t {
enum tfm_pin_service_type_t type;
union {
struct set_altfunc { /*!< TFM_PIN_SERVICE_TYPE_SET_ALTFUNC */
uint32_t alt_func;
uint64_t pin_mask;
} set_altfunc;
struct set_default_in { /*!< TFM_PIN_SERVICE_TYPE_SET_DEFAULT_IN */
uint32_t alt_func;
uint32_t pin_value;
bool default_in_value;
} set_default_in;
struct set_pin_mode { /*!< TFM_PIN_SERVICE_TYPE_SET_PIN_MODE */
uint64_t pin_mask;
uint32_t pin_mode;
} set_pin_mode;
} u;
};
/*!
* \brief Sets pin alternate function for the given pins
*
* \param[in] alt_func Alternate function to set (allowed values vary
* based on the platform)
* \param[in] pin_mask Pin mask of the selected pins
* \param[out] result Return error value
*
* \return Returns values as specified by the \ref tfm_platform_err_t
*/
enum tfm_platform_err_t
tfm_platform_set_pin_alt_func(uint32_t alt_func, uint64_t pin_mask,
uint32_t *result);
/*!
* \brief Sets default in value to use when the alternate function is not
* selected for the pin
*
* \param[in] alt_func Alternate function to use (allowed values vary
* based on the platform)
* \param[in] pin_value Pin value to use
* \param[in] default_in_value Default in value to set
* \param[out] result Return error value
*
* \return Returns values as specified by the \ref tfm_platform_err_t
*/
enum tfm_platform_err_t
tfm_platform_set_pin_default_in(uint32_t alt_func, uint32_t pin_value,
bool default_in_value, uint32_t *result);
/*!
* \brief Sets pin mode for the selected pins
*
* \param[in] pin_mask Pin mask of the selected pins
* \param[in] pin_mode Pin mode to set for the selected pins
* \param[out] result Return error value
*
* \return Returns values as specified by the \ref tfm_platform_err_t
*/
enum tfm_platform_err_t
tfm_platform_set_pin_mode(uint64_t pin_mask, uint32_t pin_mode,
uint32_t *result);
/*!
* \brief Initializes GPIO module
*
* \param[out] result Return error value
*
* \return Returns values as specified by the \ref tfm_platform_err_t
*/
enum tfm_platform_err_t tfm_platform_gpio_init(uint32_t *result);
/*!
* \brief Configures a GPIO pin as input or output
*
* \param[in] pin_num Pin number of the selected pin
* \param[in] direction Direction of the pin: 0 for input, 1 for output
* \param[out] result Return error value
*
* \return Returns values as specified by the \ref tfm_platform_err_t
*/
enum tfm_platform_err_t
tfm_platform_gpio_pin_config(uint32_t pin_num, uint32_t direction,
uint32_t *result);
/*!
* \brief Sets state of a selected GPIO pin
*
* \param[in] pin_num Pin number of the selected pin
* \param[in] value Value to set for the pin
* \param[out] result Return error value
*
* \return Returns values as specified by the \ref tfm_platform_err_t
*/
enum tfm_platform_err_t
tfm_platform_gpio_pin_write(uint32_t pin_num, uint32_t value, uint32_t *result);
/*!
* \brief Reads state of a selected GPIO pin
*
* \param[in] pin_num Pin number of the selected pin
* \param[in,out] data Bit value read from the IO pin
* \param[out] result Return error value
*
* \return Returns values as specified by the \ref tfm_platform_err_t
*/
enum tfm_platform_err_t
tfm_platform_gpio_pin_read(uint32_t pin_num, uint32_t *data, uint32_t *result);
/*!
* \brief Configures GPIO pins as input or output
*
* \param[in] pin_mask Pin mask of the selected pins
* \param[in] direction Direction of the pin: 0 for input, 1 for output
* \param[out] result Return error value
*
* \return Returns values as specified by the \ref tfm_platform_err_t
*/
enum tfm_platform_err_t
tfm_platform_gpio_port_config(uint32_t pin_mask, uint32_t direction,
uint32_t *result);
/*!
* \brief Sets state of a selected GPIO pins
*
* \param[in] pin_mask Pin mask of the selected pins
* \param[in] value Value mask to set for the pins
* \param[out] result Return error value
*
* \return Returns values as specified by the \ref tfm_platform_err_t
*/
enum tfm_platform_err_t
tfm_platform_gpio_port_write(uint32_t pin_mask, uint32_t value,
uint32_t *result);
/*!
* \brief Reads state of a selected GPIO pins
*
* \param[in] pin_mask Pin mask of the selected pins
* \param[in,out] data Bit value mask read from the IO pins
* \param[out] result Return error value
*
* \return Returns values as specified by the \ref tfm_platform_err_t
*/
enum tfm_platform_err_t
tfm_platform_gpio_port_read(uint32_t pin_mask, uint32_t *data,
uint32_t *result);
#ifdef __cplusplus
}
#endif
#endif /* __TFM_IOCTL_API__ */

View File

@ -0,0 +1,299 @@
/*
* Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <stdint.h>
#include <stdbool.h>
#include "tfm_platform_api.h"
#include "tfm_ioctl_api.h"
enum tfm_platform_err_t
tfm_platform_set_pin_alt_func(uint32_t alt_func, uint64_t pin_mask,
uint32_t *result)
{
enum tfm_platform_err_t ret;
psa_invec in_vec;
psa_outvec out_vec;
struct tfm_pin_service_args_t args;
if (result == NULL) {
return TFM_PLATFORM_ERR_INVALID_PARAM;
}
args.type = TFM_PIN_SERVICE_TYPE_SET_ALTFUNC;
args.u.set_altfunc.alt_func = alt_func;
args.u.set_altfunc.pin_mask = pin_mask;
in_vec.base = (const void *)&args;
in_vec.len = sizeof(args);
out_vec.base = (void *)result;
out_vec.len = sizeof(*result);
ret = tfm_platform_ioctl(TFM_PLATFORM_IOCTL_PIN_SERVICE,
&in_vec,
&out_vec);
return ret;
}
enum tfm_platform_err_t
tfm_platform_set_pin_default_in(uint32_t alt_func, uint32_t pin_value,
bool default_in_value, uint32_t *result)
{
enum tfm_platform_err_t ret;
psa_invec in_vec;
psa_outvec out_vec;
struct tfm_pin_service_args_t args;
if (result == NULL) {
return TFM_PLATFORM_ERR_INVALID_PARAM;
}
args.type = TFM_PIN_SERVICE_TYPE_SET_DEFAULT_IN;
args.u.set_default_in.alt_func = alt_func;
args.u.set_default_in.pin_value = pin_value;
args.u.set_default_in.default_in_value = default_in_value;
in_vec.base = (const void *)&args;
in_vec.len = sizeof(args);
out_vec.base = (void *)result;
out_vec.len = sizeof(*result);
ret = tfm_platform_ioctl(TFM_PLATFORM_IOCTL_PIN_SERVICE,
&in_vec,
&out_vec);
return ret;
}
enum tfm_platform_err_t
tfm_platform_set_pin_mode(uint64_t pin_mask, uint32_t pin_mode,
uint32_t *result)
{
enum tfm_platform_err_t ret;
psa_invec in_vec;
psa_outvec out_vec;
struct tfm_pin_service_args_t args;
if (result == NULL) {
return TFM_PLATFORM_ERR_INVALID_PARAM;
}
args.type = TFM_PIN_SERVICE_TYPE_SET_PIN_MODE;
args.u.set_pin_mode.pin_mask = pin_mask;
args.u.set_pin_mode.pin_mode = pin_mode;
in_vec.base = (const void *)&args;
in_vec.len = sizeof(args);
out_vec.base = (void *)result;
out_vec.len = sizeof(*result);
ret = tfm_platform_ioctl(TFM_PLATFORM_IOCTL_PIN_SERVICE,
&in_vec,
&out_vec);
return ret;
}
enum tfm_platform_err_t tfm_platform_gpio_init(uint32_t *result)
{
enum tfm_platform_err_t ret;
psa_invec in_vec;
psa_outvec out_vec;
struct tfm_gpio_service_args_t args;
struct tfm_gpio_service_out_t out;
args.type = TFM_GPIO_SERVICE_TYPE_INIT;
in_vec.base = (const void *)&args;
in_vec.len = sizeof(args);
out_vec.base = (void *)&out;
out_vec.len = sizeof(out);
ret = tfm_platform_ioctl(TFM_PLATFORM_IOCTL_GPIO_SERVICE,
&in_vec,
&out_vec);
*result = out.u.result;
return ret;
}
enum tfm_platform_err_t
tfm_platform_gpio_pin_config(uint32_t pin_num, uint32_t direction,
uint32_t *result)
{
enum tfm_platform_err_t ret;
psa_invec in_vec;
psa_outvec out_vec;
struct tfm_gpio_service_args_t args;
struct tfm_gpio_service_out_t out;
args.type = TFM_GPIO_SERVICE_TYPE_PIN_CONFIG;
args.u.gpio_config.pin_num_or_mask = pin_num;
args.u.gpio_config.direction = direction;
in_vec.base = (const void *)&args;
in_vec.len = sizeof(args);
out_vec.base = (void *)&out;
out_vec.len = sizeof(out);
ret = tfm_platform_ioctl(TFM_PLATFORM_IOCTL_GPIO_SERVICE,
&in_vec,
&out_vec);
*result = out.u.result;
return ret;
}
enum tfm_platform_err_t
tfm_platform_gpio_pin_write(uint32_t pin_num, uint32_t value, uint32_t *result)
{
enum tfm_platform_err_t ret;
psa_invec in_vec;
psa_outvec out_vec;
struct tfm_gpio_service_args_t args;
struct tfm_gpio_service_out_t out;
args.type = TFM_GPIO_SERVICE_TYPE_PIN_WRITE;
args.u.gpio_write.pin_num_or_mask = pin_num;
args.u.gpio_write.value = value;
in_vec.base = (const void *)&args;
in_vec.len = sizeof(args);
out_vec.base = (void *)&out;
out_vec.len = sizeof(out);
ret = tfm_platform_ioctl(TFM_PLATFORM_IOCTL_GPIO_SERVICE,
&in_vec,
&out_vec);
*result = out.u.result;
return ret;
}
enum tfm_platform_err_t
tfm_platform_gpio_pin_read(uint32_t pin_num, uint32_t *data, uint32_t *result)
{
enum tfm_platform_err_t ret;
psa_invec in_vec;
psa_outvec out_vec;
struct tfm_gpio_service_args_t args;
struct tfm_gpio_service_out_t out;
args.type = TFM_GPIO_SERVICE_TYPE_PIN_READ;
args.u.gpio_read.pin_num_or_mask = pin_num;
in_vec.base = (const void *)&args;
in_vec.len = sizeof(args);
out_vec.base = (void *)&out;
out_vec.len = sizeof(out);
ret = tfm_platform_ioctl(TFM_PLATFORM_IOCTL_GPIO_SERVICE,
&in_vec,
&out_vec);
*result = out.u.gpio_read_result.result;
*data = out.u.gpio_read_result.data;
return ret;
}
enum tfm_platform_err_t
tfm_platform_gpio_port_config(uint32_t pin_mask, uint32_t direction,
uint32_t *result)
{
enum tfm_platform_err_t ret;
psa_invec in_vec;
psa_outvec out_vec;
struct tfm_gpio_service_args_t args;
struct tfm_gpio_service_out_t out;
args.type = TFM_GPIO_SERVICE_TYPE_PORT_CONFIG;
args.u.gpio_config.pin_num_or_mask = pin_mask;
args.u.gpio_config.direction = direction;
in_vec.base = (const void *)&args;
in_vec.len = sizeof(args);
out_vec.base = (void *)&out;
out_vec.len = sizeof(out);
ret = tfm_platform_ioctl(TFM_PLATFORM_IOCTL_GPIO_SERVICE,
&in_vec,
&out_vec);
*result = out.u.result;
return ret;
}
enum tfm_platform_err_t
tfm_platform_gpio_port_write(uint32_t pin_mask, uint32_t value,
uint32_t *result)
{
enum tfm_platform_err_t ret;
psa_invec in_vec;
psa_outvec out_vec;
struct tfm_gpio_service_args_t args;
struct tfm_gpio_service_out_t out;
args.type = TFM_GPIO_SERVICE_TYPE_PORT_WRITE;
args.u.gpio_write.pin_num_or_mask = pin_mask;
args.u.gpio_write.value = value;
in_vec.base = (const void *)&args;
in_vec.len = sizeof(args);
out_vec.base = (void *)&out;
out_vec.len = sizeof(out);
ret = tfm_platform_ioctl(TFM_PLATFORM_IOCTL_GPIO_SERVICE,
&in_vec,
&out_vec);
*result = out.u.result;
return ret;
}
enum tfm_platform_err_t
tfm_platform_gpio_port_read(uint32_t pin_mask, uint32_t *data, uint32_t *result)
{
enum tfm_platform_err_t ret;
psa_invec in_vec;
psa_outvec out_vec;
struct tfm_gpio_service_args_t args;
struct tfm_gpio_service_out_t out;
args.type = TFM_GPIO_SERVICE_TYPE_PORT_READ;
args.u.gpio_read.pin_num_or_mask = pin_mask;
in_vec.base = (const void *)&args;
in_vec.len = sizeof(args);
out_vec.base = (void *)&out;
out_vec.len = sizeof(out);
ret = tfm_platform_ioctl(TFM_PLATFORM_IOCTL_GPIO_SERVICE,
&in_vec,
&out_vec);
*result = out.u.gpio_read_result.result;
*data = out.u.gpio_read_result.data;
return ret;
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,124 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2019 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Supports the High-resolution Ticker for mbed by implementing
* \ref us_ticker_api.h, using a CMSDK Timer \ref timer_cmsdk_dev_t.
*/
#include "device.h"
#include "mbed_critical.h"
#include "timer_cmsdk_drv.h"
#include "us_ticker_api.h"
static uint64_t total_ticks = 0;
/* Stores the last reload value, or the last tick value read when a read API
* call occurs from the upper layer, needed to keep total_ticks
* accumulated properly.
*/
static uint32_t previous_ticks = 0;
static void restart_timer(uint32_t new_reload)
{
timer_cmsdk_disable(&USEC_TIMER_DEV);
timer_cmsdk_set_reload_value(&USEC_TIMER_DEV,
new_reload);
timer_cmsdk_reset(&USEC_TIMER_DEV);
timer_cmsdk_clear_interrupt(&USEC_TIMER_DEV);
timer_cmsdk_enable_interrupt(&USEC_TIMER_DEV);
timer_cmsdk_enable(&USEC_TIMER_DEV);
}
static void update_ticker(void)
{
if (timer_cmsdk_is_interrupt_active(&USEC_TIMER_DEV)) {
total_ticks += previous_ticks;
previous_ticks = TIMER_CMSDK_MAX_RELOAD;
restart_timer(previous_ticks);
} else {
uint32_t tick = timer_cmsdk_get_current_value(&USEC_TIMER_DEV);
if (tick < previous_ticks) {
uint32_t delta = previous_ticks - tick;
total_ticks += delta;
previous_ticks = tick;
}
}
}
void us_ticker_init(void)
{
timer_cmsdk_init(&USEC_TIMER_DEV);
previous_ticks = TIMER_CMSDK_MAX_RELOAD;
NVIC_EnableIRQ(USEC_INTERVAL_IRQ);
restart_timer(previous_ticks);
}
void us_ticker_free(void)
{
timer_cmsdk_disable(&USEC_TIMER_DEV);
}
uint32_t us_ticker_read(void)
{
core_util_critical_section_enter();
update_ticker();
core_util_critical_section_exit();
return (uint32_t)(total_ticks >> USEC_REPORTED_SHIFT);
}
void us_ticker_set_interrupt(timestamp_t timestamp)
{
uint32_t reload = (timestamp - us_ticker_read()) << USEC_REPORTED_SHIFT;
previous_ticks = reload;
restart_timer(previous_ticks);
}
void us_ticker_disable_interrupt(void)
{
timer_cmsdk_disable_interrupt(&USEC_TIMER_DEV);
}
void us_ticker_clear_interrupt(void)
{
timer_cmsdk_clear_interrupt(&USEC_TIMER_DEV);
}
void us_ticker_fire_interrupt(void)
{
NVIC_SetPendingIRQ(USEC_INTERVAL_IRQ);
}
const ticker_info_t* us_ticker_get_info()
{
static const ticker_info_t info = {
USEC_REPORTED_FREQ_HZ,
USEC_REPORTED_BITS
};
return &info;
}
#ifndef usec_interval_irq_handler
#error "usec_interval_irq_handler should be defined, check device_cfg.h!"
#endif
void usec_interval_irq_handler(void)
{
update_ticker();
us_ticker_irq_handler();
}

View File

@ -43,7 +43,7 @@
#define INITIAL_SP (ZBT_SSRAM23_START + ZBT_SSRAM23_SIZE)
#endif
#elif defined(TARGET_MUSCA_A1) || defined(TARGET_MUSCA_B1)
#elif defined(TARGET_MUSCA_A1) || defined(TARGET_MUSCA_B1) || defined(TARGET_MUSCA_S1)
#if defined(__ARMCC_VERSION)
extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Base[];
@ -58,6 +58,6 @@
#error "no toolchain defined"
#endif
#endif /* defined(TARGET_MUSCA_A1) || defined(TARGET_MUSCA_B1) */
#endif /* defined(TARGET_MUSCA_A1) || defined(TARGET_MUSCA_B1) || defined(TARGET_MUSCA_S1) */
#endif /* MBED_MBED_RTX_H */

View File

@ -4077,6 +4077,66 @@
"ARM_MUSCA_B1"
]
},
"ARM_MUSCA_S1": {
"inherits": [
"PSA_V8_M"
],
"default_toolchain": "ARMC6",
"features_add": [
"EXPERIMENTAL_API"
],
"forced_reset_timeout": 20,
"release_versions": [
"5"
],
"core": "Cortex-M33-NS",
"supported_toolchains": [
"ARMC6",
"GCC_ARM"
],
"device_has_add": [
"INTERRUPTIN",
"I2C",
"I2CSLAVE",
"LPTICKER",
"SERIAL",
"SLEEP",
"USTICKER"
],
"macros_add": [
"__STARTUP_CLEAR_BSS",
"MBED_FAULT_HANDLER_DISABLED",
"CMSIS_NVIC_VIRTUAL",
"LPTICKER_DELAY_TICKS=3",
"MBED_MPU_CUSTOM",
"BL2"
],
"extra_labels_add": [
"ARM_SSG",
"MUSCA_S1",
"MUSCA_S1_NS"
],
"post_binary_hook": {
"function": "ArmMuscaS1Code.binary_hook"
},
"secure_image_filename": "tfm_s.bin",
"tfm_target_name": "MUSCA_S1",
"tfm_bootloader_supported": true,
"tfm_default_toolchain": "ARMCLANG",
"tfm_supported_toolchains": [
"ARMCLANG",
"GNUARM"
],
"tfm_delivery_dir": "TARGET_ARM_SSG/TARGET_MUSCA_S1",
"detect_code": [
"5009"
]
},
"ARM_MUSCA_S1_NS": {
"inherits": [
"ARM_MUSCA_S1"
]
},
"RZ_A1XX": {
"inherits": [
"Target"

View File

@ -0,0 +1,111 @@
#!/usr/bin/python
# Copyright (c) 2017-2020 Arm Limited
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
from os.path import abspath, basename, dirname, splitext, isdir
from os.path import join as path_join
import re
from argparse import Namespace
from tools.psa.tfm.bin_utils.assemble import Assembly
from tools.psa.tfm.bin_utils.imgtool import do_sign
from tools.psa.tfm.bin_utils.imgtool_lib import version
SCRIPT_DIR = dirname(abspath(__file__))
MBED_OS_ROOT = abspath(path_join(SCRIPT_DIR, os.pardir, os.pardir))
MUSCA_S1_BASE = path_join(MBED_OS_ROOT, 'targets', 'TARGET_ARM_SSG', 'TARGET_MUSCA_S1')
def musca_tfm_bin(t_self, non_secure_bin, secure_bin):
assert os.path.isfile(secure_bin)
assert os.path.isfile(non_secure_bin)
build_dir = dirname(non_secure_bin)
tempdir = path_join(build_dir, 'temp')
if not isdir(tempdir):
os.makedirs(tempdir)
flash_layout = path_join(MUSCA_S1_BASE, 'partition', 'flash_layout.h')
mcuboot_bin = path_join(MUSCA_S1_BASE, 'mcuboot.bin')
image_macros_s = path_join(MUSCA_S1_BASE, 'partition', 'image_macros_preprocessed_s.c')
image_macros_ns = path_join(MUSCA_S1_BASE, 'partition', 'image_macros_preprocessed_ns.c')
s_bin_name, s_bin_ext = splitext(basename(secure_bin))
s_signed_bin = path_join(tempdir, s_bin_name + '_signed' + s_bin_ext)
ns_bin_name, ns_bin_ext = splitext(basename(non_secure_bin))
ns_signed_bin = path_join(tempdir, 'tfm_' + ns_bin_name + '_signed' + ns_bin_ext)
concatenated_bin = path_join(tempdir, s_bin_name + '_' + ns_bin_name + '_concat' + ns_bin_ext)
assert os.path.isfile(image_macros_s)
assert os.path.isfile(image_macros_ns)
#1. Run imgtool to sign the secure binary
sign_args = Namespace(
layout=image_macros_s,
key=path_join(SCRIPT_DIR, 'musca_s1-root-rsa-3072.pem'),
public_key_format=None,
align=1,
dependencies=None,
version=version.decode_version('1.0'),
header_size=0x400,
security_counter=None,
rsa_pkcs1_15=False,
included_header=False,
infile=secure_bin,
outfile=s_signed_bin
)
do_sign(sign_args)
#2. Run imgtool to sign the non-secure mbed binary
sign_args = Namespace(
layout=image_macros_ns,
key=path_join(SCRIPT_DIR, 'musca_s1-root-rsa-3072_1.pem'),
public_key_format=None,
align=1,
dependencies=None,
version=version.decode_version('1.0'),
header_size=0x400,
security_counter=None,
rsa_pkcs1_15=False,
included_header=False,
infile=non_secure_bin,
outfile=ns_signed_bin
)
do_sign(sign_args)
#1. Concatenate signed secure TFM and non-secure mbed binaries
output = Assembly(image_macros_s, concatenated_bin)
output.add_image(s_signed_bin, "SECURE")
output.add_image(ns_signed_bin, "NON_SECURE")
#3. Concatenate mcuboot and signed binary and overwrite mbed built binary file
mcuboot_image_size = find_bl2_size(flash_layout)
with open(mcuboot_bin, "rb") as mcuboot_fh, open(concatenated_bin, "rb") as concat_fh:
with open(non_secure_bin, "w+b") as out_fh:
out_fh.write(mcuboot_fh.read())
out_fh.seek(mcuboot_image_size)
out_fh.write(concat_fh.read())
def find_bl2_size(configFile):
bl2_size_re = re.compile(r"^#define\s+FLASH_AREA_BL2_SIZE\s+\({0,1}(0x[0-9a-fA-F]+)\){0,1}")
bl2_size = None
with open(configFile, 'r') as flash_layout_file:
for line in flash_layout_file:
m = bl2_size_re.match(line)
if m is not None:
bl2_size = int(m.group(1), 0)
break
return bl2_size

View File

@ -711,6 +711,21 @@ class ArmMuscaB1Code(object):
)
musca_tfm_bin(t_self, binf, secure_bin)
class ArmMuscaS1Code(object):
"""Musca-S1 Hooks"""
@staticmethod
def binary_hook(t_self, resources, elf, binf):
from tools.targets.ARM_MUSCA_S1 import musca_tfm_bin
configured_secure_image_filename = t_self.target.secure_image_filename
secure_bin = find_secure_image(
t_self.notify,
resources,
binf,
configured_secure_image_filename,
FileType.BIN
)
musca_tfm_bin(t_self, binf, secure_bin)
def find_secure_image(notify, resources, ns_image_path,
configured_s_image_filename, image_type):
""" Find secure image. """

View File

@ -0,0 +1,11 @@
# Musca-S1 RSA keypair
A default RSA key pair is given to the Musca-S1 target.
Public keys were pre-compiled to `targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/prebuilt/mcuboot.bin` and private key is in `musca_s1-root-rsa-3072.pem` for Secure image and `musca_s1-root-rsa-3072_1.pem` for Non-Secure image.
DO NOT use them in production code, they are exclusively for testing!
Private key must be stored in a safe place outside of the repository.
`tools/psa/tfm/bin_utils/imgtool.py` can be used to generate new key pairs.

View File

@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
MIIG4gIBAAKCAYEAnLrCWr/MxU8gDE9vbFFPXAqrgLhrEMSbK8RSMglLOyeUah3V
TKhcoMB2lXsmBLETfngn1gy06LAtklKK+2n/QhCqVgyDyGVuug1fjvcrKZL8Qi0t
+YD1hSGH6qxAqMvQqDvi0uzwFEgOzyuKS6TNoQVbF2Yd3m5E/kajDdBpv4ytqRZo
Uet5kSDmgQMHiUBVS+vPZ/gxxxxUTlILYOiiUAfRz84SJs2Ogo1OZKn3xyGZJQfd
xdVf9GP6zCvaBlxZZ7AGNemqkkU15aAD/xwCtcdOlEturXOdzm8Js7GPYGyi+s13
D8wn5jZYs1L3j75JmLfpYP2XV83q0wvfokL3RNOH3uAQA5Ta/LzdvpOzSitY3JYS
8m8jujs3/vwYH3V9VAEOvj0YE7MouTQs1fvFM72HvTvkHdcCPRxyZXJDQzao+uZz
LaRh6AKcOlZNHNF2nIyqXxvrHEr1ubhvQUsnh972lB/d5vGpwgLCT6P8pANa2W94
/YTw5f09pU0brVtLAgMBAAECggGAG786mltbctEL0PIdPVV10cs3yq2bktfjys9S
Z/ZaQcpDjbfjY9NotrLsK5GmTO1WkKzQDKaqPom2P7HqVhFRdg5CQcKscAV5IWot
sT9T/mO90i9ydLoefWfOyr6dIeUXdzlG8mWtKUIKkSXZsYOnPesXUeCryA3InCXA
RzlPB3Dt68ICTQJ9vrJO7KcvJd7kWvEQAo2frmr3B/iheBInbji8LeiDMShyIu3G
Y67tpWzu0m3+lsAsYTV0GMJosniVulaZ3hYQQazHUk+zDzMSC7zryICrpjEbgzWU
HZI9EGi1B890nwUtdhlCpkr8zoWDb0BjawpftiGz7fRm7q2TQkYAWGzNKm3DZlIS
4LsRACvHnPZ17wUSze9tqP14Pb593WR3nOTiVjrJWm+4Z5hgV3QfoEqW5swOAYl4
6QmKZsCXAfGkozJiHnYcyaULkGBVegn1LQ5rcb8JUMribQddrHZxCVHrbgwh2zm/
v9CYfTtpWCnKHq+wF3mwjl6w7m4JAoHBALolVbgs919Dx0xjcPnW5MSxW3ctflI9
2ZE1BOH/Rtg5gfBwR/aToUM3a/ZgIJHQYhVty2TzUVtthtmLNTRKu2FSqWN8//GJ
wmj4bcNBshMgniHEfkutlBiP9exhdvCZX4bYpdTkJAyvOmUGjEM8QBFsod60u0z7
Bd0EIXs7PIURP0fNAUXCgSHMPjdICLljhwHinr31VEIU2/xehw8DBIJwkR/rCsPq
xBmlIwPWVjzCRTnYUxQuxCAYf+qvgNylKQKBwQDXi3UGI7t30rYNMdIjMn1GPkhW
o62BOJNCusoXiGnbVOkj8qBayf7kPu10ONBzHcYL7+SQYeVVXQY+DH033ji8oa0J
p1xMGIlx4JZEduQYlk0ke4hUNrcBQczTRA47DmMm2kIdWlaTHtB7aCJNx72IrwWn
lVTY9TWm6+yOPcpV5JfyCMM6GqoRycikgNS5IQug5hl2pFVLw+UTfxo6msYaAOnp
ICUjoeDUKS0Z8+FtzGhAkWTk8GXIiPbfu7RoN1MCgcAcah6Poq2QKTR/AJ76REdf
jwM7SgKCY1aWx9Ua+nDCCOVA4qLZjOeM7yTX0wyltX2Db+MgYdQFdM6k3o8ckFvS
G2AoA6i+Ih0/EM0QhTK9oLkCxo/Q1YpJxY/wqWASkhb26pNF0B2Aoi7zxPAcQ1I0
VrTO3h/JPHhEqKDDwuMWHO/f8fdDwtEba6YDokdSpVKygvlgXdaiz7RU7ckIDZne
n3hHuwVFqsyMbZzOtSUs2SrgDZmA9zKRA6xjEq9E/yECgcAnm7XecfSCGVNg61XN
J/sDTHCokx1QEKBm88ItPuEM7/aDp5M1+8Z+FN43rDUJ4l/BU8zxhzvISvbZshvU
h15vs1oD2yBHz356UaXrYNmbdwsn+BdeOku4zGmiLPBcg9FOk27wy+f60v/GnaUo
G9tFYbwtRnC4CZ9ZVCM9JDepPv9494lAhSPZbvYS3KW6e0sSvxXQynPuH0paIdIl
EMn0f1R8hW6ttJKHCiYCjeFP9u71ZoJe25oolpqfFHQbbocCgcAuBR4w3Qmnbscm
3b7fyy8n3AXa1gIfYjjPpR35qyp1K9thiLyj66YZIl0ACC/dt08lmI9/lguRoNIQ
AfjzZ8DByZa0caiSiFIMlgNZXdh7N3BUNNbIQk98Wd91gBlWDAiFEhrJKFPpRkmv
FySATPYcq0lcrjJb3IW2GDK4uo/jb4Nb7Cfog95W6T76XcSKHS5O8k1aI4kFPRsr
1wGZw64OkA8VXVaCaEBQ4brZ1YKB3mx4/tDqwn0I6bqkGRX3RJg=
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
MIIG5AIBAAKCAYEAv7ewn+jI0f4WHVOHl3kcFceZFmzKuC3Kwg1i+euP6ToYQ0fX
u9VivOMzY6ejqFzzI3j9LQchH7lUcCipCNpQfp6OzGhOf0gN6ifoxu+tX51GSrxp
mjBfO8FSkvi8ddQ8J3BAAKYuKH9Z5WBDEdwxCX3PL0E/tlIao0kW8rWznDz7Xiwf
Ioa9rr42Ur3E8FhpNqeAPoGzVJjkXZXtIfC6riH7xBmHVdErTwDYQVjL26maU+ls
Z8t8XfaRBnVS8sB+sWtdMEBAL9gelTwFl3/wBPBOLNU5DpQ9fAMIHQkI8o1EDc+z
lj1aduj27pNk6FfR4vULGGlv6eE9+IlJKOavuKjGQlUtwduMXbJtf/4m6nXZ/R/c
IjukG6et63HfvbQ30eu+CBAceIQcmnXEreXvcxesaXi81jeMDBQhBke9+AqsGQmd
DR1y4T4adOqG2VxKzczGlKf+2guHEbtr8DrjT4JPseSkzbxwPJ2cSfnPKG242m99
OFdVQypzjbYY/XCnAgMBAAECggGAWmcsjuMumzMEy5RhWlB+KVkC+7uWRg41z5aP
ZwkoxdIiscs1U/nVwvsh9uqMdi5Kap45SFvVx0dVpUPPHYEQtvxems3Owh9AjHuA
PRq09uLLTB+XbmFD7wIExZAsEiXfrbs1Ovkhx+/xfIONbOUXbIHaSk6q0/bYX8nt
28pJpTFuWORWVCoUVMuWAyNANBOEnYSTqSXw4cHs4aJ6fOgup0EYHsro8dMd6HWe
BAZyrqTFxK7L8w/Vl9tWXKTDVfvlj8DHRwWBQhvS1P4XWaEcVopv7Sy4XK7UUeXm
tllsi5byGlNmr9ADK7Gd+eft/y/APyWo6SFPBLiyVLCSJ+6X4/7FwmLGYYt1WysH
/86W55qTRgtHQmb+oPBn8NYDxnYhEYFzGbpoAPD83U4CyGbnoqp5tsmssw8SfvWH
BTUdJiPjVLpHRuH1pwAyHMi+MvIVB6A8f5yWbtVwAho3Q+pIwd62aZqCpelUg9Vp
F1ssr723gQxPJqS/mwm1SfIe0GfNAoHBAMVgHdTANplIZIadWDulggjYXH5qkU+b
nB8bxv35s1Rl8iTQuD/UtxflIaLwciOl1mAfUUqG+6JH8c1OpVIaGmWKDeVThliH
tN8/OGdCPkPOFKyY8MHl83tNpsNk7P3F/WJOxCqxWziK3YoDwSr+l96XokAg/SDu
LoTax3DZPMAd2HSZuBPMGBlIbbfdkAaWzB0QJBSWv6ednt0kue+F1O/sdQ15SXoz
jGzCrEf60HIOWdAnnCCq0iT+ZeZTX1gMhQKBwQD4qVxxlSJUv+w3pGC17IN3uC3K
yq988GVqOND21RdwZ/YeYZrmORjnpXyrpJsbj9IGwYd/hpwkLe8qwOj67mZCXmND
Eca4xE7s4gtAiHXOZKXRgISEs+9giWd/8U7pczVsUwiTS77j6C7nd1f5ZgKajxJd
Tdy4bIWErCKijmpT/IEQVVYb+Ki8khTKxzbaDxWtrHv/iM+7+bgUfsKefDcO6MCb
jmhj/aOSzcmcJNfx1bdqCyxuK6iw583awBtctjsCgcEArcdwvG74I4GPsM48b1fL
48nLtipSAot5rBIi5F7Du91+k1eJwfmhs1I0iWe2txg+ZadtRXcPetRpW2CRQnZl
I12n2m/t62igoabiHFhAxiZeIZEO+UljVP8LgyILX2zBKZs8MHKzZFcvs2KW4yoB
wSQ04M2q0SGkp6iQzRUX3fbpK9BkOFoMJcaVg7t6IbMHx9b8TXxlBklLJF4/r1pg
H1ZLwS82uHdGfkPwt/dnK+Tiwtj9J+3+1D+ArIhffACZAoHBANghRLOIv41QP73h
Rxn5GA//6vVflIaQ4GUiOya/8p6GDhs8FQnUSPxXD3SVHygmqpOqtN44HxEnR8Eu
aZJpkkJPjhFmqwY/wqYMl2Eg+txJCQN+pDA/wWl0JJzFHiS1OZMM3OBCLwoi7lnL
lpC0hMDYaErm+VjnImo9v+DwziRvzbJnqe+oAuncQuw5mUiRYfNRf3mM7ZpiJAjU
YM6mAqkXzwmmDsASXpGkAn+QWo3dh41JZvXfRsF0ya0/2siLrwKBwBBX7YegsNPJ
skp5AAwYDvujDISc3aLxqEc1UHyM5SmKVt1U0/Dsyod0ZBMe27N8t9INFqy+G7hI
Y1sthsk6DyM1hSiZsLBTossJgyu3Tf3e300NTmc6CpFSRqL1L4lcSzKAGNTWvS9H
5q+MpRkZLzug83pmFw0qTWTw8p79cpELM4sklLg8L5cnLDLZyU+Gr5ZshkgpkXJI
egyV0maL40d5fDsX2ZqCZQPrQ7+FhDHKg/jf3Z3lXHwTAKBNrQGN6g==
-----END RSA PRIVATE KEY-----