mirror of https://github.com/ARMmbed/mbed-os.git
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
parent
7f60090ddb
commit
bdf2306f16
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,9 @@
|
|||
},
|
||||
"ARM_MUSCA_B1_S": {
|
||||
"storage_type": "TDB_INTERNAL"
|
||||
},
|
||||
"ARM_MUSCA_S1_S": {
|
||||
"storage_type": "TDB_INTERNAL"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
|
@ -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.
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
|
@ -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__ */
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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")
|
||||
}
|
|
@ -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
|
|
@ -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__ */
|
|
@ -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
|
|
@ -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
|
|
@ -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__ */
|
|
@ -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
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
|
@ -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__ */
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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__ */
|
|
@ -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));
|
||||
}
|
|
@ -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__ */
|
|
@ -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);
|
||||
}
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
|
@ -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__ */
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
*/
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -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.
|
@ -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
|
|
@ -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__ */
|
|
@ -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)),
|
||||
};
|
|
@ -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)),
|
||||
};
|
|
@ -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__ */
|
|
@ -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.
|
@ -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");
|
||||
}
|
|
@ -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
|
|
@ -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__ */
|
|
@ -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.
|
@ -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();
|
||||
}
|
|
@ -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 */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
|
@ -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. """
|
||||
|
|
|
@ -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.
|
|
@ -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-----
|
|
@ -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-----
|
Loading…
Reference in New Issue