Merge pull request #4974 from ARMmbed/release-candidate

Release candidate for mbed-os-5.5.6
mbed-os-5.5 mbed_lib_rev150
Jimmy Brisson 2017-08-29 13:05:59 -05:00 committed by GitHub
commit 98ba8acb83
351 changed files with 100110 additions and 10202 deletions

View File

@ -28,10 +28,10 @@ script:
- python tools/project.py -S
- python tools/build_travis.py
before_install:
- sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded
- sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa
- sudo add-apt-repository -y ppa:libreoffice/libreoffice-4-2
- sudo apt-get update -qq
- sudo apt-get install -qq gcc-arm-none-eabi doxygen --force-yes
- sudo apt-get install -qq gcc-arm-embedded doxygen --force-yes
# Print versions we use
- arm-none-eabi-gcc --version
- python --version

View File

@ -0,0 +1,94 @@
/* Copyright (c) 2009 - 2012 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* Functions
*---------------------------------------------------------------------------*/
.text
.global __v7_all_cache
/*
* __STATIC_ASM void __v7_all_cache(uint32_t op) {
*/
__v7_all_cache:
.arm
PUSH {R4-R11}
MRC p15, 1, R6, c0, c0, 1 /* Read CLIDR */
ANDS R3, R6, #0x07000000 /* Extract coherency level */
MOV R3, R3, LSR #23 /* Total cache levels << 1 */
BEQ Finished /* If 0, no need to clean */
MOV R10, #0 /* R10 holds current cache level << 1 */
Loop1: ADD R2, R10, R10, LSR #1 /* R2 holds cache "Set" position */
MOV R1, R6, LSR R2 /* Bottom 3 bits are the Cache-type for this level */
AND R1, R1, #7 /* Isolate those lower 3 bits */
CMP R1, #2
BLT Skip /* No cache or only instruction cache at this level */
MCR p15, 2, R10, c0, c0, 0 /* Write the Cache Size selection register */
ISB /* ISB to sync the change to the CacheSizeID reg */
MRC p15, 1, R1, c0, c0, 0 /* Reads current Cache Size ID register */
AND R2, R1, #7 /* Extract the line length field */
ADD R2, R2, #4 /* Add 4 for the line length offset (log2 16 bytes) */
LDR R4, =0x3FF
ANDS R4, R4, R1, LSR #3 /* R4 is the max number on the way size (right aligned) */
CLZ R5, R4 /* R5 is the bit position of the way size increment */
LDR R7, =0x7FFF
ANDS R7, R7, R1, LSR #13 /* R7 is the max number of the index size (right aligned) */
Loop2: MOV R9, R4 /* R9 working copy of the max way size (right aligned) */
Loop3: ORR R11, R10, R9, LSL R5 /* Factor in the Way number and cache number into R11 */
ORR R11, R11, R7, LSL R2 /* Factor in the Set number */
CMP R0, #0
BNE Dccsw
MCR p15, 0, R11, c7, c6, 2 /* DCISW. Invalidate by Set/Way */
B cont
Dccsw: CMP R0, #1
BNE Dccisw
MCR p15, 0, R11, c7, c10, 2 /* DCCSW. Clean by Set/Way */
B cont
Dccisw: MCR p15, 0, R11, c7, c14, 2 /* DCCISW, Clean and Invalidate by Set/Way */
cont: SUBS R9, R9, #1 /* Decrement the Way number */
BGE Loop3
SUBS R7, R7, #1 /* Decrement the Set number */
BGE Loop2
Skip: ADD R10, R10, #2 /* increment the cache number */
CMP R3, R10
BGT Loop1
Finished:
DSB
POP {R4-R11}
BX lr
.END
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,97 @@
/* Copyright (c) 2009 - 2012 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* Functions
*---------------------------------------------------------------------------*/
SECTION `.text`:CODE:NOROOT(2)
arm
PUBLIC __v7_all_cache
/*
* __STATIC_ASM void __v7_all_cache(uint32_t op) {
*/
__v7_all_cache:
PUSH {R4-R11}
MRC p15, 1, R6, c0, c0, 1 /* Read CLIDR */
ANDS R3, R6, #0x07000000 /* Extract coherency level */
MOV R3, R3, LSR #23 /* Total cache levels << 1 */
BEQ Finished /* If 0, no need to clean */
MOV R10, #0 /* R10 holds current cache level << 1 */
Loop1: ADD R2, R10, R10, LSR #1 /* R2 holds cache "Set" position */
MOV R1, R6, LSR R2 /* Bottom 3 bits are the Cache-type for this level */
AND R1, R1, #7 /* Isolate those lower 3 bits */
CMP R1, #2
BLT Skip /* No cache or only instruction cache at this level */
MCR p15, 2, R10, c0, c0, 0 /* Write the Cache Size selection register */
ISB /* ISB to sync the change to the CacheSizeID reg */
MRC p15, 1, R1, c0, c0, 0 /* Reads current Cache Size ID register */
AND R2, R1, #7 /* Extract the line length field */
ADD R2, R2, #4 /* Add 4 for the line length offset (log2 16 bytes) */
LDR R4, =0x3FF
ANDS R4, R4, R1, LSR #3 /* R4 is the max number on the way size (right aligned) */
CLZ R5, R4 /* R5 is the bit position of the way size increment */
LDR R7, =0x7FFF
ANDS R7, R7, R1, LSR #13 /* R7 is the max number of the index size (right aligned) */
Loop2: MOV R9, R4 /* R9 working copy of the max way size (right aligned) */
Loop3: ORR R11, R10, R9, LSL R5 /* Factor in the Way number and cache number into R11 */
ORR R11, R11, R7, LSL R2 /* Factor in the Set number */
CMP R0, #0
BNE Dccsw
MCR p15, 0, R11, c7, c6, 2 /* DCISW. Invalidate by Set/Way */
B cont
Dccsw: CMP R0, #1
BNE Dccisw
MCR p15, 0, R11, c7, c10, 2 /* DCCSW. Clean by Set/Way */
B cont
Dccisw: MCR p15, 0, R11, c7, c14, 2 /* DCCISW, Clean and Invalidate by Set/Way */
cont: SUBS R9, R9, #1 /* Decrement the Way number */
BGE Loop3
SUBS R7, R7, #1 /* Decrement the Set number */
BGE Loop2
Skip: ADD R10, R10, #2 /* increment the cache number */
CMP R3, R10
BGT Loop1
Finished:
DSB
POP {R4-R11}
BX lr
END
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/

View File

@ -2056,7 +2056,32 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = DOXYGEN_ONLY \
PREDEFINED = DOXYGEN_ONLY \
DEVICE_ANALOGIN \
DEVICE_ANALOGOUT \
DEVICE_CAN \
DEVICE_ETHERNET \
DEVICE_EMAC \
DEVICE_FLASH \
DEVICE_I2C \
DEVICE_I2CSLAVE \
DEVICE_I2C_ASYNCH \
DEVICE_INTERRUPTIN \
DEVICE_LOWPOWERTIMER \
DEVICE_PORTIN \
DEVICE_PORTINOUT \
DEVICE_PORTOUT \
DEVICE_PWMOUT \
DEVICE_RTC \
DEVICE_TRNG \
DEVICE_SERIAL \
DEVICE_SERIAL_ASYNCH \
DEVICE_SERIAL_FC \
DEVICE_SLEEP \
DEVICE_SPI \
DEVICE_SPI_ASYNCH \
DEVICE_SPISLAVE \
DEVICE_STORAGE \
"MBED_DEPRECATED_SINCE(d, m)=" \
"MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M)="

View File

@ -5,7 +5,7 @@
"SEARCH_INCLUDES": "YES",
"INCLUDE_PATH": "",
"INCLUDE_FILE_PATTERNS": "",
"PREDEFINED": "DOXYGEN_ONLY \"MBED_DEPRECATED_SINCE(f, g)=\" \"MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M)=\"",
"PREDEFINED": "DOXYGEN_ONLY DEVICE_ANALOGIN DEVICE_ANALOGOUT DEVICE_CAN DEVICE_ETHERNET DEVICE_EMAC DEVICE_FLASH DEVICE_I2C DEVICE_I2CSLAVE DEVICE_I2C_ASYNCH DEVICE_INTERRUPTIN DEVICE_LOWPOWERTIMER DEVICE_PORTIN DEVICE_PORTINOUT DEVICE_PORTOUT DEVICE_PWMOUT DEVICE_RTC DEVICE_TRNG DEVICE_SERIAL DEVICE_SERIAL_ASYNCH DEVICE_SERIAL_FC DEVICE_SLEEP DEVICE_SPI DEVICE_SPI_ASYNCH DEVICE_SPISLAVE DEVICE_STORAGE \"MBED_DEPRECATED_SINCE(f, g)=\" \"MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M)=\"",
"EXPAND_AS_DEFINED": "",
"SKIP_FUNCTION_MACROS": "NO",
"EXCLUDE_PATTERNS": "*/tools/* */TESTS/* */targets/* */FEATURE_*/* */features/mbedtls/* */features/storage/* */features/unsupported/* */features/filesystem/* */BUILD/* */rtos/rtx*/* */cmsis/* */features/FEATURES_*"

View File

@ -1,5 +1,13 @@
# Change Log
## [v4.0.9](https://github.com/ARMmbed/mbed-coap/releases/tag/v4.0.9)
-[Full Changelog](https://github.com/ARMmbed/mbed-coap/compare/v4.0.8...v4.0.9)
**Closed issues:**
- IOTCLT-1899 Maximum COAP message resending buffer size limited to 255 bytes
- IOTCLT-1888 Problem with blockwise transfers that are even increments of block_size
## [v4.0.8](https://github.com/ARMmbed/mbed-coap/releases/tag/v4.0.8)
-[Full Changelog](https://github.com/ARMmbed/mbed-coap/compare/v4.0.4...v4.0.8)

View File

@ -1,6 +1,6 @@
{
"name": "mbed-coap",
"version": "4.0.8",
"version": "4.0.9",
"description": "COAP library",
"keywords": [
"coap",

View File

@ -225,7 +225,7 @@ struct coap_s {
uint32_t system_time; /* System time seconds */
uint16_t sn_coap_block_data_size;
uint8_t sn_coap_resending_queue_msgs;
uint8_t sn_coap_resending_queue_bytes;
uint32_t sn_coap_resending_queue_bytes;
uint8_t sn_coap_resending_count;
uint8_t sn_coap_resending_intervall;
uint8_t sn_coap_duplication_buffer_size;

View File

@ -2027,7 +2027,7 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn
original_payload_len = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len;
original_payload_ptr = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr;
if ((block_size * (block_number + 1)) > stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len) {
if ((block_size * (block_number + 1)) >= stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len) {
src_coap_blockwise_ack_msg_ptr->payload_len = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len - (block_size * block_number);
src_coap_blockwise_ack_msg_ptr->payload_ptr = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr + (block_size * block_number);
}
@ -2080,7 +2080,7 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn
stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len = original_payload_len;
stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr = original_payload_ptr;
if ((block_size * (block_number + 1)) > stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len) {
if ((block_size * (block_number + 1)) >= stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len) {
sn_coap_protocol_linked_list_blockwise_msg_remove(handle, stored_blockwise_msg_temp_ptr);
}

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2012-2015, 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 LWIPOPTS_CONF_H
#define LWIPOPTS_CONF_H
#define LWIP_TRANSPORT_ETHERNET 1
#define ETH_PAD_SIZE 2
#define MEM_SIZE (16*1024)//(8*1024)//(16*1024)
#endif

View File

@ -0,0 +1,378 @@
/*
* Copyright (c) 2017 Nuvoton Technology Corp.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Description: M480 MAC driver source file
*/
#include "m480_eth.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "mbed_toolchain.h"
#define ETH_TRIGGER_RX() do{EMAC->RXST = 0;}while(0)
#define ETH_TRIGGER_TX() do{EMAC->TXST = 0;}while(0)
#define ETH_ENABLE_TX() do{EMAC->CTL |= EMAC_CTL_TXON;}while(0)
#define ETH_ENABLE_RX() do{EMAC->CTL |= EMAC_CTL_RXON;}while(0)
#define ETH_DISABLE_TX() do{EMAC->CTL &= ~EMAC_CTL_TXON;}while(0)
#define ETH_DISABLE_RX() do{EMAC->CTL &= ~EMAC_CTL_RXON;}while(0)
/*
#ifdef __ICCARM__
#pragma data_alignment=4
struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM];
struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM];
#else
struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
#endif
*/
MBED_ALIGN(4) struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM];
MBED_ALIGN(4) struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM];
struct eth_descriptor volatile *cur_tx_desc_ptr, *cur_rx_desc_ptr, *fin_tx_desc_ptr;
MBED_ALIGN(4) u8_t rx_buf[RX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
MBED_ALIGN(4) u8_t tx_buf[TX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
extern void ethernetif_input(u16_t len, u8_t *buf, u32_t s, u32_t ns);
extern void ethernetif_loopback_input(struct pbuf *p);
extern void ack_emac_rx_isr(void);
// PTP source clock is 84MHz (Real chip using PLL). Each tick is 11.90ns
// Assume we want to set each tick to 100ns.
// Increase register = (100 * 2^31) / (10^9) = 214.71 =~ 215 = 0xD7
// Addend register = 2^32 * tick_freq / (84MHz), where tick_freq = (2^31 / 215) MHz
// From above equation, addend register = 2^63 / (84M * 215) ~= 510707200 = 0x1E70C600
static void mdio_write(u8_t addr, u8_t reg, u16_t val)
{
EMAC->MIIMDAT = val;
EMAC->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_WRITE_Msk | EMAC_MIIMCTL_MDCON_Msk;
while (EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk);
}
static u16_t mdio_read(u8_t addr, u8_t reg)
{
EMAC->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_MDCON_Msk;
while (EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk);
return(EMAC->MIIMDAT);
}
static int reset_phy(void)
{
u16_t reg;
u32_t delayCnt;
mdio_write(CONFIG_PHY_ADDR, MII_BMCR, BMCR_RESET);
delayCnt = 2000;
while(delayCnt-- > 0) {
if((mdio_read(CONFIG_PHY_ADDR, MII_BMCR) & BMCR_RESET) == 0)
break;
}
if(delayCnt == 0) {
LWIP_DEBUGF(LWIP_DBG_LEVEL_SEVERE|LWIP_DBG_ON,("Reset phy failed\n"));
return(-1);
}
mdio_write(CONFIG_PHY_ADDR, MII_ADVERTISE, ADVERTISE_CSMA |
ADVERTISE_10HALF |
ADVERTISE_10FULL |
ADVERTISE_100HALF |
ADVERTISE_100FULL);
reg = mdio_read(CONFIG_PHY_ADDR, MII_BMCR);
mdio_write(CONFIG_PHY_ADDR, MII_BMCR, reg | BMCR_ANRESTART);
delayCnt = 200000;
while(delayCnt-- > 0) {
if((mdio_read(CONFIG_PHY_ADDR, MII_BMSR) & (BMSR_ANEGCOMPLETE | BMSR_LSTATUS))
== (BMSR_ANEGCOMPLETE | BMSR_LSTATUS))
break;
}
if(delayCnt == 0) {
LWIP_DEBUGF(LWIP_DBG_LEVEL_SEVERE|LWIP_DBG_ON , ("AN failed. Set to 100 FULL\n"));
EMAC->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
return(-1);
} else {
reg = mdio_read(CONFIG_PHY_ADDR, MII_LPA);
if(reg & ADVERTISE_100FULL) {
LWIP_DEBUGF(LWIP_DBG_LEVEL_ALL|LWIP_DBG_ON, ("100 full\n"));
EMAC->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
} else if(reg & ADVERTISE_100HALF) {
LWIP_DEBUGF(LWIP_DBG_LEVEL_ALL|LWIP_DBG_ON, ("100 half\n"));
EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_FUDUP_Msk) | EMAC_CTL_OPMODE_Msk;
} else if(reg & ADVERTISE_10FULL) {
LWIP_DEBUGF(LWIP_DBG_LEVEL_ALL|LWIP_DBG_ON, ("10 full\n"));
EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_OPMODE_Msk) | EMAC_CTL_FUDUP_Msk;
} else {
LWIP_DEBUGF(LWIP_DBG_LEVEL_ALL|LWIP_DBG_ON, ("10 half\n"));
EMAC->CTL &= ~(EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
}
}
printf("PHY ID 1:0x%x\r\n", mdio_read(CONFIG_PHY_ADDR, MII_PHYSID1));
printf("PHY ID 2:0x%x\r\n", mdio_read(CONFIG_PHY_ADDR, MII_PHYSID2));
return(0);
}
static void init_tx_desc(void)
{
u32_t i;
cur_tx_desc_ptr = fin_tx_desc_ptr = &tx_desc[0];
for(i = 0; i < TX_DESCRIPTOR_NUM; i++) {
tx_desc[i].status1 = TXFD_PADEN | TXFD_CRCAPP | TXFD_INTEN;
tx_desc[i].buf = &tx_buf[i][0];
tx_desc[i].status2 = 0;
tx_desc[i].next = &tx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
}
EMAC->TXDSA = (unsigned int)&tx_desc[0];
return;
}
static void init_rx_desc(void)
{
u32_t i;
cur_rx_desc_ptr = &rx_desc[0];
for(i = 0; i < RX_DESCRIPTOR_NUM; i++) {
rx_desc[i].status1 = OWNERSHIP_EMAC;
rx_desc[i].buf = &rx_buf[i][0];
rx_desc[i].status2 = 0;
rx_desc[i].next = &rx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
}
EMAC->RXDSA = (unsigned int)&rx_desc[0];
return;
}
static void set_mac_addr(u8_t *addr)
{
EMAC->CAM0M = (addr[0] << 24) |
(addr[1] << 16) |
(addr[2] << 8) |
addr[3];
EMAC->CAM0L = (addr[4] << 24) |
(addr[5] << 16);
}
static void __eth_clk_pin_init()
{
/* Unlock protected registers */
SYS_UnlockReg();
/* Enable IP clock */
CLK_EnableModuleClock(EMAC_MODULE);
// Configure MDC clock rate to HCLK / (127 + 1) = 1.25 MHz if system is running at 160 MH
CLK_SetModuleClock(EMAC_MODULE, 0, CLK_CLKDIV3_EMAC(127));
/* Update System Core Clock */
SystemCoreClockUpdate();
/*---------------------------------------------------------------------------------------------------------*/
/* Init I/O Multi-function */
/*---------------------------------------------------------------------------------------------------------*/
// Configure RMII pins
SYS->GPA_MFPL = SYS_GPA_MFPL_PA6MFP_EMAC_RMII_RXERR | SYS_GPA_MFPL_PA7MFP_EMAC_RMII_CRSDV;
SYS->GPC_MFPL = SYS_GPC_MFPL_PC6MFP_EMAC_RMII_RXD1 | SYS_GPC_MFPL_PC7MFP_EMAC_RMII_RXD0;
SYS->GPC_MFPH = SYS_GPC_MFPH_PC8MFP_EMAC_RMII_REFCLK;
SYS->GPE_MFPH = SYS_GPE_MFPH_PE8MFP_EMAC_RMII_MDC |
SYS_GPE_MFPH_PE9MFP_EMAC_RMII_MDIO |
SYS_GPE_MFPH_PE10MFP_EMAC_RMII_TXD0 |
SYS_GPE_MFPH_PE11MFP_EMAC_RMII_TXD1 |
SYS_GPE_MFPH_PE12MFP_EMAC_RMII_TXEN;
// Enable high slew rate on all RMII TX output pins
PE->SLEWCTL = (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN10_Pos) |
(GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN11_Pos) |
(GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN12_Pos);
/* Lock protected registers */
SYS_LockReg();
}
void ETH_init(u8_t *mac_addr)
{
// init CLK & pins
__eth_clk_pin_init();
// Reset MAC
EMAC->CTL = EMAC_CTL_RST_Msk;
while(EMAC->CTL & EMAC_CTL_RST_Msk) {}
init_tx_desc();
init_rx_desc();
set_mac_addr(mac_addr); // need to reconfigure hardware address 'cos we just RESET emc...
/* Configure the MAC interrupt enable register. */
EMAC->INTEN = EMAC_INTEN_RXIEN_Msk |
EMAC_INTEN_TXIEN_Msk |
EMAC_INTEN_RXGDIEN_Msk |
EMAC_INTEN_TXCPIEN_Msk |
EMAC_INTEN_RXBEIEN_Msk |
EMAC_INTEN_TXBEIEN_Msk |
EMAC_INTEN_RDUIEN_Msk |
EMAC_INTEN_TSALMIEN_Msk |
EMAC_INTEN_WOLIEN_Msk;
/* Configure the MAC control register. */
EMAC->CTL = EMAC_CTL_STRIPCRC_Msk | EMAC_CTL_RMIIEN_Msk;
/* Accept packets for us and all broadcast and multicast packets */
EMAC->CAMCTL = EMAC_CAMCTL_CMPEN_Msk |
EMAC_CAMCTL_AMP_Msk |
EMAC_CAMCTL_ABP_Msk;
EMAC->CAMEN = 1; // Enable CAM entry 0
reset_phy();
EMAC_ENABLE_RX();
EMAC_ENABLE_TX();
}
void ETH_halt(void)
{
EMAC->CTL &= ~(EMAC_CTL_RXON_Msk | EMAC_CTL_TXON_Msk);
}
unsigned int m_status;
void EMAC_RX_IRQHandler(void)
{
m_status = EMAC->INTSTS & 0xFFFF;
EMAC->INTSTS = m_status;
if (m_status & EMAC_INTSTS_RXBEIF_Msk) {
// Shouldn't goes here, unless descriptor corrupted
LWIP_DEBUGF(LWIP_DBG_LEVEL_SERIOUS|LWIP_DBG_ON, ("RX descriptor corrupted \r\n"));
//return;
}
ack_emac_rx_isr();
}
void EMAC_RX_Action(void)
{
unsigned int cur_entry, status;
do {
cur_entry = EMAC->CRXDSA;
if ((cur_entry == (u32_t)cur_rx_desc_ptr) && (!(m_status & EMAC_INTSTS_RDUIF_Msk))) // cur_entry may equal to cur_rx_desc_ptr if RDU occures
break;
status = cur_rx_desc_ptr->status1;
if(status & OWNERSHIP_EMAC)
break;
if (status & RXFD_RXGD) {
// Lwip will invoke osMutexWait for resource protection, so ethernetif_input can't be called in EMAC_RX_IRQHandler.
ethernetif_input(status & 0xFFFF, cur_rx_desc_ptr->buf, cur_rx_desc_ptr->status2, (u32_t)cur_rx_desc_ptr->next);
}
cur_rx_desc_ptr->status1 = OWNERSHIP_EMAC;
cur_rx_desc_ptr = cur_rx_desc_ptr->next;
} while (1);
ETH_TRIGGER_RX();
}
void EMAC_TX_IRQHandler(void)
{
unsigned int cur_entry, status;
status = EMAC->INTSTS & 0xFFFF0000;
EMAC->INTSTS = status;
if(status & EMAC_INTSTS_TXBEIF_Msk) {
// Shouldn't goes here, unless descriptor corrupted
return;
}
cur_entry = EMAC->CTXDSA;
while (cur_entry != (u32_t)fin_tx_desc_ptr) {
fin_tx_desc_ptr = fin_tx_desc_ptr->next;
}
}
u8_t *ETH_get_tx_buf(void)
{
if(cur_tx_desc_ptr->status1 & OWNERSHIP_EMAC)
return(NULL);
else
return(cur_tx_desc_ptr->buf);
}
void ETH_trigger_tx(u16_t length, struct pbuf *p)
{
struct eth_descriptor volatile *desc;
cur_tx_desc_ptr->status2 = (unsigned int)length;
desc = cur_tx_desc_ptr->next; // in case TX is transmitting and overwrite next pointer before we can update cur_tx_desc_ptr
cur_tx_desc_ptr->status1 |= OWNERSHIP_EMAC;
cur_tx_desc_ptr = desc;
ETH_TRIGGER_TX();
}
int ETH_link_ok()
{
/* first, a dummy read to latch */
mdio_read(CONFIG_PHY_ADDR, MII_BMSR);
if(mdio_read(CONFIG_PHY_ADDR, MII_BMSR) & BMSR_LSTATUS)
return 1;
return 0;
}

View File

@ -0,0 +1,150 @@
/*
* Copyright (c) 2016 Nuvoton Technology Corp.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Description: M480 EMAC driver header file
*/
#include "lwip/def.h"
#include "lwip/pbuf.h"
#include "M480.h"
#ifndef _M480_ETH_
#define _M480_ETH_
/* Generic MII registers. */
#define MII_BMCR 0x00 /* Basic mode control register */
#define MII_BMSR 0x01 /* Basic mode status register */
#define MII_PHYSID1 0x02 /* PHYS ID 1 */
#define MII_PHYSID2 0x03 /* PHYS ID 2 */
#define MII_ADVERTISE 0x04 /* Advertisement control reg */
#define MII_LPA 0x05 /* Link partner ability reg */
#define MII_EXPANSION 0x06 /* Expansion register */
#define MII_DCOUNTER 0x12 /* Disconnect counter */
#define MII_FCSCOUNTER 0x13 /* False carrier counter */
#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
#define MII_RERRCOUNTER 0x15 /* Receive error counter */
#define MII_SREVISION 0x16 /* Silicon revision */
#define MII_RESV1 0x17 /* Reserved... */
#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
#define MII_PHYADDR 0x19 /* PHY address */
#define MII_RESV2 0x1a /* Reserved... */
#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
#define MII_NCONFIG 0x1c /* Network interface config */
/* Basic mode control register. */
#define BMCR_RESV 0x007f /* Unused... */
#define BMCR_CTST 0x0080 /* Collision test */
#define BMCR_FULLDPLX 0x0100 /* Full duplex */
#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
#define BMCR_RESET 0x8000 /* Reset the DP83840 */
/* Basic mode status register. */
#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
#define BMSR_JCD 0x0002 /* Jabber detected */
#define BMSR_LSTATUS 0x0004 /* Link status */
#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
#define BMSR_RFAULT 0x0010 /* Remote fault detected */
#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
#define BMSR_RESV 0x07c0 /* Unused... */
#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
/* Advertisement control register. */
#define ADVERTISE_SLCT 0x001f /* Selector bits */
#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
#define ADVERTISE_RESV 0x1c00 /* Unused... */
#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
#define RX_DESCRIPTOR_NUM 4 //2 // 4: Max Number of Rx Frame Descriptors
#define TX_DESCRIPTOR_NUM 4 //2 // 4: Max number of Tx Frame Descriptors
#define PACKET_BUFFER_SIZE 1520
#define CONFIG_PHY_ADDR 1
// Frame Descriptor's Owner bit
#define OWNERSHIP_EMAC 0x80000000 // 1 = EMAC
//#define OWNERSHIP_CPU 0x7fffffff // 0 = CPU
// Rx Frame Descriptor Status
#define RXFD_RXGD 0x00100000 // Receiving Good Packet Received
#define RXFD_RTSAS 0x00800000 // RX Time Stamp Available
// Tx Frame Descriptor's Control bits
#define TXFD_TTSEN 0x08 // Tx Time Stamp Enable
#define TXFD_INTEN 0x04 // Interrupt Enable
#define TXFD_CRCAPP 0x02 // Append CRC
#define TXFD_PADEN 0x01 // Padding Enable
// Tx Frame Descriptor Status
#define TXFD_TXCP 0x00080000 // Transmission Completion
#define TXFD_TTSAS 0x08000000 // TX Time Stamp Available
// Tx/Rx buffer descriptor structure
struct eth_descriptor;
struct eth_descriptor {
u32_t status1;
u8_t *buf;
u32_t status2;
struct eth_descriptor *next;
#ifdef TIME_STAMPING
u32_t backup1;
u32_t backup2;
u32_t reserved1;
u32_t reserved2;
#endif
};
#ifdef TIME_STAMPING
#define ETH_TS_ENABLE() do{EMAC->TSCTL = EMAC_TSCTL_TSEN_Msk;}while(0)
#define ETH_TS_START() do{EMAC->TSCTL |= (EMAC_TSCTL_TSMODE_Msk | EMAC_TSCTL_TSIEN_Msk);}while(0)
s32_t ETH_settime(u32_t sec, u32_t nsec);
s32_t ETH_gettime(u32_t *sec, u32_t *nsec);
s32_t ETH_updatetime(u32_t neg, u32_t sec, u32_t nsec);
s32_t ETH_adjtimex(int ppm);
void ETH_setinc(void);
#endif
extern void ETH_init(u8_t *mac_addr);
extern u8_t *ETH_get_tx_buf(void);
extern void ETH_trigger_tx(u16_t length, struct pbuf *p);
#endif /* _M480_ETH_ */

View File

@ -0,0 +1,530 @@
/**
* @file
* Ethernet Interface Skeleton
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*
* This file is a skeleton for developing Ethernet network interface
* drivers for lwIP. Add code to the low_level functions and do a
* search-and-replace for the word "ethernetif" to replace it with
* something that better describes your network interface.
*/
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include <lwip/stats.h>
#include <lwip/snmp.h>
#include "netif/etharp.h"
#include "lwip/ethip6.h"
#include "netif/ppp/pppoe.h"
#include "m480_eth.h"
#include "string.h"
#include "eth_arch.h"
#include "sys_arch.h"
#include <ctype.h>
#include <stdio.h>
#include "mbed_interface.h"
#include "cmsis.h"
/* Define those to better describe your network interface. */
#define IFNAME0 'e'
#define IFNAME1 'n'
// Fow now, all interrupt handling happens inside one single handler, so we need to figure
// out what actually triggered the interrupt.
static volatile uint8_t emac_timer_fired;
volatile uint8_t allow_net_callbacks;
struct netif *_netif;
unsigned char my_mac_addr[6] = {0x02, 0x00, 0xac, 0x55, 0x66, 0x88};
extern u8_t my_mac_addr[6];
extern int ETH_link_ok(void);
extern void EMAC_RX_Action(void);
sys_sem_t RxReadySem; /**< RX packet ready semaphore */
static void __phy_task(void *data);
static void __packet_rx_task(void *data);
/**
* Helper struct to hold private data used to operate your ethernet interface.
* Keeping the ethernet address of the MAC in this struct is not necessary
* as it is already kept in the struct netif.
* But this is only an example, anyway...
*/
struct ethernetif {
struct eth_addr *ethaddr;
/* Add whatever per-interface state that is needed here. */
};
// Override mbed_mac_address of mbed_interface.c to provide ethernet devices with a semi-unique MAC address
void mbed_mac_address(char *mac)
{
uint32_t uID1;
// Fetch word 0
uint32_t word0 = *(uint32_t *)0x7F804; // 2KB Data Flash at 0x7F800
// Fetch word 1
// we only want bottom 16 bits of word1 (MAC bits 32-47)
// and bit 9 forced to 1, bit 8 forced to 0
// Locally administered MAC, reduced conflicts
// http://en.wikipedia.org/wiki/MAC_address
uint32_t word1 = *(uint32_t *)0x7F800; // 2KB Data Flash at 0x7F800
if( word0 == 0xFFFFFFFF ) // Not burn any mac address at 1st 2 words of Data Flash
{
// with a semi-unique MAC address from the UUID
/* Enable FMC ISP function */
SYS_UnlockReg();
FMC_Open();
// = FMC_ReadUID(0);
uID1 = FMC_ReadUID(1);
word1 = (uID1 & 0x003FFFFF) | ((uID1 & 0x030000) << 6) >> 8;
word0 = ((FMC_ReadUID(0) >> 4) << 20) | ((uID1 & 0xFF)<<12) | (FMC_ReadUID(2) & 0xFFF);
/* Disable FMC ISP function */
FMC_Close();
/* Lock protected registers */
SYS_LockReg();
}
word1 |= 0x00000200;
word1 &= 0x0000FEFF;
mac[0] = (word1 & 0x0000ff00) >> 8;
mac[1] = (word1 & 0x000000ff);
mac[2] = (word0 & 0xff000000) >> 24;
mac[3] = (word0 & 0x00ff0000) >> 16;
mac[4] = (word0 & 0x0000ff00) >> 8;
mac[5] = (word0 & 0x000000ff);
// printf("mac address %02x-%02x-%02x-%02x-%02x-%02x \r\n", mac[0], mac[1],mac[2],mac[3],mac[4],mac[5]);
}
/**
* In this function, the hardware should be initialized.
* Called from ethernetif_init().
*
* @param netif the already initialized lwip network interface structure
* for this ethernetif
*/
static void
low_level_init(struct netif *netif)
{
/* set MAC hardware address length */
netif->hwaddr_len = ETH_HWADDR_LEN;
/* set MAC hardware address */
#if 1 // set MAC HW address
#if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE)
netif->hwaddr[0] = MBED_MAC_ADDR_0;
netif->hwaddr[1] = MBED_MAC_ADDR_1;
netif->hwaddr[2] = MBED_MAC_ADDR_2;
netif->hwaddr[3] = MBED_MAC_ADDR_3;
netif->hwaddr[4] = MBED_MAC_ADDR_4;
netif->hwaddr[5] = MBED_MAC_ADDR_5;
#else
mbed_mac_address((char *)netif->hwaddr);
#endif /* set MAC HW address */
#else
netif->hwaddr[0] = my_mac_addr[0];
netif->hwaddr[1] = my_mac_addr[1];
netif->hwaddr[2] = my_mac_addr[2];
netif->hwaddr[3] = my_mac_addr[3];
netif->hwaddr[4] = my_mac_addr[4];
netif->hwaddr[5] = my_mac_addr[5];
#endif // endif
/* maximum transfer unit */
netif->mtu = 1500;
/* device capabilities */
/* NETIF_FLAG_LINK_UP should be enabled by netif_set_link_up() */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET;
#ifdef LWIP_IGMP
netif->flags |= NETIF_FLAG_IGMP;
#endif
#if LWIP_IPV6_MLD
netif->flags |= NETIF_FLAG_MLD6;
#endif
// TODO: enable clock & configure GPIO function
ETH_init(netif->hwaddr);
#if LWIP_IGMP
EMAC_ENABLE_RECV_BCASTPKT();
#endif
#if LWIP_IPV6_MLD
EMAC_ENABLE_RECV_MCASTPKT();
#endif
}
/**
* This function should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
* @param netif the lwip network interface structure for this ethernetif
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
*
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
* strange results. You might consider waiting for space in the DMA queue
* to become availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
static err_t
low_level_output(struct netif *netif, struct pbuf *p)
{
struct pbuf *q;
u8_t *buf = NULL;
u16_t len = 0;
buf = ETH_get_tx_buf();
if(buf == NULL)
return ERR_MEM;
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
for(q = p; q != NULL; q = q->next) {
memcpy((u8_t*)&buf[len], q->payload, q->len);
len = len + q->len;
}
#ifdef TIME_STAMPING
ETH_trigger_tx(len, p->flags & PBUF_FLAG_GET_TXTS ? p : NULL);
#else
ETH_trigger_tx(len, NULL);
#endif
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
LINK_STATS_INC(link.xmit);
return ERR_OK;
}
/**
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
* @param netif the lwip network interface structure for this ethernetif
* @return a pbuf filled with the received packet (including MAC header)
* NULL on memory error
*/
static struct pbuf *
low_level_input(struct netif *netif, u16_t len, u8_t *buf)
{
struct pbuf *p, *q;
#if ETH_PAD_SIZE
len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
#endif
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
if (p != NULL) {
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
len = 0;
/* We iterate over the pbuf chain until we have read the entire
* packet into the pbuf. */
for(q = p; q != NULL; q = q->next) {
memcpy((u8_t*)q->payload, (u8_t*)&buf[len], q->len);
len = len + q->len;
}
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
LINK_STATS_INC(link.recv);
} else {
// do nothing. drop the packet
LINK_STATS_INC(link.memerr);
LINK_STATS_INC(link.drop);
}
return p;
}
/**
* This function should be called when a packet is ready to be read
* from the interface. It uses the function low_level_input() that
* should handle the actual reception of bytes from the network
* interface. Then the type of the received packet is determined and
* the appropriate input function is called.
*
* @param netif the lwip network interface structure for this ethernetif
*/
void
ethernetif_input(u16_t len, u8_t *buf, u32_t s, u32_t ns)
{
struct eth_hdr *ethhdr;
struct pbuf *p;
/* move received packet into a new pbuf */
p = low_level_input(_netif, len, buf);
/* no packet could be read, silently ignore this */
if (p == NULL) return;
#ifdef TIME_STAMPING
p->ts_sec = s;
p->ts_nsec = ns;
#endif
/* points to packet payload, which starts with an Ethernet header */
ethhdr = p->payload;
switch (htons(ethhdr->type)) {
/* IP or ARP packet? */
case ETHTYPE_IP:
case ETHTYPE_ARP:
#if PPPOE_SUPPORT
/* PPPoE packet? */
case ETHTYPE_PPPOEDISC:
case ETHTYPE_PPPOE:
#endif /* PPPOE_SUPPORT */
/* full packet send to tcpip_thread to process */
if (_netif->input(p, _netif)!=ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
p = NULL;
}
break;
default:
pbuf_free(p);
p = NULL;
break;
}
}
#ifdef TIME_STAMPING
void
ethernetif_loopback_input(struct pbuf *p) // TODO: make sure packet not drop in input()
{
/* pass all packets to ethernet_input, which decides what packets it supports */
if (netif->input(p, netif) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("k64f_enetif_input: input error\n"));
/* Free buffer */
pbuf_free(p);
}
}
#endif
/**
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to netif_add().
*
* @param netif the lwip network interface structure for this ethernetif
* @return ERR_OK if the loopif is initialized
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t
eth_arch_enetif_init(struct netif *netif)
{
err_t err;
struct ethernetif *ethernetif;
LWIP_ASSERT("netif != NULL", (netif != NULL));
_netif = netif;
ethernetif = mem_malloc(sizeof(struct ethernetif));
if (ethernetif == NULL) {
LWIP_DEBUGF(NETIF_DEBUG, (" eth_arch_enetif_init: out of memory\n"));
return ERR_MEM;
}
// Chris: The initialization code uses osDelay, so timers neet to run
// SysTick_Init();
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = "m480";
#endif /* LWIP_NETIF_HOSTNAME */
/*
* Initialize the snmp variables and counters inside the struct netif.
* The last argument should be replaced with your link speed, in units
* of bits per second.
*/
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
netif->state = ethernetif;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...) */
#if LWIP_IPV4
netif->output = etharp_output;
#endif
#if LWIP_IPV6
netif->output_ip6 = ethip6_output;
#endif
netif->linkoutput = low_level_output;
ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
/* initialize the hardware */
low_level_init(netif);
/* Packet receive task */
err = sys_sem_new(&RxReadySem, 0);
if(err != ERR_OK) {
LWIP_ASSERT("RxReadySem creation error", (err == ERR_OK));
}
// In GCC code, DEFAULT_THREAD_STACKSIZE 512 bytes is not enough for rx_task
#if defined (__GNUC__)
// mbed OS 2.0, DEFAULT_THREAD_STACKSIZE*3
// mbed OS 5.0, DEFAULT_THREAD_STACKSIZE*5
sys_thread_new("receive_thread", __packet_rx_task, &RxReadySem, DEFAULT_THREAD_STACKSIZE*5, osPriorityNormal);
#else
sys_thread_new("receive_thread", __packet_rx_task, &RxReadySem, DEFAULT_THREAD_STACKSIZE, osPriorityNormal);
#endif
/* PHY monitoring task */
#if defined (__GNUC__)
// mbed OS 2.0, DEFAULT_THREAD_STACKSIZE
// mbed OS 5.0, DEFAULT_THREAD_STACKSIZE*2
sys_thread_new("phy_thread", __phy_task, netif, DEFAULT_THREAD_STACKSIZE*2, osPriorityNormal);
#else
sys_thread_new("phy_thread", __phy_task, netif, DEFAULT_THREAD_STACKSIZE, osPriorityNormal);
#endif
/* Allow the PHY task to detect the initial link state and set up the proper flags */
osDelay(10);
return ERR_OK;
}
void eth_arch_enable_interrupts(void) {
// enet_hal_config_interrupt(BOARD_DEBUG_ENET_INSTANCE_ADDR, (kEnetTxFrameInterrupt | kEnetRxFrameInterrupt), true);
EMAC->INTEN |= EMAC_INTEN_RXIEN_Msk |
EMAC_INTEN_TXIEN_Msk ;
NVIC_EnableIRQ(EMAC_RX_IRQn);
NVIC_EnableIRQ(EMAC_TX_IRQn);
}
void eth_arch_disable_interrupts(void) {
NVIC_DisableIRQ(EMAC_RX_IRQn);
NVIC_DisableIRQ(EMAC_TX_IRQn);
}
/* Defines the PHY link speed */
typedef enum _phy_speed
{
kPHY_Speed10M = 0U, /* ENET PHY 10M speed. */
kPHY_Speed100M /* ENET PHY 100M speed. */
} phy_speed_t;
/* Defines the PHY link duplex. */
typedef enum _phy_duplex
{
kPHY_HalfDuplex = 0U, /* ENET PHY half duplex. */
kPHY_FullDuplex /* ENET PHY full duplex. */
} phy_duplex_t;
typedef struct {
int connected;
phy_speed_t speed;
phy_duplex_t duplex;
} PHY_STATE;
#define STATE_UNKNOWN (-1)
static void __phy_task(void *data) {
struct netif *netif = (struct netif*)data;
// PHY_STATE crt_state = {STATE_UNKNOWN, (phy_speed_t)STATE_UNKNOWN, (phy_duplex_t)STATE_UNKNOWN};
// PHY_STATE prev_state;
// prev_state = crt_state;
while (1) {
// Get current status
// Get the actual PHY link speed
// Compare with previous state
if( !(ETH_link_ok()) && (netif->flags & NETIF_FLAG_LINK_UP) ) {
/* tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_down, (void*) netif, 1); */
netif_set_link_down(netif);
LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING|LWIP_DBG_ON, ("Link Down\r\n"));
}else if ( ETH_link_ok() && !(netif->flags & NETIF_FLAG_LINK_UP) ) {
/* tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_up, (void*) netif, 1); */
netif_set_link_up(netif);
LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING|LWIP_DBG_ON, ("Link Up\r\n"));
}
osDelay(200);
}
}
void ack_emac_rx_isr()
{
sys_sem_signal(&RxReadySem);
}
static void __packet_rx_task(void *data) {
while (1) {
/* Wait for receive task to wakeup */
sys_arch_sem_wait(&RxReadySem, 0);
EMAC_RX_Action();
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2016 Nuvoton Technology Corp.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Description: EMAC driver header file
*/
#ifndef __ETHERNETIF_H__
#define __ETHERNETIF_H__
#include "lwip/err.h"
#include "lwip/netif.h"
#if defined(__cplusplus)
extern "C" {
#endif
//extern sys_sem_t tx_sem;
extern sys_sem_t rx_sem;
//err_t ethernetif_init(struct netif *netif);
//err_t ethernetif_input(struct netif *netif);
//struct netif *ethernetif_register(void);
//int ethernetif_poll(void);
#if defined(__cplusplus)
}
#endif
#ifdef SERVER
#define MAC_ADDR0 0x00
#define MAC_ADDR1 0x00
#define MAC_ADDR2 0x00
#define MAC_ADDR3 0x00
#define MAC_ADDR4 0x00
#define MAC_ADDR5 0x01
#else
#define MAC_ADDR0 0x00
#define MAC_ADDR1 0x00
#define MAC_ADDR2 0x00
#define MAC_ADDR3 0x00
#define MAC_ADDR4 0x00
//#define MAC_ADDR5 0x02
#define MAC_ADDR5 0x03
//#define MAC_ADDR5 0x04
#endif
#endif

View File

@ -21,6 +21,7 @@
#include "HeapBlockDevice.h"
#include "SlicingBlockDevice.h"
#include "ChainingBlockDevice.h"
#include "ProfilingBlockDevice.h"
#include <stdlib.h>
using namespace utest::v1;
@ -176,6 +177,67 @@ void test_chaining() {
TEST_ASSERT_EQUAL(0, err);
}
// Simple test which read/writes blocks on a chain of block devices
void test_profiling() {
HeapBlockDevice bd(BLOCK_COUNT*BLOCK_SIZE, BLOCK_SIZE);
uint8_t *write_block = new uint8_t[BLOCK_SIZE];
uint8_t *read_block = new uint8_t[BLOCK_SIZE];
// Test under profiling
ProfilingBlockDevice profiler(&bd);
int err = profiler.init();
TEST_ASSERT_EQUAL(0, err);
TEST_ASSERT_EQUAL(BLOCK_SIZE, profiler.get_erase_size());
TEST_ASSERT_EQUAL(BLOCK_COUNT*BLOCK_SIZE, profiler.size());
// Fill with random sequence
srand(1);
for (int i = 0; i < BLOCK_SIZE; i++) {
write_block[i] = 0xff & rand();
}
// Write, sync, and read the block
err = profiler.erase(0, BLOCK_SIZE);
TEST_ASSERT_EQUAL(0, err);
err = profiler.program(write_block, 0, BLOCK_SIZE);
TEST_ASSERT_EQUAL(0, err);
err = profiler.read(read_block, 0, BLOCK_SIZE);
TEST_ASSERT_EQUAL(0, err);
// Check that the data was unmodified
srand(1);
for (int i = 0; i < BLOCK_SIZE; i++) {
TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]);
}
// Check with original block device
err = bd.read(read_block, 0, BLOCK_SIZE);
TEST_ASSERT_EQUAL(0, err);
// Check that the data was unmodified
srand(1);
for (int i = 0; i < BLOCK_SIZE; i++) {
TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]);
}
delete[] write_block;
delete[] read_block;
err = profiler.deinit();
TEST_ASSERT_EQUAL(0, err);
// Check that profiled operations match expectations
bd_size_t read_count = profiler.get_read_count();
TEST_ASSERT_EQUAL(BLOCK_SIZE, read_count);
bd_size_t program_count = profiler.get_program_count();
TEST_ASSERT_EQUAL(BLOCK_SIZE, program_count);
bd_size_t erase_count = profiler.get_erase_count();
TEST_ASSERT_EQUAL(BLOCK_SIZE, erase_count);
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
@ -186,6 +248,7 @@ utest::v1::status_t test_setup(const size_t number_of_cases) {
Case cases[] = {
Case("Testing slicing of a block device", test_slicing),
Case("Testing chaining of block devices", test_chaining),
Case("Testing profiling of block devices", test_profiling),
};
Specification specification(test_setup, cases);

View File

@ -0,0 +1,105 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* 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 "ProfilingBlockDevice.h"
ProfilingBlockDevice::ProfilingBlockDevice(BlockDevice *bd)
: _bd(bd)
, _read_count(0)
, _program_count(0)
, _erase_count(0)
{
}
int ProfilingBlockDevice::init()
{
return _bd->init();
}
int ProfilingBlockDevice::deinit()
{
return _bd->deinit();
}
int ProfilingBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
{
int err = _bd->read(b, addr, size);
if (!err) {
_read_count += size;
}
return err;
}
int ProfilingBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
{
int err = _bd->program(b, addr, size);
if (!err) {
_program_count += size;
}
return err;
}
int ProfilingBlockDevice::erase(bd_addr_t addr, bd_size_t size)
{
int err = _bd->erase(addr, size);
if (!err) {
_erase_count += size;
}
return err;
}
bd_size_t ProfilingBlockDevice::get_read_size() const
{
return _bd->get_read_size();
}
bd_size_t ProfilingBlockDevice::get_program_size() const
{
return _bd->get_program_size();
}
bd_size_t ProfilingBlockDevice::get_erase_size() const
{
return _bd->get_erase_size();
}
bd_size_t ProfilingBlockDevice::size() const
{
return _bd->size();
}
void ProfilingBlockDevice::reset()
{
_read_count = 0;
_program_count = 0;
_erase_count = 0;
}
bd_size_t ProfilingBlockDevice::get_read_count() const
{
return _read_count;
}
bd_size_t ProfilingBlockDevice::get_program_count() const
{
return _program_count;
}
bd_size_t ProfilingBlockDevice::get_erase_count() const
{
return _erase_count;
}

View File

@ -0,0 +1,159 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef MBED_PROFILING_BLOCK_DEVICE_H
#define MBED_PROFILING_BLOCK_DEVICE_H
#include "BlockDevice.h"
#include "mbed.h"
/** Block device for measuring storage operations of another block device
*
* @code
* #include "mbed.h"
* #include "HeapBlockDevice.h"
* #include "ProfilingBlockDevice.h"
*
* // Create a heap block device and profiling block device
* HeapBlockDevice mem(64*512, 512);
* ProfilingBlockDevice profiler(&mem);
*
* // do block device work....
*
* printf("read count: %lld\n", profiler.get_read_count());
* printf("program count: %lld\n", profiler.get_program_count());
* printf("erase count: %lld\n", profiler.get_erase_count());
*/
class ProfilingBlockDevice : public BlockDevice
{
public:
/** Lifetime of the memory block device
*
* @param bd Block device to back the ProfilingBlockDevice
*/
ProfilingBlockDevice(BlockDevice *bd);
/** Lifetime of a block device
*/
virtual ~ProfilingBlockDevice() {};
/** Initialize a block device
*
* @return 0 on success or a negative error code on failure
* @note The init and deinit functions do not effect profile counts
*/
virtual int init();
/** Deinitialize a block device
*
* @return 0 on success or a negative error code on failure
* @note The init and deinit functions do not effect profile counts
*/
virtual int deinit();
/** Read blocks from a block device
*
* @param buffer Buffer to read blocks into
* @param addr Address of block to begin reading from
* @param size Size to read in bytes, must be a multiple of read block size
* @return 0 on success, negative error code on failure
*/
virtual int read(void *buffer, bd_addr_t addr, bd_size_t size);
/** Program blocks to a block device
*
* The blocks must have been erased prior to being programmed
*
* @param buffer Buffer of data to write to blocks
* @param addr Address of block to begin writing to
* @param size Size to write in bytes, must be a multiple of program block size
* @return 0 on success, negative error code on failure
*/
virtual int program(const void *buffer, bd_addr_t addr, bd_size_t size);
/** Erase blocks on a block device
*
* The state of an erased block is undefined until it has been programmed
*
* @param addr Address of block to begin erasing
* @param size Size to erase in bytes, must be a multiple of erase block size
* @return 0 on success, negative error code on failure
*/
virtual int erase(bd_addr_t addr, bd_size_t size);
/** Get the size of a readable block
*
* @return Size of a readable block in bytes
*/
virtual bd_size_t get_read_size() const;
/** Get the size of a programable block
*
* @return Size of a programable block in bytes
* @note Must be a multiple of the read size
*/
virtual bd_size_t get_program_size() const;
/** Get the size of a eraseable block
*
* @return Size of a eraseable block in bytes
* @note Must be a multiple of the program size
*/
virtual bd_size_t get_erase_size() const;
/** Get the total size of the underlying device
*
* @return Size of the underlying device in bytes
*/
virtual bd_size_t size() const;
/** Reset the current profile counts to zero
*/
void reset();
/** Get number of bytes that have been read from the block device
*
* @return The number of bytes that have been read from the block device
*/
bd_size_t get_read_count() const;
/** Get number of bytes that have been programed to the block device
*
* @return The number of bytes that have been programed to the block device
*/
bd_size_t get_program_count() const;
/** Get number of bytes that have been erased from the block device
*
* @return The number of bytes that have been erased from the block device
*/
bd_size_t get_erase_count() const;
private:
BlockDevice *_bd;
bd_size_t _read_count;
bd_size_t _program_count;
bd_size_t _erase_count;
};
#endif

View File

@ -0,0 +1,31 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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 MBEDTLS_DEVICE_H
#define MBEDTLS_DEVICE_H
#define MBEDTLS_DES_ALT
#define MBEDTLS_SHA1_ALT
#define MBEDTLS_SHA256_ALT
#define MBEDTLS_SHA512_ALT
#define MBEDTLS_AES_ALT
#define MBEDTLS_AES_SETKEY_ENC_ALT
#define MBEDTLS_AES_SETKEY_DEC_ALT
#define MBEDTLS_AES_ENCRYPT_ALT
#define MBEDTLS_AES_DECRYPT_ALT
#endif /* MBEDTLS_DEVICE_H */

View File

@ -0,0 +1,584 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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.
*/
/*
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
*
* http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_AES_C)
#if defined(MBEDTLS_AES_ALT)
#include <string.h>
#include "mbedtls/aes.h"
#include "M480.h"
#include "mbed_toolchain.h"
#include "mbed_assert.h"
#define mbedtls_trace(...) //printf(__VA_ARGS__)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
}
static uint32_t au32MyAESIV[4] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000
};
extern volatile int g_AES_done;
// Must be a multiple of 16 bytes block size
#define MAX_DMA_CHAIN_SIZE (16*6)
MBED_ALIGN(4) static uint8_t au8OutputData[MAX_DMA_CHAIN_SIZE];
MBED_ALIGN(4) static uint8_t au8InputData[MAX_DMA_CHAIN_SIZE];
static void dumpHex(const unsigned char au8Data[], int len)
{
int j;
for (j = 0; j < len; j++) mbedtls_trace("%02x ", au8Data[j]);
mbedtls_trace("\r\n");
}
static void swapInitVector(unsigned char iv[16])
{
unsigned int* piv;
int i;
// iv SWAP
piv = (unsigned int*)iv;
for( i=0; i< 4; i++)
{
*piv = (((*piv) & 0x000000FF) << 24) |
(((*piv) & 0x0000FF00) << 8) |
(((*piv) & 0x00FF0000) >> 8) |
(((*piv) & 0xFF000000) >> 24);
piv++;
}
}
/* IRQHandler: To share CRYPTO_IRQHandler() with TRNG & other crypto IPs
For ex:
volatile void CRYPTO_IRQHandler()
{
...
if (AES_GET_INT_FLAG()) {
g_AES_done = 1;
AES_CLR_INT_FLAG();
}
...
}
*/
/* AES available channel 0~3 */
static unsigned char channel_flag[4]={0x00,0x00,0x00,0x00}; // 0: idle, 1: busy
static int channel_alloc()
{
int i;
for(i=0; i< (int)sizeof(channel_flag); i++)
{
if( channel_flag[i] == 0x00 )
{
channel_flag[i] = 0x01;
return i;
}
}
return(-1);
}
static void channel_free(int i)
{
if( i >=0 && i < (int)sizeof(channel_flag) )
channel_flag[i] = 0x00;
}
void mbedtls_aes_init( mbedtls_aes_context *ctx )
{
int i =-1;
mbedtls_trace("=== %s \r\n", __FUNCTION__);
memset( ctx, 0, sizeof( mbedtls_aes_context ) );
ctx->swapType = AES_IN_OUT_SWAP;
while( (i = channel_alloc()) < 0 )
{
mbed_assert_internal("No available AES channel", __FILE__, __LINE__);
}
ctx->channel = i;
ctx->iv = au32MyAESIV;
/* Unlock protected registers */
SYS_UnlockReg();
CLK_EnableModuleClock(CRPT_MODULE);
/* Lock protected registers */
SYS_LockReg();
NVIC_EnableIRQ(CRPT_IRQn);
AES_ENABLE_INT();
mbedtls_trace("=== %s channel[%d]\r\n", __FUNCTION__, (int)ctx->channel);
}
void mbedtls_aes_free( mbedtls_aes_context *ctx )
{
mbedtls_trace("=== %s channel[%d]\r\n", __FUNCTION__,(int)ctx->channel);
if( ctx == NULL )
return;
channel_free(ctx->channel);
mbedtls_zeroize( ctx, sizeof( mbedtls_aes_context ) );
}
/*
* AES key schedule (encryption)
*/
#if defined(MBEDTLS_AES_SETKEY_ENC_ALT)
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits )
{
unsigned int i;
mbedtls_trace("=== %s keybits[%d]\r\n", __FUNCTION__, keybits);
dumpHex(key,keybits/8);
switch( keybits )
{
case 128:
ctx->keySize = AES_KEY_SIZE_128;
break;
case 192:
ctx->keySize = AES_KEY_SIZE_192;
break;
case 256:
ctx->keySize = AES_KEY_SIZE_256;
break;
default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
}
// key swap
for( i = 0; i < ( keybits >> 5 ); i++ )
{
ctx->buf[i] = (*(key+i*4) << 24) |
(*(key+1+i*4) << 16) |
(*(key+2+i*4) << 8) |
(*(key+3+i*4) );
}
AES_SetKey(ctx->channel, ctx->buf, ctx->keySize);
return( 0 );
}
#endif /* MBEDTLS_AES_SETKEY_ENC_ALT */
/*
* AES key schedule (decryption)
*/
#if defined(MBEDTLS_AES_SETKEY_DEC_ALT)
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits )
{
int ret;
mbedtls_trace("=== %s keybits[%d]\r\n", __FUNCTION__, keybits);
dumpHex((uint8_t *)key,keybits/8);
/* Also checks keybits */
if( ( ret = mbedtls_aes_setkey_enc( ctx, key, keybits ) ) != 0 )
goto exit;
exit:
return( ret );
}
#endif /* MBEDTLS_AES_SETKEY_DEC_ALT */
static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16], int dataSize)
{
unsigned char* pIn;
unsigned char* pOut;
// mbedtls_trace("=== %s \r\n", __FUNCTION__);
dumpHex(input,16);
AES_Open(ctx->channel, ctx->encDec, ctx->opMode, ctx->keySize, ctx->swapType);
AES_SetInitVect(ctx->channel, ctx->iv);
if( ((uint32_t)input) & 0x03 )
{
memcpy(au8InputData, input, dataSize);
pIn = au8InputData;
}else{
pIn = (unsigned char*)input;
}
if( (((uint32_t)output) & 0x03) || (dataSize%4)) // HW CFB output byte count must be multiple of word
{
pOut = au8OutputData;
} else {
pOut = output;
}
AES_SetDMATransfer(ctx->channel, (uint32_t)pIn, (uint32_t)pOut, dataSize);
g_AES_done = 0;
AES_Start(ctx->channel, CRYPTO_DMA_ONE_SHOT);
while (!g_AES_done);
if( pOut != output ) memcpy(output, au8OutputData, dataSize);
dumpHex(output,16);
}
/*
* AES-ECB block encryption
*/
#if defined(MBEDTLS_AES_ENCRYPT_ALT)
void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] )
{
mbedtls_trace("=== %s \r\n", __FUNCTION__);
ctx->encDec = 1;
__nvt_aes_crypt(ctx, input, output, 16);
}
#endif /* MBEDTLS_AES_ENCRYPT_ALT */
/*
* AES-ECB block decryption
*/
#if defined(MBEDTLS_AES_DECRYPT_ALT)
void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] )
{
mbedtls_trace("=== %s \r\n", __FUNCTION__);
ctx->encDec = 0;
__nvt_aes_crypt(ctx, input, output, 16);
}
#endif /* MBEDTLS_AES_DECRYPT_ALT */
/*
* AES-ECB block encryption/decryption
*/
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] )
{
mbedtls_trace("=== %s \r\n", __FUNCTION__);
ctx->opMode = AES_MODE_ECB;
if( mode == MBEDTLS_AES_ENCRYPT )
mbedtls_aes_encrypt( ctx, input, output );
else
mbedtls_aes_decrypt( ctx, input, output );
return( 0 );
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/*
* AES-CBC buffer encryption/decryption
*/
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
int mode,
size_t len,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
unsigned char temp[16];
int length = len;
int blockChainLen;
mbedtls_trace("=== %s [0x%x]\r\n", __FUNCTION__,length);
if( length % 16 )
return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
if( (((uint32_t)input) & 0x03) || (((uint32_t)output) & 0x03) )
{
blockChainLen = (( length > MAX_DMA_CHAIN_SIZE ) ? MAX_DMA_CHAIN_SIZE : length );
} else {
blockChainLen = length;
}
while( length > 0 )
{
ctx->opMode = AES_MODE_CBC;
swapInitVector(iv); // iv SWAP
ctx->iv = (uint32_t *)iv;
if( mode == MBEDTLS_AES_ENCRYPT )
{
ctx->encDec = 1;
__nvt_aes_crypt(ctx, input, output, blockChainLen);
// if( blockChainLen == length ) break; // finish last block chain but still need to prepare next iv for mbedtls_aes_self_test()
memcpy( iv, output+blockChainLen-16, 16 );
}else{
memcpy( temp, input+blockChainLen-16, 16 );
ctx->encDec = 0;
__nvt_aes_crypt(ctx, input, output, blockChainLen);
// if( blockChainLen == length ) break; // finish last block chain but still need to prepare next iv for mbedtls_aes_self_test()
memcpy( iv, temp, 16 );
}
length -= blockChainLen;
input += blockChainLen;
output += blockChainLen;
if(length < MAX_DMA_CHAIN_SIZE ) blockChainLen = length; // For last remainder block chain
}
return( 0 );
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/*
* AES-CFB128 buffer encryption/decryption
*/
/* Support partial block encryption/decryption */
static int __nvt_aes_crypt_partial_block_cfb128( mbedtls_aes_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
int c;
size_t n = *iv_off;
unsigned char iv_tmp[16];
mbedtls_trace("=== %s \r\n", __FUNCTION__);
if( mode == MBEDTLS_AES_DECRYPT )
{
while( length-- )
{
if( n == 0)
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
else if( ctx->opMode == AES_MODE_CFB) // For previous cryption is CFB mode
{
memcpy(iv_tmp, iv, n);
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, ctx->prv_iv, iv );
memcpy(iv, iv_tmp, n);
}
c = *input++;
*output++ = (unsigned char)( c ^ iv[n] );
iv[n] = (unsigned char) c;
n = ( n + 1 ) & 0x0F;
}
}
else
{
while( length-- )
{
if( n == 0 )
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
else if( ctx->opMode == AES_MODE_CFB) // For previous cryption is CFB mode
{
memcpy(iv_tmp, iv, n);
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, ctx->prv_iv, iv );
memcpy(iv, iv_tmp, n);
}
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
n = ( n + 1 ) & 0x0F;
}
}
*iv_off = n;
return( 0 );
}
int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
int mode,
size_t len,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
size_t n = *iv_off;
unsigned char temp[16];
int length=len;
int blockChainLen;
int remLen=0;
int ivLen;
mbedtls_trace("=== %s \r\n", __FUNCTION__);
// proceed: start with partial block by ECB mode first
if( n !=0 ) {
__nvt_aes_crypt_partial_block_cfb128(ctx, mode, 16 - n , iv_off, iv, input, output);
input += (16 - n);
output += (16 - n);
length -= (16 - n);
}
// For address or byte count non-word alignment, go through reserved DMA buffer.
if( (((uint32_t)input) & 0x03) || (((uint32_t)output) & 0x03) ) // Must reserved DMA buffer for each block
{
blockChainLen = (( length > MAX_DMA_CHAIN_SIZE ) ? MAX_DMA_CHAIN_SIZE : length );
} else if(length%4) { // Need reserved DMA buffer once for last chain
blockChainLen = (( length > MAX_DMA_CHAIN_SIZE ) ? (length - length%16) : length );
} else { // Not need reserved DMA buffer
blockChainLen = length;
}
// proceed: start with block alignment
while( length > 0 )
{
ctx->opMode = AES_MODE_CFB;
swapInitVector(iv); // iv SWAP
ctx->iv = (uint32_t *)iv;
remLen = blockChainLen%16;
ivLen = (( remLen > 0) ? remLen: 16 );
if( mode == MBEDTLS_AES_DECRYPT )
{
memcpy(temp, input+blockChainLen - ivLen, ivLen);
if(blockChainLen >= 16) memcpy(ctx->prv_iv, input+blockChainLen-remLen-16 , 16);
ctx->encDec = 0;
__nvt_aes_crypt(ctx, input, output, blockChainLen);
memcpy(iv,temp, ivLen);
}
else
{
ctx->encDec = 1;
__nvt_aes_crypt(ctx, input, output, blockChainLen);
if(blockChainLen >= 16) memcpy(ctx->prv_iv, output+blockChainLen-remLen-16 , 16);
memcpy(iv,output+blockChainLen-ivLen,ivLen);
}
length -= blockChainLen;
input += blockChainLen;
output += blockChainLen;
if(length < MAX_DMA_CHAIN_SIZE ) blockChainLen = length; // For last remainder block chain
}
*iv_off = remLen;
return( 0 );
}
/*
* AES-CFB8 buffer encryption/decryption
*/
int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
unsigned char c;
unsigned char ov[17];
mbedtls_trace("=== %s \r\n", __FUNCTION__);
while( length-- )
{
memcpy( ov, iv, 16 );
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
if( mode == MBEDTLS_AES_DECRYPT )
ov[16] = *input;
c = *output++ = (unsigned char)( iv[0] ^ *input++ );
if( mode == MBEDTLS_AES_ENCRYPT )
ov[16] = c;
memcpy( iv, ov + 1, 16 );
}
return( 0 );
}
#endif /*MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/*
* AES-CTR buffer encryption/decryption
*/
int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[16],
unsigned char stream_block[16],
const unsigned char *input,
unsigned char *output )
{
int c, i;
size_t n = *nc_off;
mbedtls_trace("=== %s \r\n", __FUNCTION__);
while( length-- )
{
if( n == 0 ) {
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
for( i = 16; i > 0; i-- )
if( ++nonce_counter[i - 1] != 0 )
break;
}
c = *input++;
*output++ = (unsigned char)( c ^ stream_block[n] );
n = ( n + 1 ) & 0x0F;
}
*nc_off = n;
return( 0 );
}
#endif /* MBEDTLS_CIPHER_MODE_CTR */
#endif /* MBEDTLS_AES_ALT */
#endif /* MBEDTLS_AES_C */

View File

@ -20,7 +20,16 @@
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_AES_ALT_H
#define MBEDTLS_AES_ALT_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_AES_C)
#if defined(MBEDTLS_AES_ALT)
// Regular implementation
//
@ -270,5 +279,6 @@ void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
#endif /* MBEDTLS_AES_ALT */
#endif /* MBEDTLS_AES_C */
#endif /* aes_alt.h */

View File

@ -14,9 +14,6 @@
* limitations under the License.
*/
/* Compatible with mbed OS 2 which doesn't support mbedtls */
#if MBED_CONF_RTOS_PRESENT
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
@ -348,7 +345,7 @@ static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_S
uint32_t rmn = length;
const unsigned char *in_pos = input;
const unsigned char *out_pos = output;
unsigned char *out_pos = output;
while (rmn) {
uint32_t data_len = (rmn <= MAXSIZE_DMABUF) ? rmn : MAXSIZE_DMABUF;
@ -411,5 +408,3 @@ static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_S
#endif /* MBEDTLS_DES_ALT */
#endif /* MBEDTLS_DES_C */
#endif /* MBED_CONF_RTOS_PRESENT */

View File

@ -23,6 +23,7 @@
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_DES_C)
#if defined(MBEDTLS_DES_ALT)
#include <stddef.h>
@ -276,5 +277,6 @@ void mbedtls_des_setkey( uint32_t SK[32],
#endif
#endif /* MBEDTLS_DES_ALT */
#endif /* MBEDTLS_DES_C */
#endif /* des_alt.h */

View File

@ -25,9 +25,6 @@
* http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
*/
/* Compatible with mbed OS 2 which doesn't support mbedtls */
#if MBED_CONF_RTOS_PRESENT
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
@ -798,5 +795,3 @@ int mbedtls_des3_sw_crypt_cbc( mbedtls_des3_sw_context *ctx,
#endif /* MBEDTLS_DES_ALT */
#endif /* MBEDTLS_DES_C */
#endif /* MBED_CONF_RTOS_PRESENT */

View File

@ -14,9 +14,6 @@
* limitations under the License.
*/
/* Compatible with mbed OS 2 which doesn't support mbedtls */
#if MBED_CONF_RTOS_PRESENT
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
@ -139,5 +136,3 @@ void mbedtls_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64
#endif /* MBEDTLS_SHA1_ALT */
#endif /* MBEDTLS_SHA1_C */
#endif /* MBED_CONF_RTOS_PRESENT */

View File

@ -0,0 +1,344 @@
/*
* FIPS-180-1 compliant SHA-1 implementation
*
* Copyright (C) 2006-2015, 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 part of mbed TLS (https://tls.mbed.org)
*/
/*
* The SHA-1 standard was published by NIST in 1993.
*
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA1_C)
#if defined(MBEDTLS_SHA1_ALT)
#include "mbedtls/sha1.h"
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
}
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
void mbedtls_sha1_sw_init( mbedtls_sha1_sw_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_sha1_sw_context ) );
}
void mbedtls_sha1_sw_free( mbedtls_sha1_sw_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_sw_context ) );
}
void mbedtls_sha1_sw_clone( mbedtls_sha1_sw_context *dst,
const mbedtls_sha1_sw_context *src )
{
*dst = *src;
}
/*
* SHA-1 context setup
*/
void mbedtls_sha1_sw_starts( mbedtls_sha1_sw_context *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
ctx->state[4] = 0xC3D2E1F0;
}
void mbedtls_sha1_sw_process( mbedtls_sha1_sw_context *ctx, const unsigned char data[64] )
{
uint32_t temp, W[16], A, B, C, D, E;
GET_UINT32_BE( W[ 0], data, 0 );
GET_UINT32_BE( W[ 1], data, 4 );
GET_UINT32_BE( W[ 2], data, 8 );
GET_UINT32_BE( W[ 3], data, 12 );
GET_UINT32_BE( W[ 4], data, 16 );
GET_UINT32_BE( W[ 5], data, 20 );
GET_UINT32_BE( W[ 6], data, 24 );
GET_UINT32_BE( W[ 7], data, 28 );
GET_UINT32_BE( W[ 8], data, 32 );
GET_UINT32_BE( W[ 9], data, 36 );
GET_UINT32_BE( W[10], data, 40 );
GET_UINT32_BE( W[11], data, 44 );
GET_UINT32_BE( W[12], data, 48 );
GET_UINT32_BE( W[13], data, 52 );
GET_UINT32_BE( W[14], data, 56 );
GET_UINT32_BE( W[15], data, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define R(t) \
( \
temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \
W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \
( W[t & 0x0F] = S(temp,1) ) \
)
#define P(a,b,c,d,e,x) \
{ \
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
E = ctx->state[4];
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define K 0x5A827999
P( A, B, C, D, E, W[0] );
P( E, A, B, C, D, W[1] );
P( D, E, A, B, C, W[2] );
P( C, D, E, A, B, W[3] );
P( B, C, D, E, A, W[4] );
P( A, B, C, D, E, W[5] );
P( E, A, B, C, D, W[6] );
P( D, E, A, B, C, W[7] );
P( C, D, E, A, B, W[8] );
P( B, C, D, E, A, W[9] );
P( A, B, C, D, E, W[10] );
P( E, A, B, C, D, W[11] );
P( D, E, A, B, C, W[12] );
P( C, D, E, A, B, W[13] );
P( B, C, D, E, A, W[14] );
P( A, B, C, D, E, W[15] );
P( E, A, B, C, D, R(16) );
P( D, E, A, B, C, R(17) );
P( C, D, E, A, B, R(18) );
P( B, C, D, E, A, R(19) );
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0x6ED9EBA1
P( A, B, C, D, E, R(20) );
P( E, A, B, C, D, R(21) );
P( D, E, A, B, C, R(22) );
P( C, D, E, A, B, R(23) );
P( B, C, D, E, A, R(24) );
P( A, B, C, D, E, R(25) );
P( E, A, B, C, D, R(26) );
P( D, E, A, B, C, R(27) );
P( C, D, E, A, B, R(28) );
P( B, C, D, E, A, R(29) );
P( A, B, C, D, E, R(30) );
P( E, A, B, C, D, R(31) );
P( D, E, A, B, C, R(32) );
P( C, D, E, A, B, R(33) );
P( B, C, D, E, A, R(34) );
P( A, B, C, D, E, R(35) );
P( E, A, B, C, D, R(36) );
P( D, E, A, B, C, R(37) );
P( C, D, E, A, B, R(38) );
P( B, C, D, E, A, R(39) );
#undef K
#undef F
#define F(x,y,z) ((x & y) | (z & (x | y)))
#define K 0x8F1BBCDC
P( A, B, C, D, E, R(40) );
P( E, A, B, C, D, R(41) );
P( D, E, A, B, C, R(42) );
P( C, D, E, A, B, R(43) );
P( B, C, D, E, A, R(44) );
P( A, B, C, D, E, R(45) );
P( E, A, B, C, D, R(46) );
P( D, E, A, B, C, R(47) );
P( C, D, E, A, B, R(48) );
P( B, C, D, E, A, R(49) );
P( A, B, C, D, E, R(50) );
P( E, A, B, C, D, R(51) );
P( D, E, A, B, C, R(52) );
P( C, D, E, A, B, R(53) );
P( B, C, D, E, A, R(54) );
P( A, B, C, D, E, R(55) );
P( E, A, B, C, D, R(56) );
P( D, E, A, B, C, R(57) );
P( C, D, E, A, B, R(58) );
P( B, C, D, E, A, R(59) );
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0xCA62C1D6
P( A, B, C, D, E, R(60) );
P( E, A, B, C, D, R(61) );
P( D, E, A, B, C, R(62) );
P( C, D, E, A, B, R(63) );
P( B, C, D, E, A, R(64) );
P( A, B, C, D, E, R(65) );
P( E, A, B, C, D, R(66) );
P( D, E, A, B, C, R(67) );
P( C, D, E, A, B, R(68) );
P( B, C, D, E, A, R(69) );
P( A, B, C, D, E, R(70) );
P( E, A, B, C, D, R(71) );
P( D, E, A, B, C, R(72) );
P( C, D, E, A, B, R(73) );
P( B, C, D, E, A, R(74) );
P( A, B, C, D, E, R(75) );
P( E, A, B, C, D, R(76) );
P( D, E, A, B, C, R(77) );
P( C, D, E, A, B, R(78) );
P( B, C, D, E, A, R(79) );
#undef K
#undef F
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[4] += E;
}
/*
* SHA-1 process buffer
*/
void mbedtls_sha1_sw_update( mbedtls_sha1_sw_context *ctx, const unsigned char *input, size_t ilen )
{
size_t fill;
uint32_t left;
if( ilen == 0 )
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (uint32_t) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left), input, fill );
mbedtls_sha1_sw_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
mbedtls_sha1_sw_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
static const unsigned char sha1_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-1 final digest
*/
void mbedtls_sha1_sw_finish( mbedtls_sha1_sw_context *ctx, unsigned char output[20] )
{
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_BE( high, msglen, 0 );
PUT_UINT32_BE( low, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
mbedtls_sha1_sw_update( ctx, sha1_padding, padn );
mbedtls_sha1_sw_update( ctx, msglen, 8 );
PUT_UINT32_BE( ctx->state[0], output, 0 );
PUT_UINT32_BE( ctx->state[1], output, 4 );
PUT_UINT32_BE( ctx->state[2], output, 8 );
PUT_UINT32_BE( ctx->state[3], output, 12 );
PUT_UINT32_BE( ctx->state[4], output, 16 );
}
#endif /* MBEDTLS_SHA1_ALT */
#endif /* MBEDTLS_SHA1_C */

View File

@ -0,0 +1,139 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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.
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA256_C)
#if defined(MBEDTLS_SHA256_ALT)
#include "sha256_alt.h"
#include "crypto-misc.h"
#include "nu_bitutil.h"
#include "string.h"
void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
{
if (crypto_sha_acquire()) {
ctx->ishw = 1;
mbedtls_sha256_hw_init(&ctx->hw_ctx);
}
else {
ctx->ishw = 0;
mbedtls_sha256_sw_init(&ctx->sw_ctx);
}
}
void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
{
if (ctx == NULL) {
return;
}
if (ctx->ishw) {
mbedtls_sha256_hw_free(&ctx->hw_ctx);
crypto_sha_release();
}
else {
mbedtls_sha256_sw_free(&ctx->sw_ctx);
}
}
void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
const mbedtls_sha256_context *src)
{
if (src->ishw) {
// Clone S/W ctx from H/W ctx
dst->ishw = 0;
dst->sw_ctx.total[0] = src->hw_ctx.total;
dst->sw_ctx.total[1] = 0;
{
unsigned char output[32];
crypto_sha_getinternstate(output, sizeof (output));
unsigned char *output_pos = output;
unsigned char *output_end = output + (sizeof (output) / sizeof (output[0]));
uint32_t *state_pos = (uint32_t *) &(dst->sw_ctx.state[0]);
while (output_pos != output_end) {
*state_pos ++ = nu_get32_be(output_pos);
output_pos += 4;
}
}
memcpy(dst->sw_ctx.buffer, src->hw_ctx.buffer, src->hw_ctx.buffer_left);
dst->sw_ctx.is224 = src->hw_ctx.is224_384;
if (src->hw_ctx.buffer_left == src->hw_ctx.blocksize) {
mbedtls_sha256_sw_process(&dst->sw_ctx, dst->sw_ctx.buffer);
}
}
else {
// Clone S/W ctx from S/W ctx
dst->sw_ctx = src->sw_ctx;
}
}
/*
* SHA-256 context setup
*/
void mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
{
if (ctx->ishw) {
mbedtls_sha256_hw_starts(&ctx->hw_ctx, is224);
}
else {
mbedtls_sha256_sw_starts(&ctx->sw_ctx, is224);
}
}
/*
* SHA-256 process buffer
*/
void mbedtls_sha256_update(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
{
if (ctx->ishw) {
mbedtls_sha256_hw_update(&ctx->hw_ctx, input, ilen);
}
else {
mbedtls_sha256_sw_update(&ctx->sw_ctx, input, ilen);
}
}
/*
* SHA-256 final digest
*/
void mbedtls_sha256_finish(mbedtls_sha256_context *ctx, unsigned char output[32])
{
if (ctx->ishw) {
mbedtls_sha256_hw_finish(&ctx->hw_ctx, output);
}
else {
mbedtls_sha256_sw_finish(&ctx->sw_ctx, output);
}
}
void mbedtls_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
{
if (ctx->ishw) {
mbedtls_sha256_hw_process(&ctx->hw_ctx, data);
}
else {
mbedtls_sha256_sw_process(&ctx->sw_ctx, data);
}
}
#endif /* MBEDTLS_SHA256_ALT */
#endif /* MBEDTLS_SHA256_C */

View File

@ -0,0 +1,318 @@
/*
* FIPS-180-2 compliant SHA-256 implementation
*
* Copyright (C) 2006-2015, 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 part of mbed TLS (https://tls.mbed.org)
*/
/*
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
*
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA256_C)
#if defined(MBEDTLS_SHA256_ALT)
#include "mbedtls/sha256.h"
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#include <stdlib.h>
#define mbedtls_printf printf
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
do { \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
} while( 0 )
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
do { \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
} while( 0 )
#endif
void mbedtls_sha256_sw_init( mbedtls_sha256_sw_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_sha256_sw_context ) );
}
void mbedtls_sha256_sw_free( mbedtls_sha256_sw_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_sw_context ) );
}
void mbedtls_sha256_sw_clone( mbedtls_sha256_sw_context *dst,
const mbedtls_sha256_sw_context *src )
{
*dst = *src;
}
/*
* SHA-256 context setup
*/
void mbedtls_sha256_sw_starts( mbedtls_sha256_sw_context *ctx, int is224 )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
if( is224 == 0 )
{
/* SHA-256 */
ctx->state[0] = 0x6A09E667;
ctx->state[1] = 0xBB67AE85;
ctx->state[2] = 0x3C6EF372;
ctx->state[3] = 0xA54FF53A;
ctx->state[4] = 0x510E527F;
ctx->state[5] = 0x9B05688C;
ctx->state[6] = 0x1F83D9AB;
ctx->state[7] = 0x5BE0CD19;
}
else
{
/* SHA-224 */
ctx->state[0] = 0xC1059ED8;
ctx->state[1] = 0x367CD507;
ctx->state[2] = 0x3070DD17;
ctx->state[3] = 0xF70E5939;
ctx->state[4] = 0xFFC00B31;
ctx->state[5] = 0x68581511;
ctx->state[6] = 0x64F98FA7;
ctx->state[7] = 0xBEFA4FA4;
}
ctx->is224 = is224;
}
static const uint32_t K[] =
{
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
};
#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
#define F0(x,y,z) ((x & y) | (z & (x | y)))
#define F1(x,y,z) (z ^ (x & (y ^ z)))
#define R(t) \
( \
W[t] = S1(W[t - 2]) + W[t - 7] + \
S0(W[t - 15]) + W[t - 16] \
)
#define P(a,b,c,d,e,f,g,h,x,K) \
{ \
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
temp2 = S2(a) + F0(a,b,c); \
d += temp1; h = temp1 + temp2; \
}
void mbedtls_sha256_sw_process( mbedtls_sha256_sw_context *ctx, const unsigned char data[64] )
{
uint32_t temp1, temp2, W[64];
uint32_t A[8];
unsigned int i;
for( i = 0; i < 8; i++ )
A[i] = ctx->state[i];
#if defined(MBEDTLS_SHA256_SMALLER)
for( i = 0; i < 64; i++ )
{
if( i < 16 )
GET_UINT32_BE( W[i], data, 4 * i );
else
R( i );
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
}
#else /* MBEDTLS_SHA256_SMALLER */
for( i = 0; i < 16; i++ )
GET_UINT32_BE( W[i], data, 4 * i );
for( i = 0; i < 16; i += 8 )
{
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
}
for( i = 16; i < 64; i += 8 )
{
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
}
#endif /* MBEDTLS_SHA256_SMALLER */
for( i = 0; i < 8; i++ )
ctx->state[i] += A[i];
}
/*
* SHA-256 process buffer
*/
void mbedtls_sha256_sw_update( mbedtls_sha256_sw_context *ctx, const unsigned char *input,
size_t ilen )
{
size_t fill;
uint32_t left;
if( ilen == 0 )
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (uint32_t) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left), input, fill );
mbedtls_sha256_sw_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
mbedtls_sha256_sw_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
static const unsigned char sha256_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-256 final digest
*/
void mbedtls_sha256_sw_finish( mbedtls_sha256_sw_context *ctx, unsigned char output[32] )
{
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_BE( high, msglen, 0 );
PUT_UINT32_BE( low, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
mbedtls_sha256_sw_update( ctx, sha256_padding, padn );
mbedtls_sha256_sw_update( ctx, msglen, 8 );
PUT_UINT32_BE( ctx->state[0], output, 0 );
PUT_UINT32_BE( ctx->state[1], output, 4 );
PUT_UINT32_BE( ctx->state[2], output, 8 );
PUT_UINT32_BE( ctx->state[3], output, 12 );
PUT_UINT32_BE( ctx->state[4], output, 16 );
PUT_UINT32_BE( ctx->state[5], output, 20 );
PUT_UINT32_BE( ctx->state[6], output, 24 );
if( ctx->is224 == 0 )
PUT_UINT32_BE( ctx->state[7], output, 28 );
}
#endif /* MBEDTLS_SHA256_ALT */
#endif /* MBEDTLS_SHA256_C */

View File

@ -0,0 +1,140 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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.
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA512_C)
#if defined(MBEDTLS_SHA512_ALT)
#include "sha512_alt.h"
#include "crypto-misc.h"
#include "nu_bitutil.h"
#include "string.h"
void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
{
if (crypto_sha_acquire()) {
ctx->ishw = 1;
mbedtls_sha512_hw_init(&ctx->hw_ctx);
}
else {
ctx->ishw = 0;
mbedtls_sha512_sw_init(&ctx->sw_ctx);
}
}
void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
{
if (ctx == NULL) {
return;
}
if (ctx->ishw) {
mbedtls_sha512_hw_free(&ctx->hw_ctx);
crypto_sha_release();
}
else {
mbedtls_sha512_sw_free(&ctx->sw_ctx);
}
}
void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
const mbedtls_sha512_context *src)
{
if (src->ishw) {
// Clone S/W ctx from H/W ctx
dst->ishw = 0;
dst->sw_ctx.total[0] = src->hw_ctx.total;
dst->sw_ctx.total[1] = 0;
{
unsigned char output[128];
crypto_sha_getinternstate(output, sizeof (output));
unsigned char *output_pos = output;
unsigned char *output_end = output + (sizeof (output) / sizeof (output[0]));
uint32_t *state_pos = (uint32_t *) &(dst->sw_ctx.state[0]);
while (output_pos != output_end) {
*state_pos ++ = nu_get32_be(output_pos + 4);
*state_pos ++ = nu_get32_be(output_pos);
output_pos += 8;
}
}
memcpy(dst->sw_ctx.buffer, src->hw_ctx.buffer, src->hw_ctx.buffer_left);
dst->sw_ctx.is384 = src->hw_ctx.is224_384;
if (src->hw_ctx.buffer_left == src->hw_ctx.blocksize) {
mbedtls_sha512_sw_process(&dst->sw_ctx, dst->sw_ctx.buffer);
}
}
else {
// Clone S/W ctx from S/W ctx
dst->sw_ctx = src->sw_ctx;
}
}
/*
* SHA-512 context setup
*/
void mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
{
if (ctx->ishw) {
mbedtls_sha512_hw_starts(&ctx->hw_ctx, is384);
}
else {
mbedtls_sha512_sw_starts(&ctx->sw_ctx, is384);
}
}
/*
* SHA-512 process buffer
*/
void mbedtls_sha512_update(mbedtls_sha512_context *ctx, const unsigned char *input, size_t ilen)
{
if (ctx->ishw) {
mbedtls_sha512_hw_update(&ctx->hw_ctx, input, ilen);
}
else {
mbedtls_sha512_sw_update(&ctx->sw_ctx, input, ilen);
}
}
/*
* SHA-512 final digest
*/
void mbedtls_sha512_finish(mbedtls_sha512_context *ctx, unsigned char output[64])
{
if (ctx->ishw) {
mbedtls_sha512_hw_finish(&ctx->hw_ctx, output);
}
else {
mbedtls_sha512_sw_finish(&ctx->sw_ctx, output);
}
}
void mbedtls_sha512_process(mbedtls_sha512_context *ctx, const unsigned char data[128])
{
if (ctx->ishw) {
mbedtls_sha512_hw_process(&ctx->hw_ctx, data);
}
else {
mbedtls_sha512_sw_process(&ctx->sw_ctx, data);
}
}
#endif /* MBEDTLS_SHA512_ALT */
#endif /* MBEDTLS_SHA512_C */

View File

@ -0,0 +1,107 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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 MBEDTLS_SHA512_ALT_H
#define MBEDTLS_SHA512_ALT_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA512_C)
#if defined(MBEDTLS_SHA512_ALT)
#include "sha_alt_hw.h"
#include "sha512_alt_sw.h"
#ifdef __cplusplus
extern "C" {
#endif
struct mbedtls_sha512_context_s;
/**
* \brief SHA-512 context structure
*/
typedef struct mbedtls_sha512_context_s
{
int ishw;
crypto_sha_context hw_ctx;
mbedtls_sha512_sw_context sw_ctx;
}
mbedtls_sha512_context;
/**
* \brief Initialize SHA-512 context
*
* \param ctx SHA-512 context to be initialized
*/
void mbedtls_sha512_init( mbedtls_sha512_context *ctx );
/**
* \brief Clear SHA-512 context
*
* \param ctx SHA-512 context to be cleared
*/
void mbedtls_sha512_free( mbedtls_sha512_context *ctx );
/**
* \brief Clone (the state of) a SHA-512 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
const mbedtls_sha512_context *src );
/**
* \brief SHA-512 context setup
*
* \param ctx context to be initialized
* \param is384 0 = use SHA512, 1 = use SHA384
*/
void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 );
/**
* \brief SHA-512 process buffer
*
* \param ctx SHA-512 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
size_t ilen );
/**
* \brief SHA-512 final digest
*
* \param ctx SHA-512 context
* \param output SHA-384/512 checksum result
*/
void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] );
/* Internal use */
void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_SHA512_ALT */
#endif /* MBEDTLS_SHA512_C */
#endif /* sha512_alt.h */

View File

@ -0,0 +1,357 @@
/*
* FIPS-180-2 compliant SHA-384/512 implementation
*
* Copyright (C) 2006-2015, 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 part of mbed TLS (https://tls.mbed.org)
*/
/*
* The SHA-512 Secure Hash Standard was published by NIST in 2002.
*
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA512_C)
#if defined(MBEDTLS_SHA512_ALT)
#include "mbedtls/sha512.h"
#if defined(_MSC_VER) || defined(__WATCOMC__)
#define UL64(x) x##ui64
#else
#define UL64(x) x##ULL
#endif
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#include <stdlib.h>
#define mbedtls_printf printf
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* 64-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT64_BE
#define GET_UINT64_BE(n,b,i) \
{ \
(n) = ( (uint64_t) (b)[(i) ] << 56 ) \
| ( (uint64_t) (b)[(i) + 1] << 48 ) \
| ( (uint64_t) (b)[(i) + 2] << 40 ) \
| ( (uint64_t) (b)[(i) + 3] << 32 ) \
| ( (uint64_t) (b)[(i) + 4] << 24 ) \
| ( (uint64_t) (b)[(i) + 5] << 16 ) \
| ( (uint64_t) (b)[(i) + 6] << 8 ) \
| ( (uint64_t) (b)[(i) + 7] ); \
}
#endif /* GET_UINT64_BE */
#ifndef PUT_UINT64_BE
#define PUT_UINT64_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
(b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
(b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 7] = (unsigned char) ( (n) ); \
}
#endif /* PUT_UINT64_BE */
void mbedtls_sha512_sw_init( mbedtls_sha512_sw_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_sha512_sw_context ) );
}
void mbedtls_sha512_sw_free( mbedtls_sha512_sw_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_sw_context ) );
}
void mbedtls_sha512_sw_clone( mbedtls_sha512_sw_context *dst,
const mbedtls_sha512_sw_context *src )
{
*dst = *src;
}
/*
* SHA-512 context setup
*/
void mbedtls_sha512_sw_starts( mbedtls_sha512_sw_context *ctx, int is384 )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
if( is384 == 0 )
{
/* SHA-512 */
ctx->state[0] = UL64(0x6A09E667F3BCC908);
ctx->state[1] = UL64(0xBB67AE8584CAA73B);
ctx->state[2] = UL64(0x3C6EF372FE94F82B);
ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
ctx->state[4] = UL64(0x510E527FADE682D1);
ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
ctx->state[7] = UL64(0x5BE0CD19137E2179);
}
else
{
/* SHA-384 */
ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
ctx->state[1] = UL64(0x629A292A367CD507);
ctx->state[2] = UL64(0x9159015A3070DD17);
ctx->state[3] = UL64(0x152FECD8F70E5939);
ctx->state[4] = UL64(0x67332667FFC00B31);
ctx->state[5] = UL64(0x8EB44A8768581511);
ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
}
ctx->is384 = is384;
}
#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
/*
* Round constants
*/
static const uint64_t K[80] =
{
UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
};
void mbedtls_sha512_sw_process( mbedtls_sha512_sw_context *ctx, const unsigned char data[128] )
{
int i;
uint64_t temp1, temp2, W[80];
uint64_t A, B, C, D, E, F, G, H;
#define SHR(x,n) (x >> n)
#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
#define F0(x,y,z) ((x & y) | (z & (x | y)))
#define F1(x,y,z) (z ^ (x & (y ^ z)))
#define P(a,b,c,d,e,f,g,h,x,K) \
{ \
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
temp2 = S2(a) + F0(a,b,c); \
d += temp1; h = temp1 + temp2; \
}
for( i = 0; i < 16; i++ )
{
GET_UINT64_BE( W[i], data, i << 3 );
}
for( ; i < 80; i++ )
{
W[i] = S1(W[i - 2]) + W[i - 7] +
S0(W[i - 15]) + W[i - 16];
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
E = ctx->state[4];
F = ctx->state[5];
G = ctx->state[6];
H = ctx->state[7];
i = 0;
do
{
P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
}
while( i < 80 );
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[4] += E;
ctx->state[5] += F;
ctx->state[6] += G;
ctx->state[7] += H;
}
#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
/*
* SHA-512 process buffer
*/
void mbedtls_sha512_sw_update( mbedtls_sha512_sw_context *ctx, const unsigned char *input,
size_t ilen )
{
size_t fill;
unsigned int left;
if( ilen == 0 )
return;
left = (unsigned int) (ctx->total[0] & 0x7F);
fill = 128 - left;
ctx->total[0] += (uint64_t) ilen;
if( ctx->total[0] < (uint64_t) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left), input, fill );
mbedtls_sha512_sw_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 128 )
{
mbedtls_sha512_sw_process( ctx, input );
input += 128;
ilen -= 128;
}
if( ilen > 0 )
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
static const unsigned char sha512_padding[128] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-512 final digest
*/
void mbedtls_sha512_sw_finish( mbedtls_sha512_sw_context *ctx, unsigned char output[64] )
{
size_t last, padn;
uint64_t high, low;
unsigned char msglen[16];
high = ( ctx->total[0] >> 61 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT64_BE( high, msglen, 0 );
PUT_UINT64_BE( low, msglen, 8 );
last = (size_t)( ctx->total[0] & 0x7F );
padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
mbedtls_sha512_sw_update( ctx, sha512_padding, padn );
mbedtls_sha512_sw_update( ctx, msglen, 16 );
PUT_UINT64_BE( ctx->state[0], output, 0 );
PUT_UINT64_BE( ctx->state[1], output, 8 );
PUT_UINT64_BE( ctx->state[2], output, 16 );
PUT_UINT64_BE( ctx->state[3], output, 24 );
PUT_UINT64_BE( ctx->state[4], output, 32 );
PUT_UINT64_BE( ctx->state[5], output, 40 );
if( ctx->is384 == 0 )
{
PUT_UINT64_BE( ctx->state[6], output, 48 );
PUT_UINT64_BE( ctx->state[7], output, 56 );
}
}
#endif /* MBEDTLS_SHA512_ALT */
#endif /* MBEDTLS_SHA512_C */

View File

@ -0,0 +1,113 @@
/**
* \file sha512.h
*
* \brief SHA-384 and SHA-512 cryptographic hash function
*
* Copyright (C) 2006-2015, 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 part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_SHA512_ALT_SW_H
#define MBEDTLS_SHA512_ALT_SW_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA512_C)
#if defined(MBEDTLS_SHA512_ALT)
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA-512 context structure
*/
typedef struct
{
uint64_t total[2]; /*!< number of bytes processed */
uint64_t state[8]; /*!< intermediate digest state */
unsigned char buffer[128]; /*!< data block being processed */
int is384; /*!< 0 => SHA-512, else SHA-384 */
}
mbedtls_sha512_sw_context;
/**
* \brief Initialize SHA-512 context
*
* \param ctx SHA-512 context to be initialized
*/
void mbedtls_sha512_sw_init( mbedtls_sha512_sw_context *ctx );
/**
* \brief Clear SHA-512 context
*
* \param ctx SHA-512 context to be cleared
*/
void mbedtls_sha512_sw_free( mbedtls_sha512_sw_context *ctx );
/**
* \brief Clone (the state of) a SHA-512 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_sha512_sw_clone( mbedtls_sha512_sw_context *dst,
const mbedtls_sha512_sw_context *src );
/**
* \brief SHA-512 context setup
*
* \param ctx context to be initialized
* \param is384 0 = use SHA512, 1 = use SHA384
*/
void mbedtls_sha512_sw_starts( mbedtls_sha512_sw_context *ctx, int is384 );
/**
* \brief SHA-512 process buffer
*
* \param ctx SHA-512 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_sha512_sw_update( mbedtls_sha512_sw_context *ctx, const unsigned char *input,
size_t ilen );
/**
* \brief SHA-512 final digest
*
* \param ctx SHA-512 context
* \param output SHA-384/512 checksum result
*/
void mbedtls_sha512_sw_finish( mbedtls_sha512_sw_context *ctx, unsigned char output[64] );
/* Internal use */
void mbedtls_sha512_sw_process( mbedtls_sha512_sw_context *ctx, const unsigned char data[128] );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_SHA512_ALT */
#endif /* MBEDTLS_SHA512_C */
#endif /* sha512_alt_sw.h */

View File

@ -0,0 +1,439 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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.
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA1_C) || defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA512_C)
#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_SHA512_ALT)
#if defined(MBEDTLS_SHA1_ALT)
#include "sha1_alt.h"
#endif /* MBEDTLS_SHA1_ALT */
#if defined(MBEDTLS_SHA256_ALT)
#include "sha256_alt.h"
#endif /* MBEDTLS_SHA256_ALT */
#if defined(MBEDTLS_SHA512_ALT)
#include "sha512_alt.h"
#endif /* MBEDTLS_SHA512_ALT */
#include "nu_bitutil.h"
#include "mbed_assert.h"
#include "crypto-misc.h"
#include <string.h>
void crypto_sha_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen);
void crypto_sha_update_nobuf(crypto_sha_context *ctx, const unsigned char *input, size_t ilen, int islast);
void crypto_sha_getinternstate(unsigned char output[], size_t olen);
#endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT || MBEDTLS_SHA512_ALT */
#if defined(MBEDTLS_SHA1_C)
#if defined(MBEDTLS_SHA1_ALT)
void mbedtls_sha1_hw_init(crypto_sha_context *ctx)
{
crypto_init();
memset(ctx, 0, sizeof(crypto_sha_context));
}
void mbedtls_sha1_hw_free(crypto_sha_context *ctx)
{
if (ctx == NULL) {
return;
}
crypto_zeroize(ctx, sizeof(crypto_sha_context));
}
void mbedtls_sha1_hw_clone(crypto_sha_context *dst,
const crypto_sha_context *src)
{
*dst = *src;
}
void mbedtls_sha1_hw_starts(crypto_sha_context *ctx)
{
// NOTE: mbedtls may call mbedtls_shaXXX_starts multiple times and then call the ending mbedtls_shaXXX_finish. Guard from it.
CRPT->HMAC_CTL |= CRPT_HMAC_CTL_STOP_Msk;
ctx->total = 0;
ctx->buffer_left = 0;
ctx->blocksize = 64;
ctx->blocksize_mask = 0x3F;
SHA_Open(SHA_MODE_SHA1, SHA_NO_SWAP, 0);
// Ensure we have correct initial internal states in SHA_DGST registers even though SHA H/W is not actually started.
CRPT->HMAC_CTL |= CRPT_HMAC_CTL_START_Msk;
return;
}
void mbedtls_sha1_hw_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen)
{
crypto_sha_update(ctx, input, ilen);
}
void mbedtls_sha1_hw_finish(crypto_sha_context *ctx, unsigned char output[20])
{
// H/W SHA cannot handle zero data well. Fall back to S/W SHA.
if (ctx->total) {
crypto_sha_update_nobuf(ctx, ctx->buffer, ctx->buffer_left, 1);
ctx->buffer_left = 0;
crypto_sha_getinternstate(output, 20);
CRPT->HMAC_CTL |= CRPT_HMAC_CTL_STOP_Msk;
}
else {
mbedtls_sha1_sw_context ctx_sw;
mbedtls_sha1_sw_init(&ctx_sw);
mbedtls_sha1_sw_starts(&ctx_sw);
mbedtls_sha1_sw_finish(&ctx_sw, output);
mbedtls_sha1_sw_free(&ctx_sw);
}
}
void mbedtls_sha1_hw_process(crypto_sha_context *ctx, const unsigned char data[64])
{
mbedtls_sha1_hw_update(ctx, data, 64);
}
#endif /* MBEDTLS_SHA1_ALT */
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
#if defined(MBEDTLS_SHA256_ALT)
void mbedtls_sha256_hw_init(crypto_sha_context *ctx)
{
crypto_init();
memset(ctx, 0, sizeof(crypto_sha_context));
}
void mbedtls_sha256_hw_free(crypto_sha_context *ctx)
{
if (ctx == NULL) {
return;
}
crypto_zeroize(ctx, sizeof(crypto_sha_context));
}
void mbedtls_sha256_hw_clone(crypto_sha_context *dst,
const crypto_sha_context *src)
{
*dst = *src;
}
void mbedtls_sha256_hw_starts( crypto_sha_context *ctx, int is224)
{
// NOTE: mbedtls may call mbedtls_shaXXX_starts multiple times and then call the ending mbedtls_shaXXX_finish. Guard from it.
CRPT->HMAC_CTL |= CRPT_HMAC_CTL_STOP_Msk;
ctx->total = 0;
ctx->buffer_left = 0;
ctx->blocksize = 64;
ctx->blocksize_mask = 0x3F;
ctx->is224_384 = is224;
SHA_Open(is224 ? SHA_MODE_SHA224 : SHA_MODE_SHA256, SHA_NO_SWAP, 0);
// Ensure we have correct initial inernal states in SHA_DGST registers even though SHA H/W is not actually started.
CRPT->HMAC_CTL |= CRPT_HMAC_CTL_START_Msk;
return;
}
void mbedtls_sha256_hw_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen)
{
crypto_sha_update(ctx, input, ilen);
}
void mbedtls_sha256_hw_finish(crypto_sha_context *ctx, unsigned char output[32])
{
// H/W SHA cannot handle zero data well. Fall back to S/W SHA.
if (ctx->total) {
crypto_sha_update_nobuf(ctx, ctx->buffer, ctx->buffer_left, 1);
ctx->buffer_left = 0;
crypto_sha_getinternstate(output, ctx->is224_384 ? 28 : 32);
CRPT->HMAC_CTL |= CRPT_HMAC_CTL_STOP_Msk;
}
else {
mbedtls_sha256_sw_context ctx_sw;
mbedtls_sha256_sw_init(&ctx_sw);
mbedtls_sha256_sw_starts(&ctx_sw, ctx->is224_384);
mbedtls_sha256_sw_finish(&ctx_sw, output);
mbedtls_sha256_sw_free(&ctx_sw);
}
}
void mbedtls_sha256_hw_process(crypto_sha_context *ctx, const unsigned char data[64])
{
mbedtls_sha256_hw_update(ctx, data, 64);
}
#endif /* MBEDTLS_SHA256_ALT */
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
#if defined(MBEDTLS_SHA512_ALT)
void mbedtls_sha512_hw_init(crypto_sha_context *ctx)
{
crypto_init();
memset(ctx, 0, sizeof(crypto_sha_context));
}
void mbedtls_sha512_hw_free(crypto_sha_context *ctx)
{
if (ctx == NULL) {
return;
}
crypto_zeroize(ctx, sizeof(crypto_sha_context));
}
void mbedtls_sha512_hw_clone(crypto_sha_context *dst,
const crypto_sha_context *src)
{
*dst = *src;
}
void mbedtls_sha512_hw_starts( crypto_sha_context *ctx, int is384)
{
// NOTE: mbedtls may call mbedtls_shaXXX_starts multiple times and then call the ending mbedtls_shaXXX_finish. Guard from it.
CRPT->HMAC_CTL |= CRPT_HMAC_CTL_STOP_Msk;
ctx->total = 0;
ctx->buffer_left = 0;
ctx->blocksize = 128;
ctx->blocksize_mask = 0x7F;
ctx->is224_384 = is384;
SHA_Open(is384 ? SHA_MODE_SHA384 : SHA_MODE_SHA512, SHA_NO_SWAP, 0);
// Ensure we have correct initial inernal states in SHA_DGST registers even though SHA H/W is not actually started.
CRPT->HMAC_CTL |= CRPT_HMAC_CTL_START_Msk;
return;
}
void mbedtls_sha512_hw_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen)
{
crypto_sha_update(ctx, input, ilen);
}
void mbedtls_sha512_hw_finish(crypto_sha_context *ctx, unsigned char output[64])
{
// H/W SHA cannot handle zero data well. Fall back to S/W SHA.
if (ctx->total) {
crypto_sha_update_nobuf(ctx, ctx->buffer, ctx->buffer_left, 1);
ctx->buffer_left = 0;
crypto_sha_getinternstate(output, ctx->is224_384 ? 48 : 64);
CRPT->HMAC_CTL |= CRPT_HMAC_CTL_STOP_Msk;
}
else {
mbedtls_sha512_sw_context ctx_sw;
mbedtls_sha512_sw_init(&ctx_sw);
mbedtls_sha512_sw_starts(&ctx_sw, ctx->is224_384);
mbedtls_sha512_sw_finish(&ctx_sw, output);
mbedtls_sha512_sw_free(&ctx_sw);
}
}
void mbedtls_sha512_hw_process(crypto_sha_context *ctx, const unsigned char data[128])
{
mbedtls_sha512_hw_update(ctx, data, 128);
}
#endif /* MBEDTLS_SHA512_ALT */
#endif /* MBEDTLS_SHA512_C */
#if defined(MBEDTLS_SHA1_C) || defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA512_C)
#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_SHA512_ALT)
void crypto_sha_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen)
{
if (ilen == 0) {
return;
}
size_t fill = ctx->blocksize - ctx->buffer_left;
ctx->total += (uint32_t) ilen;
if (ctx->buffer_left && ilen >= fill) {
memcpy((void *) (ctx->buffer + ctx->buffer_left), input, fill);
input += fill;
ilen -= fill;
ctx->buffer_left += fill;
if (ilen) {
crypto_sha_update_nobuf(ctx, ctx->buffer, ctx->buffer_left, 0);
ctx->buffer_left = 0;
}
}
while (ilen > ctx->blocksize) {
crypto_sha_update_nobuf(ctx, input, ctx->blocksize, 0);
input += ctx->blocksize;
ilen -= ctx->blocksize;
}
if (ilen > 0) {
memcpy((void *) (ctx->buffer + ctx->buffer_left), input, ilen);
ctx->buffer_left += ilen;
}
}
void crypto_sha_update_nobuf(crypto_sha_context *ctx, const unsigned char *input, size_t ilen, int islast)
{
// Accept only:
// 1. Last block which may be incomplete
// 2. Non-last block which is complete
MBED_ASSERT(islast || ilen == ctx->blocksize);
const unsigned char *in_pos = input;
int rmn = ilen;
uint32_t sha_ctl_start = (CRPT->HMAC_CTL & ~(CRPT_HMAC_CTL_DMALAST_Msk | CRPT_HMAC_CTL_DMAEN_Msk | CRPT_HMAC_CTL_HMACEN_Msk)) | CRPT_HMAC_CTL_START_Msk;
uint32_t sha_opmode = (CRPT->HMAC_CTL & CRPT_HMAC_CTL_OPMODE_Msk) >> CRPT_HMAC_CTL_OPMODE_Pos;
uint32_t DGST0_old = 0, DGST1_old = 0, DGST2_old = 0, DGST3_old = 0, DGST4_old = 0, DGST5_old = 0, DGST6_old = 0, DGST7_old = 0,
DGST8_old = 0, DGST9_old = 0, DGST10_old = 0, DGST11_old = 0, DGST12_old = 0, DGST13_old = 0, DGST14_old = 0, DGST15_old = 0;
while (rmn > 0) {
CRPT->HMAC_CTL = sha_ctl_start;
uint32_t data = nu_get32_be(in_pos);
if (rmn <= 4) { // Last word of a (in)complete block
if (islast) {
uint32_t lastblock_size = ctx->total & ctx->blocksize_mask;
if (lastblock_size == 0) {
lastblock_size = ctx->blocksize;
}
CRPT->HMAC_DMACNT = lastblock_size;
CRPT->HMAC_CTL = sha_ctl_start | CRPT_HMAC_CTL_DMALAST_Msk;
}
else {
switch (sha_opmode) {
case SHA_MODE_SHA512:
DGST15_old = CRPT->HMAC_DGST[15];
DGST14_old = CRPT->HMAC_DGST[14];
DGST13_old = CRPT->HMAC_DGST[13];
DGST12_old = CRPT->HMAC_DGST[12];
case SHA_MODE_SHA384:
DGST11_old = CRPT->HMAC_DGST[11];
DGST10_old = CRPT->HMAC_DGST[10];
DGST9_old = CRPT->HMAC_DGST[9];
DGST8_old = CRPT->HMAC_DGST[8];
case SHA_MODE_SHA256:
DGST7_old = CRPT->HMAC_DGST[7];
case SHA_MODE_SHA224:
DGST5_old = CRPT->HMAC_DGST[5];
DGST6_old = CRPT->HMAC_DGST[6];
case SHA_MODE_SHA1:
DGST0_old = CRPT->HMAC_DGST[0];
DGST1_old = CRPT->HMAC_DGST[1];
DGST2_old = CRPT->HMAC_DGST[2];
DGST3_old = CRPT->HMAC_DGST[3];
DGST4_old = CRPT->HMAC_DGST[4];
}
CRPT->HMAC_CTL = sha_ctl_start;
}
}
else { // Non-last word of a complete block
CRPT->HMAC_CTL = sha_ctl_start;
}
while (! (CRPT->HMAC_STS & CRPT_HMAC_STS_DATINREQ_Msk));
CRPT->HMAC_DATIN = data;
in_pos += 4;
rmn -= 4;
}
if (islast) { // Finish of last block
while (CRPT->HMAC_STS & CRPT_HMAC_STS_BUSY_Msk);
}
else { // Finish of non-last block
// No H/W flag to indicate finish of non-last block process.
// Values of SHA_DGSTx registers will change as last word of the block is input, so use it for judgement.
int isfinish = 0;
while (! isfinish) {
switch (sha_opmode) {
case SHA_MODE_SHA512:
if (DGST12_old != CRPT->HMAC_DGST[12] || DGST13_old != CRPT->HMAC_DGST[13] || DGST14_old != CRPT->HMAC_DGST[14] ||
DGST15_old != CRPT->HMAC_DGST[15]) {
isfinish = 1;
break;
}
case SHA_MODE_SHA384:
if (DGST8_old != CRPT->HMAC_DGST[8] || DGST9_old != CRPT->HMAC_DGST[9] || DGST10_old != CRPT->HMAC_DGST[10] ||
DGST11_old != CRPT->HMAC_DGST[11]) {
isfinish = 1;
break;
}
case SHA_MODE_SHA256:
if (DGST7_old != CRPT->HMAC_DGST[7]) {
isfinish = 1;
break;
}
case SHA_MODE_SHA224:
if (DGST5_old != CRPT->HMAC_DGST[5] || DGST6_old != CRPT->HMAC_DGST[6]) {
isfinish = 1;
break;
}
case SHA_MODE_SHA1:
if (DGST0_old != CRPT->HMAC_DGST[0] || DGST1_old != CRPT->HMAC_DGST[1] || DGST2_old != CRPT->HMAC_DGST[2] ||
DGST3_old != CRPT->HMAC_DGST[3] || DGST4_old != CRPT->HMAC_DGST[4]) {
isfinish = 1;
break;
}
}
}
}
}
void crypto_sha_getinternstate(unsigned char output[], size_t olen)
{
uint32_t *in_pos = (uint32_t *) &CRPT->HMAC_DGST[0];
unsigned char *out_pos = output;
uint32_t rmn = olen;
while (rmn) {
uint32_t val = *in_pos ++;
nu_set32_be(out_pos, val);
out_pos += 4;
rmn -= 4;
}
}
#endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT || MBEDTLS_SHA512_ALT */
#endif /* MBEDTLS_SHA1_C || MBEDTLS_SHA256_C || MBEDTLS_SHA512_C */
#endif /* MBEDTLS_SHA1_C || MBEDTLS_SHA256_C || MBEDTLS_SHA512_C */

View File

@ -0,0 +1,108 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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 MBEDTLS_SHA_ALT_HW_H
#define MBEDTLS_SHA_ALT_HW_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA1_C) || defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA512_C)
#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_SHA512_ALT)
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA context structure
*/
typedef struct
{
uint32_t total; /*!< number of bytes processed */
unsigned char buffer[128]; /*!< data block being processed. Max of SHA-1/SHA-256/SHA-512 */
uint16_t buffer_left;
uint16_t blocksize; /*!< block size */
uint32_t blocksize_mask; /*!< block size mask */
int is224_384; /*!< 0 => SHA-256/SHA-512, else SHA-224/384 */
}
crypto_sha_context;
void crypto_sha_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen);
void crypto_sha_update_nobuf(crypto_sha_context *ctx, const unsigned char *input, size_t ilen, int islast);
void crypto_sha_getinternstate(unsigned char output[], size_t olen);
#if defined(MBEDTLS_SHA1_C)
#if defined(MBEDTLS_SHA1_ALT)
void mbedtls_sha1_hw_init( crypto_sha_context *ctx );
void mbedtls_sha1_hw_free( crypto_sha_context *ctx );
void mbedtls_sha1_hw_clone( crypto_sha_context *dst,
const crypto_sha_context *src );
void mbedtls_sha1_hw_starts( crypto_sha_context *ctx );
void mbedtls_sha1_hw_update( crypto_sha_context *ctx, const unsigned char *input, size_t ilen );
void mbedtls_sha1_hw_finish( crypto_sha_context *ctx, unsigned char output[20] );
void mbedtls_sha1_hw_process( crypto_sha_context *ctx, const unsigned char data[64] );
#endif /* MBEDTLS_SHA1_ALT */
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
#if defined(MBEDTLS_SHA256_ALT)
void mbedtls_sha256_hw_init( crypto_sha_context *ctx );
void mbedtls_sha256_hw_free( crypto_sha_context *ctx );
void mbedtls_sha256_hw_clone( crypto_sha_context *dst,
const crypto_sha_context *src );
void mbedtls_sha256_hw_starts( crypto_sha_context *ctx, int is224 );
void mbedtls_sha256_hw_update( crypto_sha_context *ctx, const unsigned char *input,
size_t ilen );
void mbedtls_sha256_hw_finish( crypto_sha_context *ctx, unsigned char output[32] );
void mbedtls_sha256_hw_process( crypto_sha_context *ctx, const unsigned char data[64] );
#endif /* MBEDTLS_SHA256_ALT */
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
#if defined(MBEDTLS_SHA512_ALT)
void mbedtls_sha512_hw_init( crypto_sha_context *ctx );
void mbedtls_sha512_hw_free( crypto_sha_context *ctx );
void mbedtls_sha512_hw_clone( crypto_sha_context *dst,
const crypto_sha_context *src );
void mbedtls_sha512_hw_starts( crypto_sha_context *ctx, int is384 );
void mbedtls_sha512_hw_update( crypto_sha_context *ctx, const unsigned char *input,
size_t ilen );
void mbedtls_sha512_hw_finish( crypto_sha_context *ctx, unsigned char output[64] );
void mbedtls_sha512_hw_process( crypto_sha_context *ctx, const unsigned char data[128] );
#endif /* MBEDTLS_SHA512_ALT */
#endif /* MBEDTLS_SHA512_C */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT || MBEDTLS_SHA512_ALT */
#endif /* MBEDTLS_SHA1_C || MBEDTLS_SHA256_C || MBEDTLS_SHA512_C*/
#endif /* sha_alt.h */

View File

@ -0,0 +1,30 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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 MBEDTLS_DEVICE_H
#define MBEDTLS_DEVICE_H
#define MBEDTLS_DES_ALT
#define MBEDTLS_SHA1_ALT
#define MBEDTLS_SHA256_ALT
#define MBEDTLS_AES_ALT
#define MBEDTLS_AES_SETKEY_ENC_ALT
#define MBEDTLS_AES_SETKEY_DEC_ALT
#define MBEDTLS_AES_ENCRYPT_ALT
#define MBEDTLS_AES_DECRYPT_ALT
#endif /* MBEDTLS_DEVICE_H */

View File

@ -21,9 +21,6 @@
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
*/
/* Compatible with mbed OS 2 which doesn't support mbedtls */
#if MBED_CONF_RTOS_PRESENT
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
@ -591,5 +588,3 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
#endif /* MBEDTLS_AES_C */
#endif /* MBED_CONF_RTOS_PRESENT */

View File

@ -0,0 +1,285 @@
/**
* \file aes_alt.h
*
* \brief AES block cipher
*
* Copyright (C) 2006-2015, 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 part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_AES_ALT_H
#define MBEDTLS_AES_ALT_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_AES_C)
#if defined(MBEDTLS_AES_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief AES context structure
*
* \note buf is able to hold 32 extra bytes, which can be used:
* - for alignment purposes if VIA padlock is used, and/or
* - to simplify key expansion in the 256-bit case by
* generating an extra round key
*/
typedef struct
{
uint32_t keySize;
uint32_t encDec;
uint32_t opMode;
uint32_t channel;
uint32_t swapType;
uint32_t *iv;
unsigned char prv_iv[16];
#if 1
uint32_t buf[8];
/* For comparsion with software AES for correctness */
#else
uint32_t buf[68]; /*!< unaligned data */
int nr; /*!< number of rounds */
uint32_t *rk; /*!< AES round keys */
#endif
}
mbedtls_aes_context;
/**
* \brief Initialize AES context
*
* \param ctx AES context to be initialized
*/
void mbedtls_aes_init( mbedtls_aes_context *ctx );
/**
* \brief Clear AES context
*
* \param ctx AES context to be cleared
*/
void mbedtls_aes_free( mbedtls_aes_context *ctx );
/**
* \brief AES key schedule (encryption)
*
* \param ctx AES context to be initialized
* \param key encryption key
* \param keybits must be 128, 192 or 256
*
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
*/
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits );
/**
* \brief AES key schedule (decryption)
*
* \param ctx AES context to be initialized
* \param key decryption key
* \param keybits must be 128, 192 or 256
*
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
*/
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits );
/**
* \brief AES-ECB block encryption/decryption
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if successful
*/
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief AES-CBC buffer encryption/decryption
* Length should be a multiple of the block
* size (16 bytes)
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
*/
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/**
* \brief AES-CFB128 buffer encryption/decryption.
*
* Note: Due to the nature of CFB you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param length length of the input data
* \param iv_off offset in IV (updated after use)
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful
*/
int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief AES-CFB8 buffer encryption/decryption.
*
* Note: Due to the nature of CFB you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful
*/
int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /*MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/**
* \brief AES-CTR buffer encryption/decryption
*
* Warning: You have to keep the maximum use of your counter in mind!
*
* Note: Due to the nature of CTR you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
*
* \param ctx AES context
* \param length The length of the data
* \param nc_off The offset in the current stream_block (for resuming
* within current cipher stream). The offset pointer to
* should be 0 at the start of a stream.
* \param nonce_counter The 128-bit nonce and counter.
* \param stream_block The saved stream-block for resuming. Is overwritten
* by the function.
* \param input The input data stream
* \param output The output data stream
*
* \return 0 if successful
*/
int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[16],
unsigned char stream_block[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CTR */
/**
* \brief Internal AES block encryption function
* (Only exposed to allow overriding it,
* see MBEDTLS_AES_ENCRYPT_ALT)
*
* \param ctx AES context
* \param input Plaintext block
* \param output Output (ciphertext) block
*/
void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief Internal AES block decryption function
* (Only exposed to allow overriding it,
* see MBEDTLS_AES_DECRYPT_ALT)
*
* \param ctx AES context
* \param input Ciphertext block
* \param output Output (plaintext) block
*/
void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_AES_ALT */
#endif /* MBEDTLS_AES_C */
#endif /* aes_alt.h */

View File

@ -0,0 +1,63 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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"
#include "mbed_assert.h"
#include "nu_modutil.h"
#include "nu_bitutil.h"
#include "crypto-misc.h"
static int crypto_inited = 0;
static int crypto_sha_avail = 1;
void crypto_init(void)
{
if (crypto_inited) {
return;
}
crypto_inited = 1;
CLK_EnableModuleClock(CRPT_MODULE);
}
/* Implementation that should never be optimized out by the compiler */
void crypto_zeroize(void *v, size_t n)
{
volatile unsigned char *p = (unsigned char*) v;
while (n--) {
*p++ = 0;
}
}
int crypto_sha_acquire(void)
{
if (crypto_sha_avail) {
crypto_sha_avail = 0;
return 1;
}
else {
return 0;
}
}
void crypto_sha_release(void)
{
if (! crypto_sha_avail) {
crypto_sha_avail = 1;
}
}

View File

@ -0,0 +1,33 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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_CRYPTO_MISC_H
#define MBED_CRYPTO_MISC_H
#ifdef __cplusplus
extern "C" {
#endif
void crypto_init(void);
void crypto_zeroize(void *v, size_t n);
int crypto_sha_acquire(void);
void crypto_sha_release(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,410 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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.
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_DES_C)
#if defined(MBEDTLS_DES_ALT)
#include <string.h>
#include "mbedtls/des.h"
#include "des_alt.h"
#include "crypto-misc.h"
#include "nu_bitutil.h"
#include "mbed_toolchain.h"
// Must be a multiple of 64-bit block size
#define MAXSIZE_DMABUF (8 * 5)
static uint8_t dmabuf_in[MAXSIZE_DMABUF] MBED_ALIGN(4);
static uint8_t dmabuf_out[MAXSIZE_DMABUF] MBED_ALIGN(4);
static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_SIZE], int enc, uint32_t tdes_opmode, size_t length,
unsigned char iv[8], const unsigned char *input, unsigned char *output);
void mbedtls_des_init(mbedtls_des_context *ctx)
{
crypto_init();
memset(ctx, 0, sizeof(mbedtls_des_context));
}
void mbedtls_des_free( mbedtls_des_context *ctx )
{
if (ctx == NULL) {
return;
}
crypto_zeroize(ctx, sizeof(mbedtls_des_context));
}
void mbedtls_des3_init( mbedtls_des3_context *ctx )
{
crypto_init();
memset(ctx, 0, sizeof(mbedtls_des3_context));
}
void mbedtls_des3_free( mbedtls_des3_context *ctx )
{
if (ctx == NULL) {
return;
}
crypto_zeroize(ctx, sizeof (mbedtls_des3_context));
}
static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
254 };
void mbedtls_des_key_set_parity(unsigned char key[MBEDTLS_DES_KEY_SIZE])
{
int i;
for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) {
key[i] = odd_parity_table[key[i] / 2];
}
}
/*
* Check the given key's parity, returns 1 on failure, 0 on SUCCESS
*/
int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
{
int i;
for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
if( key[i] != odd_parity_table[key[i] / 2] )
return( 1 );
return( 0 );
}
/*
* Table of weak and semi-weak keys
*
* Source: http://en.wikipedia.org/wiki/Weak_key
*
* Weak:
* Alternating ones + zeros (0x0101010101010101)
* Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
* '0xE0E0E0E0F1F1F1F1'
* '0x1F1F1F1F0E0E0E0E'
*
* Semi-weak:
* 0x011F011F010E010E and 0x1F011F010E010E01
* 0x01E001E001F101F1 and 0xE001E001F101F101
* 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
* 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
* 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
* 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
*
*/
#define WEAK_KEY_COUNT 16
static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
{
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
{ 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
{ 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
{ 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
{ 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
{ 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
{ 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
{ 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
{ 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
{ 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
{ 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
{ 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
{ 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
{ 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
{ 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
};
int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
{
int i;
for( i = 0; i < WEAK_KEY_COUNT; i++ )
if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
return( 1 );
return( 0 );
}
/*
* DES key schedule (56-bit, encryption)
*/
int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
{
ctx->enc = 1;
// Keying option 3: All three keys are identical, i.e. K1 = K2 = K3.
ctx->keyopt = 3;
memcpy(ctx->key[0], key, MBEDTLS_DES_KEY_SIZE);
memcpy(ctx->key[1], key, MBEDTLS_DES_KEY_SIZE);
memcpy(ctx->key[2], key, MBEDTLS_DES_KEY_SIZE);
return 0;
}
/*
* DES key schedule (56-bit, decryption)
*/
int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
{
ctx->enc = 0;
// Keying option 3: All three keys are identical, i.e. K1 = K2 = K3.
ctx->keyopt = 3;
memcpy(ctx->key[0], key, MBEDTLS_DES_KEY_SIZE);
memcpy(ctx->key[1], key, MBEDTLS_DES_KEY_SIZE);
memcpy(ctx->key[2], key, MBEDTLS_DES_KEY_SIZE);
return 0;
}
/*
* Triple-DES key schedule (112-bit, encryption)
*/
int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
{
ctx->enc = 1;
// Keying option 2: K1 and K2 are independent, and K3 = K1.
ctx->keyopt = 2;
memcpy(ctx->key[0], key, MBEDTLS_DES_KEY_SIZE);
memcpy(ctx->key[1], key + MBEDTLS_DES_KEY_SIZE, MBEDTLS_DES_KEY_SIZE);
memcpy(ctx->key[2], key, MBEDTLS_DES_KEY_SIZE);
return 0;
}
/*
* Triple-DES key schedule (112-bit, decryption)
*/
int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
{
ctx->enc = 0;
// Keying option 2: K1 and K2 are independent, and K3 = K1.
ctx->keyopt = 2;
memcpy(ctx->key[0], key, MBEDTLS_DES_KEY_SIZE);
memcpy(ctx->key[1], key + MBEDTLS_DES_KEY_SIZE, MBEDTLS_DES_KEY_SIZE);
memcpy(ctx->key[2], key, MBEDTLS_DES_KEY_SIZE);
return 0;
}
/*
* Triple-DES key schedule (168-bit, encryption)
*/
int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
{
ctx->enc = 1;
// Keying option 1: All three keys are independent.
ctx->keyopt = 1;
memcpy(ctx->key[0], key, MBEDTLS_DES_KEY_SIZE);
memcpy(ctx->key[1], key + MBEDTLS_DES_KEY_SIZE, MBEDTLS_DES_KEY_SIZE);
memcpy(ctx->key[2], key + MBEDTLS_DES_KEY_SIZE * 2, MBEDTLS_DES_KEY_SIZE);
return 0;
}
/*
* Triple-DES key schedule (168-bit, decryption)
*/
int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
{
ctx->enc = 0;
// Keying option 1: All three keys are independent.
ctx->keyopt = 1;
memcpy(ctx->key[0], key, MBEDTLS_DES_KEY_SIZE);
memcpy(ctx->key[1], key + MBEDTLS_DES_KEY_SIZE, MBEDTLS_DES_KEY_SIZE);
memcpy(ctx->key[2], key + MBEDTLS_DES_KEY_SIZE * 2, MBEDTLS_DES_KEY_SIZE);
return 0;
}
/*
* DES-ECB block encryption/decryption
*/
int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
const unsigned char input[8],
unsigned char output[8] )
{
unsigned char iv[8] = {0x00};
return mbedtls_des_docrypt(ctx->keyopt, ctx->key, ctx->enc, DES_MODE_ECB, 8, iv, input, output);
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/*
* DES-CBC buffer encryption/decryption
*/
int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output )
{
return mbedtls_des_docrypt(ctx->keyopt, ctx->key, mode == MBEDTLS_DES_ENCRYPT, DES_MODE_CBC, length, iv, input, output);
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
/*
* 3DES-ECB block encryption/decryption
*/
int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
const unsigned char input[8],
unsigned char output[8] )
{
unsigned char iv[8] = {0x00};
return mbedtls_des_docrypt(ctx->keyopt, ctx->key, ctx->enc, TDES_MODE_ECB, 8, iv, input, output);
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/*
* 3DES-CBC buffer encryption/decryption
*/
int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output )
{
return mbedtls_des_docrypt(ctx->keyopt, ctx->key, mode == MBEDTLS_DES_ENCRYPT, TDES_MODE_CBC, length, iv, input, output);
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_SIZE], int enc, uint32_t tdes_opmode, size_t length,
unsigned char iv[8], const unsigned char *input, unsigned char *output)
{
if (length % 8) {
return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
}
// NOTE: Don't call driver function TDES_Open in BSP because it doesn't support TDES_CTL[3KEYS] setting.
CRPT->TDES_CTL = (0 << CRPT_TDES_CTL_CHANNEL_Pos) | (enc << CRPT_TDES_CTL_ENCRPT_Pos) |
tdes_opmode | (TDES_IN_OUT_WHL_SWAP << CRPT_TDES_CTL_BLKSWAP_Pos);
// Keying option 1: All three keys are independent.
// Keying option 2: K1 and K2 are independent, and K3 = K1.
// Keying option 3: All three keys are identical, i.e. K1 = K2 = K3.
if (keyopt == 1) {
CRPT->TDES_CTL |= CRPT_TDES_CTL_3KEYS_Msk;
}
else {
CRPT->TDES_CTL &= ~CRPT_TDES_CTL_3KEYS_Msk;
}
// Set DES/TDES keys
// NOTE: Don't call driver function TDES_SetKey in BSP because it doesn't support endian swap.
uint32_t val;
volatile uint32_t *tdes_key = (uint32_t *) ((uint32_t) &CRPT->TDES0_KEY1H + (0x40 * 0));
val = nu_get32_be(key[0] + 0);
*tdes_key ++ = val;
val = nu_get32_be(key[0] + 4);
*tdes_key ++ = val;
val = nu_get32_be(key[1] + 0);
*tdes_key ++ = val;
val = nu_get32_be(key[1] + 4);
*tdes_key ++ = val;
val = nu_get32_be(key[2] + 0);
*tdes_key ++ = val;
val = nu_get32_be(key[2] + 4);
*tdes_key ++ = val;
uint32_t rmn = length;
const unsigned char *in_pos = input;
unsigned char *out_pos = output;
while (rmn) {
uint32_t data_len = (rmn <= MAXSIZE_DMABUF) ? rmn : MAXSIZE_DMABUF;
uint32_t ivh, ivl;
ivh = nu_get32_be(iv);
ivl = nu_get32_be(iv + 4);
TDES_SetInitVect(0, ivh, ivl);
memcpy(dmabuf_in, in_pos, data_len);
TDES_SetDMATransfer(0, (uint32_t) dmabuf_in, (uint32_t) dmabuf_out, data_len);
// Start enc/dec.
// NOTE: Don't call driver function TDES_Start in BSP because it will override TDES_CTL[3KEYS] setting.
CRPT->TDES_CTL |= CRPT_TDES_CTL_START_Msk | (CRYPTO_DMA_ONE_SHOT << CRPT_TDES_CTL_DMALAST_Pos);
while (CRPT->TDES_STS & CRPT_TDES_STS_BUSY_Msk);
memcpy(out_pos, dmabuf_out, data_len);
in_pos += data_len;
out_pos += data_len;
rmn -= data_len;
// Update IV for next block enc/dec in next function call
switch (tdes_opmode) {
case DES_MODE_OFB:
case TDES_MODE_OFB: {
// OFB: IV (enc/dec) = output block XOR input block
uint32_t lbh, lbl;
// Last block of input data
lbh = nu_get32_be(dmabuf_in + data_len - 8 + 4);
lbl = nu_get32_be(dmabuf_in + data_len - 8 + 0);
// Last block of output data
ivh = nu_get32_be(dmabuf_out + 4);
ivl = nu_get32_be(dmabuf_out + 0);
ivh = ivh ^ lbh;
ivl = ivl ^ lbl;
nu_set32_be(iv + 4, ivh);
nu_set32_be(iv, ivl);
break;
}
case DES_MODE_CBC:
case DES_MODE_CFB:
case TDES_MODE_CBC:
case TDES_MODE_CFB: {
// CBC/CFB: IV (enc) = output block
// IV (dec) = input block
if (enc) {
memcpy(iv, dmabuf_out + data_len - 8, 8);
}
else {
memcpy(iv, dmabuf_in + data_len - 8, 8);
}
}
}
}
return 0;
}
#endif /* MBEDTLS_DES_ALT */
#endif /* MBEDTLS_DES_C */

View File

@ -0,0 +1,282 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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 MBEDTLS_DES_ALT_H
#define MBEDTLS_DES_ALT_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_DES_C)
#if defined(MBEDTLS_DES_ALT)
#include <stddef.h>
#include <stdint.h>
#include "des.h"
#include "des_alt_sw.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief DES context structure
*/
typedef struct
{
int enc; /*!< 0: dec, 1: enc */
uint16_t keyopt;
uint8_t key[3][MBEDTLS_DES_KEY_SIZE]; /*!< 3DES keys */
}
mbedtls_des_context;
/**
* \brief Triple-DES context structure
*/
typedef struct
{
int enc; /*!< 0: dec, 1: enc */
uint16_t keyopt;
uint8_t key[3][MBEDTLS_DES_KEY_SIZE]; /*!< 3DES keys */
}
mbedtls_des3_context;
/**
* \brief Initialize DES context
*
* \param ctx DES context to be initialized
*/
void mbedtls_des_init( mbedtls_des_context *ctx );
/**
* \brief Clear DES context
*
* \param ctx DES context to be cleared
*/
void mbedtls_des_free( mbedtls_des_context *ctx );
/**
* \brief Initialize Triple-DES context
*
* \param ctx DES3 context to be initialized
*/
void mbedtls_des3_init( mbedtls_des3_context *ctx );
/**
* \brief Clear Triple-DES context
*
* \param ctx DES3 context to be cleared
*/
void mbedtls_des3_free( mbedtls_des3_context *ctx );
/**
* \brief Set key parity on the given key to odd.
*
* DES keys are 56 bits long, but each byte is padded with
* a parity bit to allow verification.
*
* \param key 8-byte secret key
*/
void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Check that key parity on the given key is odd.
*
* DES keys are 56 bits long, but each byte is padded with
* a parity bit to allow verification.
*
* \param key 8-byte secret key
*
* \return 0 is parity was ok, 1 if parity was not correct.
*/
int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Check that key is not a weak or semi-weak DES key
*
* \param key 8-byte secret key
*
* \return 0 if no weak key was found, 1 if a weak key was identified.
*/
int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief DES key schedule (56-bit, encryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*
* \return 0
*/
int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief DES key schedule (56-bit, decryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*
* \return 0
*/
int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Triple-DES key schedule (112-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*
* \return 0
*/
int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
/**
* \brief Triple-DES key schedule (112-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*
* \return 0
*/
int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
/**
* \brief Triple-DES key schedule (168-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*
* \return 0
*/
int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
/**
* \brief Triple-DES key schedule (168-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*
* \return 0
*/
int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
/**
* \brief DES-ECB block encryption/decryption
*
* \param ctx DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*/
int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief DES-CBC buffer encryption/decryption
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx DES context
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*/
int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
/**
* \brief 3DES-ECB block encryption/decryption
*
* \param ctx 3DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*/
int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief 3DES-CBC buffer encryption/decryption
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx 3DES context
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
*/
int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
/**
* \brief Internal function for key expansion.
* (Only exposed to allow overriding it,
* see MBEDTLS_DES_SETKEY_ALT)
*
* \param SK Round keys
* \param key Base key
*/
void mbedtls_des_setkey( uint32_t SK[32],
const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_DES_ALT */
#endif /* MBEDTLS_DES_C */
#endif /* des_alt.h */

View File

@ -0,0 +1,797 @@
/*
* FIPS-46-3 compliant Triple-DES implementation
*
* Copyright (C) 2006-2015, 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 part of mbed TLS (https://tls.mbed.org)
*/
/*
* DES, on which TDES is based, was originally designed by Horst Feistel
* at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
*
* http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_DES_C)
#if defined(MBEDTLS_DES_ALT)
#include "mbedtls/des.h"
#include <string.h>
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
}
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
/*
* Expanded DES S-boxes
*/
static const uint32_t SB1[64] =
{
0x01010400, 0x00000000, 0x00010000, 0x01010404,
0x01010004, 0x00010404, 0x00000004, 0x00010000,
0x00000400, 0x01010400, 0x01010404, 0x00000400,
0x01000404, 0x01010004, 0x01000000, 0x00000004,
0x00000404, 0x01000400, 0x01000400, 0x00010400,
0x00010400, 0x01010000, 0x01010000, 0x01000404,
0x00010004, 0x01000004, 0x01000004, 0x00010004,
0x00000000, 0x00000404, 0x00010404, 0x01000000,
0x00010000, 0x01010404, 0x00000004, 0x01010000,
0x01010400, 0x01000000, 0x01000000, 0x00000400,
0x01010004, 0x00010000, 0x00010400, 0x01000004,
0x00000400, 0x00000004, 0x01000404, 0x00010404,
0x01010404, 0x00010004, 0x01010000, 0x01000404,
0x01000004, 0x00000404, 0x00010404, 0x01010400,
0x00000404, 0x01000400, 0x01000400, 0x00000000,
0x00010004, 0x00010400, 0x00000000, 0x01010004
};
static const uint32_t SB2[64] =
{
0x80108020, 0x80008000, 0x00008000, 0x00108020,
0x00100000, 0x00000020, 0x80100020, 0x80008020,
0x80000020, 0x80108020, 0x80108000, 0x80000000,
0x80008000, 0x00100000, 0x00000020, 0x80100020,
0x00108000, 0x00100020, 0x80008020, 0x00000000,
0x80000000, 0x00008000, 0x00108020, 0x80100000,
0x00100020, 0x80000020, 0x00000000, 0x00108000,
0x00008020, 0x80108000, 0x80100000, 0x00008020,
0x00000000, 0x00108020, 0x80100020, 0x00100000,
0x80008020, 0x80100000, 0x80108000, 0x00008000,
0x80100000, 0x80008000, 0x00000020, 0x80108020,
0x00108020, 0x00000020, 0x00008000, 0x80000000,
0x00008020, 0x80108000, 0x00100000, 0x80000020,
0x00100020, 0x80008020, 0x80000020, 0x00100020,
0x00108000, 0x00000000, 0x80008000, 0x00008020,
0x80000000, 0x80100020, 0x80108020, 0x00108000
};
static const uint32_t SB3[64] =
{
0x00000208, 0x08020200, 0x00000000, 0x08020008,
0x08000200, 0x00000000, 0x00020208, 0x08000200,
0x00020008, 0x08000008, 0x08000008, 0x00020000,
0x08020208, 0x00020008, 0x08020000, 0x00000208,
0x08000000, 0x00000008, 0x08020200, 0x00000200,
0x00020200, 0x08020000, 0x08020008, 0x00020208,
0x08000208, 0x00020200, 0x00020000, 0x08000208,
0x00000008, 0x08020208, 0x00000200, 0x08000000,
0x08020200, 0x08000000, 0x00020008, 0x00000208,
0x00020000, 0x08020200, 0x08000200, 0x00000000,
0x00000200, 0x00020008, 0x08020208, 0x08000200,
0x08000008, 0x00000200, 0x00000000, 0x08020008,
0x08000208, 0x00020000, 0x08000000, 0x08020208,
0x00000008, 0x00020208, 0x00020200, 0x08000008,
0x08020000, 0x08000208, 0x00000208, 0x08020000,
0x00020208, 0x00000008, 0x08020008, 0x00020200
};
static const uint32_t SB4[64] =
{
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802080, 0x00800081, 0x00800001, 0x00002001,
0x00000000, 0x00802000, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00800080, 0x00800001,
0x00000001, 0x00002000, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002001, 0x00002080,
0x00800081, 0x00000001, 0x00002080, 0x00800080,
0x00002000, 0x00802080, 0x00802081, 0x00000081,
0x00800080, 0x00800001, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00000000, 0x00802000,
0x00002080, 0x00800080, 0x00800081, 0x00000001,
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802081, 0x00000081, 0x00000001, 0x00002000,
0x00800001, 0x00002001, 0x00802080, 0x00800081,
0x00002001, 0x00002080, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002000, 0x00802080
};
static const uint32_t SB5[64] =
{
0x00000100, 0x02080100, 0x02080000, 0x42000100,
0x00080000, 0x00000100, 0x40000000, 0x02080000,
0x40080100, 0x00080000, 0x02000100, 0x40080100,
0x42000100, 0x42080000, 0x00080100, 0x40000000,
0x02000000, 0x40080000, 0x40080000, 0x00000000,
0x40000100, 0x42080100, 0x42080100, 0x02000100,
0x42080000, 0x40000100, 0x00000000, 0x42000000,
0x02080100, 0x02000000, 0x42000000, 0x00080100,
0x00080000, 0x42000100, 0x00000100, 0x02000000,
0x40000000, 0x02080000, 0x42000100, 0x40080100,
0x02000100, 0x40000000, 0x42080000, 0x02080100,
0x40080100, 0x00000100, 0x02000000, 0x42080000,
0x42080100, 0x00080100, 0x42000000, 0x42080100,
0x02080000, 0x00000000, 0x40080000, 0x42000000,
0x00080100, 0x02000100, 0x40000100, 0x00080000,
0x00000000, 0x40080000, 0x02080100, 0x40000100
};
static const uint32_t SB6[64] =
{
0x20000010, 0x20400000, 0x00004000, 0x20404010,
0x20400000, 0x00000010, 0x20404010, 0x00400000,
0x20004000, 0x00404010, 0x00400000, 0x20000010,
0x00400010, 0x20004000, 0x20000000, 0x00004010,
0x00000000, 0x00400010, 0x20004010, 0x00004000,
0x00404000, 0x20004010, 0x00000010, 0x20400010,
0x20400010, 0x00000000, 0x00404010, 0x20404000,
0x00004010, 0x00404000, 0x20404000, 0x20000000,
0x20004000, 0x00000010, 0x20400010, 0x00404000,
0x20404010, 0x00400000, 0x00004010, 0x20000010,
0x00400000, 0x20004000, 0x20000000, 0x00004010,
0x20000010, 0x20404010, 0x00404000, 0x20400000,
0x00404010, 0x20404000, 0x00000000, 0x20400010,
0x00000010, 0x00004000, 0x20400000, 0x00404010,
0x00004000, 0x00400010, 0x20004010, 0x00000000,
0x20404000, 0x20000000, 0x00400010, 0x20004010
};
static const uint32_t SB7[64] =
{
0x00200000, 0x04200002, 0x04000802, 0x00000000,
0x00000800, 0x04000802, 0x00200802, 0x04200800,
0x04200802, 0x00200000, 0x00000000, 0x04000002,
0x00000002, 0x04000000, 0x04200002, 0x00000802,
0x04000800, 0x00200802, 0x00200002, 0x04000800,
0x04000002, 0x04200000, 0x04200800, 0x00200002,
0x04200000, 0x00000800, 0x00000802, 0x04200802,
0x00200800, 0x00000002, 0x04000000, 0x00200800,
0x04000000, 0x00200800, 0x00200000, 0x04000802,
0x04000802, 0x04200002, 0x04200002, 0x00000002,
0x00200002, 0x04000000, 0x04000800, 0x00200000,
0x04200800, 0x00000802, 0x00200802, 0x04200800,
0x00000802, 0x04000002, 0x04200802, 0x04200000,
0x00200800, 0x00000000, 0x00000002, 0x04200802,
0x00000000, 0x00200802, 0x04200000, 0x00000800,
0x04000002, 0x04000800, 0x00000800, 0x00200002
};
static const uint32_t SB8[64] =
{
0x10001040, 0x00001000, 0x00040000, 0x10041040,
0x10000000, 0x10001040, 0x00000040, 0x10000000,
0x00040040, 0x10040000, 0x10041040, 0x00041000,
0x10041000, 0x00041040, 0x00001000, 0x00000040,
0x10040000, 0x10000040, 0x10001000, 0x00001040,
0x00041000, 0x00040040, 0x10040040, 0x10041000,
0x00001040, 0x00000000, 0x00000000, 0x10040040,
0x10000040, 0x10001000, 0x00041040, 0x00040000,
0x00041040, 0x00040000, 0x10041000, 0x00001000,
0x00000040, 0x10040040, 0x00001000, 0x00041040,
0x10001000, 0x00000040, 0x10000040, 0x10040000,
0x10040040, 0x10000000, 0x00040000, 0x10001040,
0x00000000, 0x10041040, 0x00040040, 0x10000040,
0x10040000, 0x10001000, 0x10001040, 0x00000000,
0x10041040, 0x00041000, 0x00041000, 0x00001040,
0x00001040, 0x00040040, 0x10000000, 0x10041000
};
/*
* PC1: left and right halves bit-swap
*/
static const uint32_t LHs[16] =
{
0x00000000, 0x00000001, 0x00000100, 0x00000101,
0x00010000, 0x00010001, 0x00010100, 0x00010101,
0x01000000, 0x01000001, 0x01000100, 0x01000101,
0x01010000, 0x01010001, 0x01010100, 0x01010101
};
static const uint32_t RHs[16] =
{
0x00000000, 0x01000000, 0x00010000, 0x01010000,
0x00000100, 0x01000100, 0x00010100, 0x01010100,
0x00000001, 0x01000001, 0x00010001, 0x01010001,
0x00000101, 0x01000101, 0x00010101, 0x01010101,
};
/*
* Initial Permutation macro
*/
#define DES_IP(X,Y) \
{ \
T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \
T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \
X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \
}
/*
* Final Permutation macro
*/
#define DES_FP(X,Y) \
{ \
X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \
T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \
Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \
T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
}
/*
* DES round macro
*/
#define DES_ROUND(X,Y) \
{ \
T = *SK++ ^ X; \
Y ^= SB8[ (T ) & 0x3F ] ^ \
SB6[ (T >> 8) & 0x3F ] ^ \
SB4[ (T >> 16) & 0x3F ] ^ \
SB2[ (T >> 24) & 0x3F ]; \
\
T = *SK++ ^ ((X << 28) | (X >> 4)); \
Y ^= SB7[ (T ) & 0x3F ] ^ \
SB5[ (T >> 8) & 0x3F ] ^ \
SB3[ (T >> 16) & 0x3F ] ^ \
SB1[ (T >> 24) & 0x3F ]; \
}
#define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; }
void mbedtls_des_sw_init( mbedtls_des_sw_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_des_sw_context ) );
}
void mbedtls_des_sw_free( mbedtls_des_sw_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( ctx, sizeof( mbedtls_des_sw_context ) );
}
void mbedtls_des3_sw_init( mbedtls_des3_sw_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_des3_sw_context ) );
}
void mbedtls_des3_sw_free( mbedtls_des3_sw_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( ctx, sizeof( mbedtls_des3_sw_context ) );
}
static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
254 };
void mbedtls_des_sw_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
{
int i;
for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
key[i] = odd_parity_table[key[i] / 2];
}
/*
* Check the given key's parity, returns 1 on failure, 0 on SUCCESS
*/
int mbedtls_des_sw_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
{
int i;
for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
if( key[i] != odd_parity_table[key[i] / 2] )
return( 1 );
return( 0 );
}
/*
* Table of weak and semi-weak keys
*
* Source: http://en.wikipedia.org/wiki/Weak_key
*
* Weak:
* Alternating ones + zeros (0x0101010101010101)
* Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
* '0xE0E0E0E0F1F1F1F1'
* '0x1F1F1F1F0E0E0E0E'
*
* Semi-weak:
* 0x011F011F010E010E and 0x1F011F010E010E01
* 0x01E001E001F101F1 and 0xE001E001F101F101
* 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
* 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
* 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
* 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
*
*/
#define WEAK_KEY_COUNT 16
static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
{
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
{ 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
{ 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
{ 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
{ 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
{ 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
{ 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
{ 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
{ 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
{ 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
{ 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
{ 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
{ 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
{ 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
{ 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
};
int mbedtls_des_sw_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
{
int i;
for( i = 0; i < WEAK_KEY_COUNT; i++ )
if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
return( 1 );
return( 0 );
}
void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
{
int i;
uint32_t X, Y, T;
GET_UINT32_BE( X, key, 0 );
GET_UINT32_BE( Y, key, 4 );
/*
* Permuted Choice 1
*/
T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
| (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
| (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
| (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
| (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
| (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
| (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
X &= 0x0FFFFFFF;
Y &= 0x0FFFFFFF;
/*
* calculate subkeys
*/
for( i = 0; i < 16; i++ )
{
if( i < 2 || i == 8 || i == 15 )
{
X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
}
else
{
X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
}
*SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
| ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
| ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
| ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
| ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
| ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
| ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
| ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
| ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
| ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
| ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
*SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
| ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
| ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
| ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
| ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
| ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
| ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
| ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
| ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
| ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
| ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
}
}
/*
* DES key schedule (56-bit, encryption)
*/
int mbedtls_des_sw_setkey_enc( mbedtls_des_sw_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
{
mbedtls_des_setkey( ctx->sk, key );
return( 0 );
}
/*
* DES key schedule (56-bit, decryption)
*/
int mbedtls_des_sw_setkey_dec( mbedtls_des_sw_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
{
int i;
mbedtls_des_setkey( ctx->sk, key );
for( i = 0; i < 16; i += 2 )
{
SWAP( ctx->sk[i ], ctx->sk[30 - i] );
SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
}
return( 0 );
}
static void des3_set2key( uint32_t esk[96],
uint32_t dsk[96],
const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
{
int i;
mbedtls_des_setkey( esk, key );
mbedtls_des_setkey( dsk + 32, key + 8 );
for( i = 0; i < 32; i += 2 )
{
dsk[i ] = esk[30 - i];
dsk[i + 1] = esk[31 - i];
esk[i + 32] = dsk[62 - i];
esk[i + 33] = dsk[63 - i];
esk[i + 64] = esk[i ];
esk[i + 65] = esk[i + 1];
dsk[i + 64] = dsk[i ];
dsk[i + 65] = dsk[i + 1];
}
}
/*
* Triple-DES key schedule (112-bit, encryption)
*/
int mbedtls_des3_sw_set2key_enc( mbedtls_des3_sw_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
{
uint32_t sk[96];
des3_set2key( ctx->sk, sk, key );
mbedtls_zeroize( sk, sizeof( sk ) );
return( 0 );
}
/*
* Triple-DES key schedule (112-bit, decryption)
*/
int mbedtls_des3_sw_set2key_dec( mbedtls_des3_sw_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
{
uint32_t sk[96];
des3_set2key( sk, ctx->sk, key );
mbedtls_zeroize( sk, sizeof( sk ) );
return( 0 );
}
static void des3_set3key( uint32_t esk[96],
uint32_t dsk[96],
const unsigned char key[24] )
{
int i;
mbedtls_des_setkey( esk, key );
mbedtls_des_setkey( dsk + 32, key + 8 );
mbedtls_des_setkey( esk + 64, key + 16 );
for( i = 0; i < 32; i += 2 )
{
dsk[i ] = esk[94 - i];
dsk[i + 1] = esk[95 - i];
esk[i + 32] = dsk[62 - i];
esk[i + 33] = dsk[63 - i];
dsk[i + 64] = esk[30 - i];
dsk[i + 65] = esk[31 - i];
}
}
/*
* Triple-DES key schedule (168-bit, encryption)
*/
int mbedtls_des3_sw_set3key_enc( mbedtls_des3_sw_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
{
uint32_t sk[96];
des3_set3key( ctx->sk, sk, key );
mbedtls_zeroize( sk, sizeof( sk ) );
return( 0 );
}
/*
* Triple-DES key schedule (168-bit, decryption)
*/
int mbedtls_des3_sw_set3key_dec( mbedtls_des3_sw_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
{
uint32_t sk[96];
des3_set3key( sk, ctx->sk, key );
mbedtls_zeroize( sk, sizeof( sk ) );
return( 0 );
}
/*
* DES-ECB block encryption/decryption
*/
int mbedtls_des_sw_crypt_ecb( mbedtls_des_sw_context *ctx,
const unsigned char input[8],
unsigned char output[8] )
{
int i;
uint32_t X, Y, T, *SK;
SK = ctx->sk;
GET_UINT32_BE( X, input, 0 );
GET_UINT32_BE( Y, input, 4 );
DES_IP( X, Y );
for( i = 0; i < 8; i++ )
{
DES_ROUND( Y, X );
DES_ROUND( X, Y );
}
DES_FP( Y, X );
PUT_UINT32_BE( Y, output, 0 );
PUT_UINT32_BE( X, output, 4 );
return( 0 );
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/*
* DES-CBC buffer encryption/decryption
*/
int mbedtls_des_sw_crypt_cbc( mbedtls_des_sw_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output )
{
int i;
unsigned char temp[8];
if( length % 8 )
return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
if( mode == MBEDTLS_DES_ENCRYPT )
{
while( length > 0 )
{
for( i = 0; i < 8; i++ )
output[i] = (unsigned char)( input[i] ^ iv[i] );
mbedtls_des_sw_crypt_ecb( ctx, output, output );
memcpy( iv, output, 8 );
input += 8;
output += 8;
length -= 8;
}
}
else /* MBEDTLS_DES_DECRYPT */
{
while( length > 0 )
{
memcpy( temp, input, 8 );
mbedtls_des_sw_crypt_ecb( ctx, input, output );
for( i = 0; i < 8; i++ )
output[i] = (unsigned char)( output[i] ^ iv[i] );
memcpy( iv, temp, 8 );
input += 8;
output += 8;
length -= 8;
}
}
return( 0 );
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
/*
* 3DES-ECB block encryption/decryption
*/
int mbedtls_des3_sw_crypt_ecb( mbedtls_des3_sw_context *ctx,
const unsigned char input[8],
unsigned char output[8] )
{
int i;
uint32_t X, Y, T, *SK;
SK = ctx->sk;
GET_UINT32_BE( X, input, 0 );
GET_UINT32_BE( Y, input, 4 );
DES_IP( X, Y );
for( i = 0; i < 8; i++ )
{
DES_ROUND( Y, X );
DES_ROUND( X, Y );
}
for( i = 0; i < 8; i++ )
{
DES_ROUND( X, Y );
DES_ROUND( Y, X );
}
for( i = 0; i < 8; i++ )
{
DES_ROUND( Y, X );
DES_ROUND( X, Y );
}
DES_FP( Y, X );
PUT_UINT32_BE( Y, output, 0 );
PUT_UINT32_BE( X, output, 4 );
return( 0 );
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/*
* 3DES-CBC buffer encryption/decryption
*/
int mbedtls_des3_sw_crypt_cbc( mbedtls_des3_sw_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output )
{
int i;
unsigned char temp[8];
if( length % 8 )
return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
if( mode == MBEDTLS_DES_ENCRYPT )
{
while( length > 0 )
{
for( i = 0; i < 8; i++ )
output[i] = (unsigned char)( input[i] ^ iv[i] );
mbedtls_des3_sw_crypt_ecb( ctx, output, output );
memcpy( iv, output, 8 );
input += 8;
output += 8;
length -= 8;
}
}
else /* MBEDTLS_DES_DECRYPT */
{
while( length > 0 )
{
memcpy( temp, input, 8 );
mbedtls_des3_sw_crypt_ecb( ctx, input, output );
for( i = 0; i < 8; i++ )
output[i] = (unsigned char)( output[i] ^ iv[i] );
memcpy( iv, temp, 8 );
input += 8;
output += 8;
length -= 8;
}
}
return( 0 );
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#endif /* MBEDTLS_DES_ALT */
#endif /* MBEDTLS_DES_C */

View File

@ -0,0 +1,283 @@
/**
* \file des.h
*
* \brief DES block cipher
*
* Copyright (C) 2006-2015, 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 part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_DES_ALT_SW_H
#define MBEDTLS_DES_ALT_SW_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_DES_C)
#if defined(MBEDTLS_DES_ALT)
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief DES context structure
*/
typedef struct
{
uint32_t sk[32]; /*!< DES subkeys */
}
mbedtls_des_sw_context;
/**
* \brief Triple-DES context structure
*/
typedef struct
{
uint32_t sk[96]; /*!< 3DES subkeys */
}
mbedtls_des3_sw_context;
/**
* \brief Initialize DES context
*
* \param ctx DES context to be initialized
*/
void mbedtls_des_sw_init( mbedtls_des_sw_context *ctx );
/**
* \brief Clear DES context
*
* \param ctx DES context to be cleared
*/
void mbedtls_des_sw_free( mbedtls_des_sw_context *ctx );
/**
* \brief Initialize Triple-DES context
*
* \param ctx DES3 context to be initialized
*/
void mbedtls_des3_sw_init( mbedtls_des3_sw_context *ctx );
/**
* \brief Clear Triple-DES context
*
* \param ctx DES3 context to be cleared
*/
void mbedtls_des3_sw_free( mbedtls_des3_sw_context *ctx );
/**
* \brief Set key parity on the given key to odd.
*
* DES keys are 56 bits long, but each byte is padded with
* a parity bit to allow verification.
*
* \param key 8-byte secret key
*/
void mbedtls_des_sw_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Check that key parity on the given key is odd.
*
* DES keys are 56 bits long, but each byte is padded with
* a parity bit to allow verification.
*
* \param key 8-byte secret key
*
* \return 0 is parity was ok, 1 if parity was not correct.
*/
int mbedtls_des_sw_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Check that key is not a weak or semi-weak DES key
*
* \param key 8-byte secret key
*
* \return 0 if no weak key was found, 1 if a weak key was identified.
*/
int mbedtls_des_sw_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief DES key schedule (56-bit, encryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*
* \return 0
*/
int mbedtls_des_sw_setkey_enc( mbedtls_des_sw_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief DES key schedule (56-bit, decryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*
* \return 0
*/
int mbedtls_des_sw_setkey_dec( mbedtls_des_sw_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Triple-DES key schedule (112-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*
* \return 0
*/
int mbedtls_des3_sw_set2key_enc( mbedtls_des3_sw_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
/**
* \brief Triple-DES key schedule (112-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*
* \return 0
*/
int mbedtls_des3_sw_set2key_dec( mbedtls_des3_sw_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
/**
* \brief Triple-DES key schedule (168-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*
* \return 0
*/
int mbedtls_des3_sw_set3key_enc( mbedtls_des3_sw_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
/**
* \brief Triple-DES key schedule (168-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*
* \return 0
*/
int mbedtls_des3_sw_set3key_dec( mbedtls_des3_sw_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
/**
* \brief DES-ECB block encryption/decryption
*
* \param ctx DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*/
int mbedtls_des_sw_crypt_ecb( mbedtls_des_sw_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief DES-CBC buffer encryption/decryption
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx DES context
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*/
int mbedtls_des_sw_crypt_cbc( mbedtls_des_sw_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
/**
* \brief 3DES-ECB block encryption/decryption
*
* \param ctx 3DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*/
int mbedtls_des3_sw_crypt_ecb( mbedtls_des3_sw_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief 3DES-CBC buffer encryption/decryption
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx 3DES context
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
*/
int mbedtls_des3_sw_crypt_cbc( mbedtls_des3_sw_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
/**
* \brief Internal function for key expansion.
* (Only exposed to allow overriding it,
* see MBEDTLS_DES_SETKEY_ALT)
*
* \param SK Round keys
* \param key Base key
*/
void mbedtls_des_sw_setkey( uint32_t SK[32],
const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_DES_ALT */
#endif /* MBEDTLS_DES_C */
#endif /* des.h */

View File

@ -0,0 +1,138 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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.
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA1_C)
#if defined(MBEDTLS_SHA1_ALT)
#include "sha1_alt.h"
#include "crypto-misc.h"
#include "nu_bitutil.h"
#include "string.h"
void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
{
if (crypto_sha_acquire()) {
ctx->ishw = 1;
mbedtls_sha1_hw_init(&ctx->hw_ctx);
}
else {
ctx->ishw = 0;
mbedtls_sha1_sw_init(&ctx->sw_ctx);
}
}
void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
{
if (ctx == NULL) {
return;
}
if (ctx->ishw) {
mbedtls_sha1_hw_free(&ctx->hw_ctx);
crypto_sha_release();
}
else {
mbedtls_sha1_sw_free(&ctx->sw_ctx);
}
}
void mbedtls_sha1_clone(mbedtls_sha1_context *dst,
const mbedtls_sha1_context *src)
{
if (src->ishw) {
// Clone S/W ctx from H/W ctx
dst->ishw = 0;
dst->sw_ctx.total[0] = src->hw_ctx.total;
dst->sw_ctx.total[1] = 0;
{
unsigned char output[20];
crypto_sha_getinternstate(output, sizeof (output));
unsigned char *output_pos = output;
unsigned char *output_end = output + (sizeof (output) / sizeof (output[0]));
uint32_t *state_pos = (uint32_t *) &(dst->sw_ctx.state[0]);
while (output_pos != output_end) {
*state_pos ++ = nu_get32_be(output_pos);
output_pos += 4;
}
}
memcpy(dst->sw_ctx.buffer, src->hw_ctx.buffer, src->hw_ctx.buffer_left);
if (src->hw_ctx.buffer_left == src->hw_ctx.blocksize) {
mbedtls_sha1_sw_process(&dst->sw_ctx, dst->sw_ctx.buffer);
}
}
else {
// Clone S/W ctx from S/W ctx
dst->sw_ctx = src->sw_ctx;
}
}
/*
* SHA-1 context setup
*/
void mbedtls_sha1_starts(mbedtls_sha1_context *ctx)
{
if (ctx->ishw) {
mbedtls_sha1_hw_starts(&ctx->hw_ctx);
}
else {
mbedtls_sha1_sw_starts(&ctx->sw_ctx);
}
}
/*
* SHA-1 process buffer
*/
void mbedtls_sha1_update(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
{
if (ctx->ishw) {
mbedtls_sha1_hw_update(&ctx->hw_ctx, input, ilen);
}
else {
mbedtls_sha1_sw_update(&ctx->sw_ctx, input, ilen);
}
}
/*
* SHA-1 final digest
*/
void mbedtls_sha1_finish(mbedtls_sha1_context *ctx, unsigned char output[20])
{
if (ctx->ishw) {
mbedtls_sha1_hw_finish(&ctx->hw_ctx, output);
}
else {
mbedtls_sha1_sw_finish(&ctx->sw_ctx, output);
}
}
void mbedtls_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
{
if (ctx->ishw) {
mbedtls_sha1_hw_process(&ctx->hw_ctx, data);
}
else {
mbedtls_sha1_sw_process(&ctx->sw_ctx, data);
}
}
#endif /* MBEDTLS_SHA1_ALT */
#endif /* MBEDTLS_SHA1_C */

View File

@ -0,0 +1,105 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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 MBEDTLS_SHA1_ALT_H
#define MBEDTLS_SHA1_ALT_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA1_C)
#if defined(MBEDTLS_SHA1_ALT)
#include "sha_alt_hw.h"
#include "sha1_alt_sw.h"
#ifdef __cplusplus
extern "C" {
#endif
struct mbedtls_sha1_context_s;
/**
* \brief SHA-1 context structure
*/
typedef struct mbedtls_sha1_context_s
{
int ishw;
crypto_sha_context hw_ctx;
mbedtls_sha1_sw_context sw_ctx;
}
mbedtls_sha1_context;
/**
* \brief Initialize SHA-1 context
*
* \param ctx SHA-1 context to be initialized
*/
void mbedtls_sha1_init( mbedtls_sha1_context *ctx );
/**
* \brief Clear SHA-1 context
*
* \param ctx SHA-1 context to be cleared
*/
void mbedtls_sha1_free( mbedtls_sha1_context *ctx );
/**
* \brief Clone (the state of) a SHA-1 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
const mbedtls_sha1_context *src );
/**
* \brief SHA-1 context setup
*
* \param ctx context to be initialized
*/
void mbedtls_sha1_starts( mbedtls_sha1_context *ctx );
/**
* \brief SHA-1 process buffer
*
* \param ctx SHA-1 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief SHA-1 final digest
*
* \param ctx SHA-1 context
* \param output SHA-1 checksum result
*/
void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] );
/* Internal use */
void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_SHA1_ALT */
#endif /* MBEDTLS_SHA1_C */
#endif /* sha1_alt.h */

View File

@ -24,9 +24,6 @@
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
*/
/* Compatible with mbed OS 2 which doesn't support mbedtls */
#if MBED_CONF_RTOS_PRESENT
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
@ -346,5 +343,3 @@ void mbedtls_sha1_sw_finish( mbedtls_sha1_sw_context *ctx, unsigned char output[
#endif /* MBEDTLS_SHA1_ALT */
#endif /* MBEDTLS_SHA1_C */
#endif /* MBED_CONF_RTOS_PRESENT */

View File

@ -0,0 +1,110 @@
/**
* \file sha1.h
*
* \brief SHA-1 cryptographic hash function
*
* Copyright (C) 2006-2015, 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 part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_SHA1_ALT_SW_H
#define MBEDTLS_SHA1_ALT_SW_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA1_C)
#if defined(MBEDTLS_SHA1_ALT)
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA-1 context structure
*/
typedef struct
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
}
mbedtls_sha1_sw_context;
/**
* \brief Initialize SHA-1 context
*
* \param ctx SHA-1 context to be initialized
*/
void mbedtls_sha1_sw_init( mbedtls_sha1_sw_context *ctx );
/**
* \brief Clear SHA-1 context
*
* \param ctx SHA-1 context to be cleared
*/
void mbedtls_sha1_sw_free( mbedtls_sha1_sw_context *ctx );
/**
* \brief Clone (the state of) a SHA-1 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_sha1_sw_clone( mbedtls_sha1_sw_context *dst,
const mbedtls_sha1_sw_context *src );
/**
* \brief SHA-1 context setup
*
* \param ctx context to be initialized
*/
void mbedtls_sha1_sw_starts( mbedtls_sha1_sw_context *ctx );
/**
* \brief SHA-1 process buffer
*
* \param ctx SHA-1 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_sha1_sw_update( mbedtls_sha1_sw_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief SHA-1 final digest
*
* \param ctx SHA-1 context
* \param output SHA-1 checksum result
*/
void mbedtls_sha1_sw_finish( mbedtls_sha1_sw_context *ctx, unsigned char output[20] );
/* Internal use */
void mbedtls_sha1_sw_process( mbedtls_sha1_sw_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_SHA1_ALT */
#endif /* MBEDTLS_SHA1_C */
#endif /* sha1_alt_sw.h */

View File

@ -14,9 +14,6 @@
* limitations under the License.
*/
/* Compatible with mbed OS 2 which doesn't support mbedtls */
#if MBED_CONF_RTOS_PRESENT
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
@ -140,5 +137,3 @@ void mbedtls_sha256_process(mbedtls_sha256_context *ctx, const unsigned char dat
#endif /* MBEDTLS_SHA256_ALT */
#endif /* MBEDTLS_SHA256_C */
#endif /* MBED_CONF_RTOS_PRESENT */

View File

@ -0,0 +1,107 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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 MBEDTLS_SHA256_ALT_H
#define MBEDTLS_SHA256_ALT_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA256_C)
#if defined(MBEDTLS_SHA256_ALT)
#include "sha_alt_hw.h"
#include "sha256_alt_sw.h"
#ifdef __cplusplus
extern "C" {
#endif
struct mbedtls_sha256_context_s;
/**
* \brief SHA-256 context structure
*/
typedef struct mbedtls_sha256_context_s
{
int ishw;
crypto_sha_context hw_ctx;
mbedtls_sha256_sw_context sw_ctx;
}
mbedtls_sha256_context;
/**
* \brief Initialize SHA-256 context
*
* \param ctx SHA-256 context to be initialized
*/
void mbedtls_sha256_init( mbedtls_sha256_context *ctx );
/**
* \brief Clear SHA-256 context
*
* \param ctx SHA-256 context to be cleared
*/
void mbedtls_sha256_free( mbedtls_sha256_context *ctx );
/**
* \brief Clone (the state of) a SHA-256 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
const mbedtls_sha256_context *src );
/**
* \brief SHA-256 context setup
*
* \param ctx context to be initialized
* \param is224 0 = use SHA256, 1 = use SHA224
*/
void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 );
/**
* \brief SHA-256 process buffer
*
* \param ctx SHA-256 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
size_t ilen );
/**
* \brief SHA-256 final digest
*
* \param ctx SHA-256 context
* \param output SHA-224/256 checksum result
*/
void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] );
/* Internal use */
void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_SHA256_ALT */
#endif /* MBEDTLS_SHA256_C */
#endif /* sha256_alt.h */

View File

@ -24,9 +24,6 @@
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
/* Compatible with mbed OS 2 which doesn't support mbedtls */
#if MBED_CONF_RTOS_PRESENT
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
@ -320,5 +317,3 @@ void mbedtls_sha256_sw_finish( mbedtls_sha256_sw_context *ctx, unsigned char out
#endif /* MBEDTLS_SHA256_ALT */
#endif /* MBEDTLS_SHA256_C */
#endif /* MBED_CONF_RTOS_PRESENT */

View File

@ -0,0 +1,113 @@
/**
* \file sha256.h
*
* \brief SHA-224 and SHA-256 cryptographic hash function
*
* Copyright (C) 2006-2015, 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 part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_SHA256_ALT_SW_H
#define MBEDTLS_SHA256_ALT_SW_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_SHA256_C)
#if defined(MBEDTLS_SHA256_ALT)
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA-256 context structure
*/
typedef struct
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[8]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
int is224; /*!< 0 => SHA-256, else SHA-224 */
}
mbedtls_sha256_sw_context;
/**
* \brief Initialize SHA-256 context
*
* \param ctx SHA-256 context to be initialized
*/
void mbedtls_sha256_sw_init( mbedtls_sha256_sw_context *ctx );
/**
* \brief Clear SHA-256 context
*
* \param ctx SHA-256 context to be cleared
*/
void mbedtls_sha256_sw_free( mbedtls_sha256_sw_context *ctx );
/**
* \brief Clone (the state of) a SHA-256 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_sha256_sw_clone( mbedtls_sha256_sw_context *dst,
const mbedtls_sha256_sw_context *src );
/**
* \brief SHA-256 context setup
*
* \param ctx context to be initialized
* \param is224 0 = use SHA256, 1 = use SHA224
*/
void mbedtls_sha256_sw_starts( mbedtls_sha256_sw_context *ctx, int is224 );
/**
* \brief SHA-256 process buffer
*
* \param ctx SHA-256 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_sha256_sw_update( mbedtls_sha256_sw_context *ctx, const unsigned char *input,
size_t ilen );
/**
* \brief SHA-256 final digest
*
* \param ctx SHA-256 context
* \param output SHA-224/256 checksum result
*/
void mbedtls_sha256_sw_finish( mbedtls_sha256_sw_context *ctx, unsigned char output[32] );
/* Internal use */
void mbedtls_sha256_sw_process( mbedtls_sha256_sw_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_SHA256_ALT */
#endif /* MBEDTLS_SHA256_C */
#endif /* sha256_alt_sw.h */

View File

@ -14,9 +14,6 @@
* limitations under the License.
*/
/* Compatible with mbed OS 2 which doesn't support mbedtls */
#if MBED_CONF_RTOS_PRESENT
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
@ -51,6 +48,7 @@ void crypto_sha_getinternstate(unsigned char output[], size_t olen);
#endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT || MBEDTLS_SHA512_ALT */
#if defined(MBEDTLS_SHA1_C)
#if defined(MBEDTLS_SHA1_ALT)
void mbedtls_sha1_hw_init(crypto_sha_context *ctx)
@ -123,7 +121,9 @@ void mbedtls_sha1_hw_process(crypto_sha_context *ctx, const unsigned char data[6
}
#endif /* MBEDTLS_SHA1_ALT */
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
#if defined(MBEDTLS_SHA256_ALT)
void mbedtls_sha256_hw_init(crypto_sha_context *ctx)
@ -197,7 +197,9 @@ void mbedtls_sha256_hw_process(crypto_sha_context *ctx, const unsigned char data
}
#endif /* MBEDTLS_SHA256_ALT */
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA1_C) || defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA512_C)
#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_SHA512_ALT)
void crypto_sha_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen)
@ -332,7 +334,6 @@ void crypto_sha_getinternstate(unsigned char output[], size_t olen)
}
#endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT || MBEDTLS_SHA512_ALT */
#endif /* MBEDTLS_SHA1_C || MBEDTLS_SHA256_C || MBEDTLS_SHA512_C */
#endif /* MBED_CONF_RTOS_PRESENT */
#endif /* MBEDTLS_SHA1_C || MBEDTLS_SHA256_C || MBEDTLS_SHA512_C */

View File

@ -23,6 +23,7 @@
#endif
#if defined(MBEDTLS_SHA1_C) || defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA512_C)
#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_SHA512_ALT)
#include <stddef.h>
#include <stdint.h>
@ -50,6 +51,7 @@ void crypto_sha_update(crypto_sha_context *ctx, const unsigned char *input, size
void crypto_sha_update_nobuf(crypto_sha_context *ctx, const unsigned char *input, size_t ilen, int islast);
void crypto_sha_getinternstate(unsigned char output[], size_t olen);
#if defined(MBEDTLS_SHA1_C)
#if defined(MBEDTLS_SHA1_ALT)
void mbedtls_sha1_hw_init( crypto_sha_context *ctx );
@ -62,7 +64,9 @@ void mbedtls_sha1_hw_finish( crypto_sha_context *ctx, unsigned char output[20] )
void mbedtls_sha1_hw_process( crypto_sha_context *ctx, const unsigned char data[64] );
#endif /* MBEDTLS_SHA1_ALT */
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
#if defined(MBEDTLS_SHA256_ALT)
void mbedtls_sha256_hw_init( crypto_sha_context *ctx );
@ -76,11 +80,13 @@ void mbedtls_sha256_hw_finish( crypto_sha_context *ctx, unsigned char output[32]
void mbedtls_sha256_hw_process( crypto_sha_context *ctx, const unsigned char data[64] );
#endif /* MBEDTLS_SHA256_ALT */
#endif /* MBEDTLS_SHA256_C */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_SHA1_C || MBEDTLS_SHA256_C || MBEDTLS_SHA512_C*/
#endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT || MBEDTLS_SHA512_ALT */
#endif /* MBEDTLS_SHA1_C || MBEDTLS_SHA256_C || MBEDTLS_SHA512_C */
#endif /* sha_alt.h */

View File

@ -34,6 +34,7 @@ An example of the configuration file:
| Parameter name | Value | Description |
| --------------- | ------------- | ----------- |
| heap-size | number [0-0xfffe] | Nanostack's internal heap size |
| use-malloc-for-heap | `false` or `true` | Use `malloc()` for reserving the internal heap. Default: `false` |
### Thread related configuration parameters

View File

@ -2,6 +2,7 @@
"name": "mbed-mesh-api",
"config": {
"heap-size": 32500,
"use-malloc-for-heap": false,
"6lowpan-nd-channel-mask": "(1<<12)",
"6lowpan-nd-channel-page": 0,
"6lowpan-nd-channel": 12,

View File

@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <stdlib.h>
#include "eventOS_scheduler.h"
#include "eventOS_event.h"
#include "net_interface.h"
@ -22,13 +23,18 @@
#include "platform/arm_hal_timer.h"
#include "ns_hal_init.h"
#include "include/mesh_system.h"
#include "mbed_assert.h"
// For tracing we need to define flag, have include and define group
#define HAVE_DEBUG 1
#include "ns_trace.h"
#define TRACE_GROUP "m6-mesh-system"
/* Heap for NanoStack */
#if !MBED_CONF_MBED_MESH_API_USE_MALLOC_FOR_HEAP
static uint8_t app_stack_heap[MBED_CONF_MBED_MESH_API_HEAP_SIZE + 1];
#else
static uint8_t *app_stack_heap;
#endif
static bool mesh_initialized = false;
/*
@ -55,6 +61,10 @@ static void mesh_system_heap_error_handler(heap_fail_t event)
void mesh_system_init(void)
{
if (mesh_initialized == false) {
#if MBED_CONF_MBED_MESH_API_USE_MALLOC_FOR_HEAP
app_stack_heap = malloc(MBED_CONF_MBED_MESH_API_HEAP_SIZE+1);
MBED_ASSERT(app_stack_heap);
#endif
ns_hal_init(app_stack_heap, MBED_CONF_MBED_MESH_API_HEAP_SIZE,
mesh_system_heap_error_handler, NULL);
eventOS_scheduler_mutex_wait();

View File

@ -89,7 +89,7 @@ void emac_stack_mem_set_len(emac_stack_t* stack, emac_stack_mem_t *mem, uint32_t
* Returns first memory structure from the list and move the head to point to the next node
*
* @param stack Emac stack context
* @param list Pointer to the list
* @param chain Pointer to the list
* @return First memory structure from the list
*/
emac_stack_mem_t *emac_stack_mem_chain_dequeue(emac_stack_t* stack, emac_stack_mem_chain_t **chain);

View File

@ -98,7 +98,6 @@ uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address);
/** Get page size
*
* @param obj The flash object
* @param address The page starting address
* @return The size of a page
*/
uint32_t flash_get_page_size(const flash_t *obj);

View File

@ -156,6 +156,7 @@ int i2c_byte_write(i2c_t *obj, int data);
/** Configure I2C as slave or master.
* @param obj The I2C object
* @param enable_slave Enable i2c hardware so you can receive events with ::i2c_slave_receive
* @return non-zero if a value is available
*/
void i2c_slave_mode(i2c_t *obj, int enable_slave);
@ -169,12 +170,16 @@ int i2c_slave_receive(i2c_t *obj);
/** Configure I2C as slave or master.
* @param obj The I2C object
* @param data The buffer for receiving
* @param length Number of bytes to read
* @return non-zero if a value is available
*/
int i2c_slave_read(i2c_t *obj, char *data, int length);
/** Configure I2C as slave or master.
* @param obj The I2C object
* @param data The buffer for sending
* @param length Number of bytes to write
* @return non-zero if a value is available
*/
int i2c_slave_write(i2c_t *obj, const char *data, int length);
@ -208,6 +213,7 @@ void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask);
* @param address The address to be set - 7bit or 9bit
* @param stop If true, stop will be generated after the transfer is done
* @param handler The I2C IRQ handler to be set
* @param event Event mask for the transfer. See \ref hal_I2CEvents
* @param hint DMA hint usage
*/
void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint);

4
mbed.h
View File

@ -16,13 +16,13 @@
#ifndef MBED_H
#define MBED_H
#define MBED_LIBRARY_VERSION 149
#define MBED_LIBRARY_VERSION 150
#if MBED_CONF_RTOS_PRESENT
// RTOS present, this is valid only for mbed OS 5
#define MBED_MAJOR_VERSION 5
#define MBED_MINOR_VERSION 5
#define MBED_PATCH_VERSION 5
#define MBED_PATCH_VERSION 6
#else
// mbed 2

View File

@ -23,12 +23,6 @@
#include "platform/mbed_assert.h"
#include "platform/mbed_toolchain.h"
#if !defined (__CORTEX_M0) && !defined (__CORTEX_M0PLUS)
#define EXCLUSIVE_ACCESS 1
#else
#define EXCLUSIVE_ACCESS 0
#endif
static volatile uint32_t interrupt_enable_counter = 0;
static volatile bool critical_interrupts_disabled = false;
@ -107,7 +101,7 @@ MBED_WEAK void core_util_critical_section_exit(void)
}
}
#if EXCLUSIVE_ACCESS
#if __EXCLUSIVE_ACCESS
/* Supress __ldrex and __strex deprecated warnings - "#3731-D: intrinsic is deprecated" */
#if defined (__CC_ARM)

View File

@ -228,10 +228,10 @@ extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) {
FileHandle *res = NULL;
/* FILENAME: ":0x12345678" describes a FileHandle* */
/* FILENAME: ":(pointer)" describes a FileHandle* */
if (name[0] == ':') {
void *p;
std::sscanf(name, ":%p", &p);
memcpy(&p, name + 1, sizeof(p));
res = (FileHandle*)p;
/* FILENAME: "/file_system/file_name" */
@ -682,11 +682,11 @@ extern "C" uint32_t __HeapLimit;
extern "C" int errno;
// Dynamic memory allocation related syscall.
#if defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NUMAKER_PFM_M453)
#if defined(TARGET_NUVOTON)
// Overwrite _sbrk() to support two region model (heap and stack are two distinct regions).
// __wrap__sbrk() is implemented in:
// TARGET_NUMAKER_PFM_NUC472 hal/targets/cmsis/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/TOOLCHAIN_GCC_ARM/retarget.c
// TARGET_NUMAKER_PFM_M453 hal/targets/cmsis/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/TOOLCHAIN_GCC_ARM/retarget.c
// TARGET_NUMAKER_PFM_NUC472 targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/TOOLCHAIN_GCC_ARM/nuc472_retarget.c
// TARGET_NUMAKER_PFM_M453 targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/TOOLCHAIN_GCC_ARM/m451_retarget.c
extern "C" void *__wrap__sbrk(int incr);
extern "C" caddr_t _sbrk(int incr) {
return (caddr_t) __wrap__sbrk(incr);
@ -826,8 +826,12 @@ void mbed_set_unbuffered_stream(std::FILE *_file) {
*/
std::FILE *mbed_fdopen(FileHandle *fh, const char *mode)
{
char buf[12]; /* :0x12345678 + null byte */
std::sprintf(buf, ":%p", fh);
// This is to avoid scanf(buf, ":%.4s", fh) and the bloat it brings.
char buf[1 + sizeof(fh)]; /* :(pointer) */
MBED_STATIC_ASSERT(sizeof(buf) == 5, "Pointers should be 4 bytes.");
buf[0] = ':';
memcpy(buf + 1, &fh, sizeof(fh));
std::FILE *stream = std::fopen(buf, mode);
/* newlib-nano doesn't appear to ever call _isatty itself, so
* happily fully buffers an interactive stream. Deal with that here.
@ -978,72 +982,3 @@ void operator delete[](void *ptr)
free(ptr);
}
}
#if defined(MBED_CONF_RTOS_PRESENT) && defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED
static const char* error_msg(int32_t status)
{
switch (status) {
case osError:
return "Unspecified RTOS error";
case osErrorTimeout:
return "Operation not completed within the timeout period";
case osErrorResource:
return "Resource not available";
case osErrorParameter:
return "Parameter error";
case osErrorNoMemory:
return "System is out of memory";
case osErrorISR:
return "Not allowed in ISR context";
default:
return "Unknown";
}
}
extern "C" void EvrRtxKernelError (int32_t status)
{
error("Kernel error %i: %s\r\n", status, error_msg(status));
}
extern "C" void EvrRtxThreadError (osThreadId_t thread_id, int32_t status)
{
error("Thread %p error %i: %s\r\n", thread_id, status, error_msg(status));
}
extern "C" void EvrRtxTimerError (osTimerId_t timer_id, int32_t status)
{
error("Timer %p error %i: %s\r\n", timer_id, status, error_msg(status));
}
extern "C" void EvrRtxEventFlagsError (osEventFlagsId_t ef_id, int32_t status)
{
error("Event %p error %i: %s\r\n", ef_id, status, error_msg(status));
}
extern "C" void EvrRtxMutexError (osMutexId_t mutex_id, int32_t status)
{
error("Mutex %p error %i: %s\r\n", mutex_id, status, error_msg(status));
}
extern "C" void EvrRtxSemaphoreError (osSemaphoreId_t semaphore_id, int32_t status)
{
// Ignore semaphore overflow, the count will saturate with a returned error
if (status == osRtxErrorSemaphoreCountLimit) {
return;
}
error("Semaphore %p error %i\r\n", semaphore_id, status);
}
extern "C" void EvrRtxMemoryPoolError (osMemoryPoolId_t mp_id, int32_t status)
{
error("Memory Pool %p error %i\r\n", mp_id, status);
}
extern "C" void EvrRtxMessageQueueError (osMessageQueueId_t mq_id, int32_t status)
{
error("Message Queue %p error %i\r\n", mq_id, status);
}
#endif

View File

@ -44,6 +44,7 @@ namespace rtos {
*/
template<typename T, uint32_t pool_sz>
class MemoryPool : private mbed::NonCopyable<MemoryPool<T, pool_sz> > {
MBED_STATIC_ASSERT(pool_sz > 0, "Invalid memory pool size. Must be greater than 0.");
public:
/** Create and Initialize a memory pool. */
MemoryPool() {
@ -83,7 +84,10 @@ public:
/** Free a memory block.
@param block address of the allocated memory block to be freed.
@return status code that indicates the execution status of the function.
@return osOK on successful deallocation, osErrorParameter if given memory block id
is NULL or invalid, or osErrorResource if given memory block is in an
invalid memory pool state.
*/
osStatus free(T *block) {
return osMemoryPoolFree(_id, (void*)block);
@ -92,7 +96,8 @@ public:
private:
osMemoryPoolId_t _id;
osMemoryPoolAttr_t _attr;
char _pool_mem[sizeof(T) * pool_sz];
/* osMemoryPoolNew requires that pool block size is a multiple of 4 bytes. */
char _pool_mem[((sizeof(T) + 3) & ~3) * pool_sz];
mbed_rtos_storage_mem_pool_t _obj_mem;
};

View File

@ -16,6 +16,7 @@
#include "cmsis_compiler.h"
#include "rtx_os.h"
#include "rtx_evr.h"
#include "mbed_rtx.h"
#include "mbed_error.h"
@ -66,3 +67,72 @@ __NO_RETURN uint32_t osRtxErrorNotify (uint32_t code, void *object_id)
/* That shouldn't be reached */
for (;;) {}
}
#if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED
static const char* error_msg(int32_t status)
{
switch (status) {
case osError:
return "Unspecified RTOS error";
case osErrorTimeout:
return "Operation not completed within the timeout period";
case osErrorResource:
return "Resource not available";
case osErrorParameter:
return "Parameter error";
case osErrorNoMemory:
return "System is out of memory";
case osErrorISR:
return "Not allowed in ISR context";
default:
return "Unknown";
}
}
void EvrRtxKernelError (int32_t status)
{
error("Kernel error %i: %s\r\n", status, error_msg(status));
}
void EvrRtxThreadError (osThreadId_t thread_id, int32_t status)
{
error("Thread %p error %i: %s\r\n", thread_id, status, error_msg(status));
}
void EvrRtxTimerError (osTimerId_t timer_id, int32_t status)
{
error("Timer %p error %i: %s\r\n", timer_id, status, error_msg(status));
}
void EvrRtxEventFlagsError (osEventFlagsId_t ef_id, int32_t status)
{
error("Event %p error %i: %s\r\n", ef_id, status, error_msg(status));
}
void EvrRtxMutexError (osMutexId_t mutex_id, int32_t status)
{
error("Mutex %p error %i: %s\r\n", mutex_id, status, error_msg(status));
}
void EvrRtxSemaphoreError (osSemaphoreId_t semaphore_id, int32_t status)
{
// Ignore semaphore overflow, the count will saturate with a returned error
if (status == osRtxErrorSemaphoreCountLimit) {
return;
}
error("Semaphore %p error %i\r\n", semaphore_id, status);
}
void EvrRtxMemoryPoolError (osMemoryPoolId_t mp_id, int32_t status)
{
error("Memory Pool %p error %i\r\n", mp_id, status);
}
void EvrRtxMessageQueueError (osMessageQueueId_t mq_id, int32_t status)
{
error("Message Queue %p error %i\r\n", mq_id, status);
}
#endif

View File

@ -131,13 +131,17 @@ int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
char *rx_buffer, int rx_length, char write_fill) {
int total = (tx_length > rx_length) ? tx_length : rx_length;
for (int i = 0; i < total; i++) {
char out = (i < tx_length) ? tx_buffer[i] : write_fill;
char in = spi_master_write(obj, out);
if (i < rx_length) {
rx_buffer[i] = in;
}
}
// Default write is done in each and every call, in future can create HAL API instead
DSPI_SetDummyData(spi_address[obj->spi.instance], write_fill);
DSPI_MasterTransferBlocking(spi_address[obj->spi.instance], &(dspi_transfer_t){
.txData = (uint8_t *)tx_buffer,
.rxData = (uint8_t *)rx_buffer,
.dataSize = total,
.configFlags = kDSPI_MasterCtar0 | kDSPI_MasterPcs0 | kDSPI_MasterPcsContinuous,
});
DSPI_ClearStatusFlags(spi_address[obj->spi.instance], kDSPI_RxFifoDrainRequestFlag | kDSPI_EndOfQueueFlag);
return total;
}

View File

@ -40,6 +40,8 @@ void analogout_init(dac_t *obj, PinName pin)
DAC_Init(dac_bases[obj->dac], &dac_config);
DAC_SetBufferValue(dac_bases[obj->dac], 0, 0);
DAC_Enable(dac_bases[obj->dac], true);
}
void analogout_free(dac_t *obj)

View File

@ -115,7 +115,7 @@ typedef enum {
LED1 = PD_2,
LED2 = PD_3,
LED3 = PD_7,
LED4 = D0, // No real LED. Just for passing ATS.
LED4 = LED1, // No real LED. Just for passing ATS.
LED_RED = LED2,
LED_GREEN = LED3,
LED_BLUE = LED1,

View File

@ -16,14 +16,6 @@
#include "analogin_api.h"
// NOTE: Ensurce mbed_sdk_init() will get called before C++ global object constructor.
#if defined(__CC_ARM) || defined(__GNUC__)
void mbed_sdk_init_forced(void) __attribute__((constructor(101)));
#elif defined(__ICCARM__)
// FIXME: How to achieve it in IAR?
#endif
void mbed_sdk_init(void)
{
// NOTE: Support singleton semantics to be called from other init functions
@ -75,8 +67,3 @@ void mbed_sdk_init(void)
/* Lock protected registers */
SYS_LockReg();
}
void mbed_sdk_init_forced(void)
{
mbed_sdk_init();
}

View File

@ -9,7 +9,7 @@ define symbol __ICFEDIT_intvec_start__ = MBED_APP_START;
define symbol __ICFEDIT_region_ROM_start__ = MBED_APP_START;
define symbol __ICFEDIT_region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1;
define symbol __ICFEDIT_region_IRAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_IRAM_end__ = 0x20008000;
define symbol __ICFEDIT_region_IRAM_end__ = 0x20008000 - 1;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x800;
define symbol __ICFEDIT_size_heap__ = 0x4000;

View File

@ -61,12 +61,11 @@ extern uint32_t __bss_start__;
extern uint32_t __bss_end__;
extern void uvisor_init(void);
//#if defined(TOOLCHAIN_GCC_ARM)
//extern void _start(void);
//#endif
extern void software_init_hook(void) __attribute__((weak));
extern void __libc_init_array(void);
extern int main(void);
#if defined(TOOLCHAIN_GCC_ARM)
extern void _start(void);
#else
#error("For GCC toolchain, only support GNU ARM Embedded")
#endif
#endif
/* Default empty handler */
@ -271,14 +270,15 @@ void Reset_Handler(void)
/* HXT Crystal Type Select: INV */
CLK->PWRCTL &= ~CLK_PWRCTL_HXTSELTYP_Msk;
/* Enable register write-protection function */
SYS_LockReg();
/**
* Because EBI (external SRAM) init is done in SystemInit(), SystemInit() must be called at the very start.
* NOTE 1: Unlock is required for perhaps some register access in SystemInit().
* NOTE 2: Because EBI (external SRAM) init is done in SystemInit(), SystemInit() must be called at the very start.
*/
SystemInit();
/* Enable register write-protection function */
SYS_LockReg();
#if defined(__CC_ARM)
__main();
@ -306,19 +306,8 @@ void Reset_Handler(void)
}
}
//uvisor_init();
_start();
if (software_init_hook) {
/**
* Give control to the RTOS via software_init_hook() which will also call __libc_init_array().
* Assume software_init_hook() is defined in libraries/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h.
*/
software_init_hook();
}
else {
__libc_init_array();
main();
}
#endif
/* Infinite loop */

View File

@ -52,23 +52,23 @@ static struct nu_gpio_irq_var gpio_irq_var_arr[] = {
#define NU_MAX_PORT (sizeof (gpio_irq_var_arr) / sizeof (gpio_irq_var_arr[0]))
#ifndef MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE
#define MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE 0
#ifndef MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE
#define MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE 0
#endif
#ifndef MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE_LIST
#define MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE_LIST NC
#ifndef MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE_LIST
#define MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE_LIST NC
#endif
static PinName gpio_irq_debounce_arr[] = {
MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE_LIST
MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE_LIST
};
#ifndef MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE
#define MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE GPIO_DBCTL_DBCLKSRC_LIRC
#ifndef MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE
#define MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE GPIO_DBCTL_DBCLKSRC_LIRC
#endif
#ifndef MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE
#define MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE GPIO_DBCTL_DBCLKSEL_16
#ifndef MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE
#define MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE GPIO_DBCTL_DBCLKSEL_16
#endif
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
@ -88,15 +88,16 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
obj->irq_id = id;
GPIO_T *gpio_base = NU_PORT_BASE(port_index);
// NOTE: In InterruptIn constructor, gpio_irq_init() is called with gpio_init_in() which is responsible for multi-function pin setting.
//gpio_set(pin);
{
#if MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE
#if MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_ENABLE
// Suppress compiler warning
(void) gpio_irq_debounce_arr;
// Configure de-bounce clock source and sampling cycle time
GPIO_SET_DEBOUNCE_TIME(MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE);
GPIO_SET_DEBOUNCE_TIME(MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE);
GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index);
#else
// Enable de-bounce if the pin is in the de-bounce enable list
@ -113,7 +114,7 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
if (pin_index == pin_index_debunce &&
port_index == port_index_debounce) {
// Configure de-bounce clock source and sampling cycle time
GPIO_SET_DEBOUNCE_TIME(MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE);
GPIO_SET_DEBOUNCE_TIME(MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_TARGET_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE);
GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index);
break;
}

View File

@ -138,7 +138,7 @@ timestamp_t lp_ticker_read()
while (minor_clks == 0 || minor_clks == TMR2_CLK_PER_TMR2_INT);
// Add power-down compensation
return ((uint64_t) major_minor_clks * US_PER_SEC / TMR3_CLK_PER_SEC / US_PER_TICK);
return ((uint64_t) major_minor_clks * US_PER_SEC / TMR2_CLK_PER_SEC / US_PER_TICK);
}
while (0);
}

View File

@ -1,22 +0,0 @@
{
"name": "M451",
"config": {
"gpio-irq-debounce-enable": {
"help": "Enable GPIO IRQ debounce",
"value": 0
},
"gpio-irq-debounce-enable-list": {
"help": "Comma separated pin list to enable GPIO IRQ debounce",
"value": "NC"
},
"gpio-irq-debounce-clock-source": {
"help": "Select GPIO IRQ debounce clock source: GPIO_DBCTL_DBCLKSRC_HCLK or GPIO_DBCTL_DBCLKSRC_LIRC",
"value": "GPIO_DBCTL_DBCLKSRC_LIRC"
},
"gpio-irq-debounce-sample-rate": {
"help": "Select GPIO IRQ debounce sample rate: GPIO_DBCTL_DBCLKSEL_1, GPIO_DBCTL_DBCLKSEL_2, GPIO_DBCTL_DBCLKSEL_4, ..., or GPIO_DBCTL_DBCLKSEL_32768",
"value": "GPIO_DBCTL_DBCLKSEL_16"
}
}
}

View File

@ -26,31 +26,33 @@
#define YEAR0 1900
//#define EPOCH_YR 1970
static int rtc_inited = 0;
static const struct nu_modinit_s rtc_modinit = {RTC_0, RTC_MODULE, 0, 0, 0, RTC_IRQn, NULL};
void rtc_init(void)
{
if (rtc_inited) {
if (rtc_isenabled()) {
return;
}
rtc_inited = 1;
// Enable IP clock
CLK_EnableModuleClock(rtc_modinit.clkidx);
RTC_Open(NULL);
}
void rtc_free(void)
{
// FIXME
// N/A
}
int rtc_isenabled(void)
{
return rtc_inited;
// NOTE: To access (RTC) registers, clock must be enabled first.
if (! (CLK->APBCLK0 & CLK_APBCLK0_RTCCKEN_Msk)) {
// Enable IP clock
CLK_EnableModuleClock(rtc_modinit.clkidx);
}
// NOTE: Check RTC Init Active flag to support crossing reset cycle.
return !! (RTC->INIT & RTC_INIT_ACTIVE_Msk);
}
/*
@ -68,7 +70,9 @@ int rtc_isenabled(void)
time_t rtc_read(void)
{
if (! rtc_inited) {
// NOTE: After boot, RTC time registers are not synced immediately, about 1 sec latency.
// RTC time got (through RTC_GetDateAndTime()) in this sec would be last-synced and incorrect.
if (! rtc_isenabled()) {
rtc_init();
}
@ -94,7 +98,7 @@ time_t rtc_read(void)
void rtc_write(time_t t)
{
if (! rtc_inited) {
if (! rtc_isenabled()) {
rtc_init();
}

View File

@ -269,7 +269,11 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
// Flush Tx FIFO. Otherwise, output data may get lost on this change.
while (! UART_IS_TX_EMPTY(((UART_T *) NU_MODBASE(obj->serial.uart))));
// TODO: Assert for not supported parity and data bits
// Sanity check arguments
MBED_ASSERT((data_bits == 5) || (data_bits == 6) || (data_bits == 7) || (data_bits == 8));
MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) || (parity == ParityForced1) || (parity == ParityForced0));
MBED_ASSERT((stop_bits == 1) || (stop_bits == 2));
obj->serial.databits = data_bits;
obj->serial.parity = parity;
obj->serial.stopbits = stop_bits;

View File

@ -573,7 +573,7 @@ static uint32_t spi_event_check(spi_t *obj)
// Receive Time-Out
if (spi_base->STATUS & SPI_STATUS_RXTOIF_Msk) {
spi_base->STATUS = SPI_STATUS_RXTOIF_Msk;
//event |= SPI_EVENT_ERROR;
// Not using this IF. Just clear it.
}
// Transmit FIFO Under-Run
if (spi_base->STATUS & SPI_STATUS_TXUFIF_Msk) {

View File

@ -0,0 +1,140 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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
// NOTE: Check all module base addresses (XXX_BASE in BSP) for free bit fields to define module name
// which encodes module base address and module index/subindex.
#define NU_MODSUBINDEX_Pos 0
#define NU_MODSUBINDEX_Msk (0x1Ful << NU_MODSUBINDEX_Pos)
#define NU_MODINDEX_Pos 20
#define NU_MODINDEX_Msk (0xFul << NU_MODINDEX_Pos)
#define NU_MODNAME(MODBASE, INDEX, SUBINDEX) ((MODBASE) | ((INDEX) << NU_MODINDEX_Pos) | ((SUBINDEX) << NU_MODSUBINDEX_Pos))
#define NU_MODBASE(MODNAME) ((MODNAME) & ~(NU_MODINDEX_Msk | NU_MODSUBINDEX_Msk))
#define NU_MODINDEX(MODNAME) (((MODNAME) & NU_MODINDEX_Msk) >> NU_MODINDEX_Pos)
#define NU_MODSUBINDEX(MODNAME) (((MODNAME) & NU_MODSUBINDEX_Msk) >> NU_MODSUBINDEX_Pos)
#if 0
typedef enum {
GPIO_A = (int) NU_MODNAME(GPIOA_BASE, 0, 0),
GPIO_B = (int) NU_MODNAME(GPIOB_BASE, 1, 0),
GPIO_C = (int) NU_MODNAME(GPIOC_BASE, 2, 0),
GPIO_D = (int) NU_MODNAME(GPIOD_BASE, 3, 0),
GPIO_E = (int) NU_MODNAME(GPIOE_BASE, 4, 0),
GPIO_F = (int) NU_MODNAME(GPIOF_BASE, 5, 0),
GPIO_G = (int) NU_MODNAME(GPIOG_BASE, 6, 0),
GPIO_H = (int) NU_MODNAME(GPIOH_BASE, 7, 0)
} GPIOName;
#endif
typedef enum {
ADC_0_0 = (int) NU_MODNAME(EADC_BASE, 0, 0),
ADC_0_1 = (int) NU_MODNAME(EADC_BASE, 0, 1),
ADC_0_2 = (int) NU_MODNAME(EADC_BASE, 0, 2),
ADC_0_3 = (int) NU_MODNAME(EADC_BASE, 0, 3),
ADC_0_4 = (int) NU_MODNAME(EADC_BASE, 0, 4),
ADC_0_5 = (int) NU_MODNAME(EADC_BASE, 0, 5),
ADC_0_6 = (int) NU_MODNAME(EADC_BASE, 0, 6),
ADC_0_7 = (int) NU_MODNAME(EADC_BASE, 0, 7),
ADC_0_8 = (int) NU_MODNAME(EADC_BASE, 0, 8),
ADC_0_9 = (int) NU_MODNAME(EADC_BASE, 0, 9),
ADC_0_10 = (int) NU_MODNAME(EADC_BASE, 0, 10),
ADC_0_11 = (int) NU_MODNAME(EADC_BASE, 0, 11),
ADC_0_12 = (int) NU_MODNAME(EADC_BASE, 0, 12),
ADC_0_13 = (int) NU_MODNAME(EADC_BASE, 0, 13),
ADC_0_14 = (int) NU_MODNAME(EADC_BASE, 0, 14),
ADC_0_15 = (int) NU_MODNAME(EADC_BASE, 0, 15)
} ADCName;
typedef enum {
UART_0 = (int) NU_MODNAME(UART0_BASE, 0, 0),
UART_1 = (int) NU_MODNAME(UART1_BASE, 1, 0),
UART_2 = (int) NU_MODNAME(UART2_BASE, 2, 0),
UART_3 = (int) NU_MODNAME(UART3_BASE, 3, 0),
UART_4 = (int) NU_MODNAME(UART4_BASE, 4, 0),
UART_5 = (int) NU_MODNAME(UART5_BASE, 5, 0),
// NOTE: board-specific
STDIO_UART = UART_0
} UARTName;
typedef enum {
SPI_0 = (int) NU_MODNAME(SPI0_BASE, 0, 0),
SPI_1 = (int) NU_MODNAME(SPI1_BASE, 1, 0),
SPI_2 = (int) NU_MODNAME(SPI2_BASE, 2, 0),
SPI_3 = (int) NU_MODNAME(SPI3_BASE, 3, 0),
SPI_4 = (int) NU_MODNAME(SPI4_BASE, 4, 0)
} SPIName;
typedef enum {
I2C_0 = (int) NU_MODNAME(I2C0_BASE, 0, 0),
I2C_1 = (int) NU_MODNAME(I2C1_BASE, 1, 0),
I2C_2 = (int) NU_MODNAME(I2C2_BASE, 2, 0)
} I2CName;
typedef enum {
PWM_0_0 = (int) NU_MODNAME(EPWM0_BASE, 0, 0),
PWM_0_1 = (int) NU_MODNAME(EPWM0_BASE, 0, 1),
PWM_0_2 = (int) NU_MODNAME(EPWM0_BASE, 0, 2),
PWM_0_3 = (int) NU_MODNAME(EPWM0_BASE, 0, 3),
PWM_0_4 = (int) NU_MODNAME(EPWM0_BASE, 0, 4),
PWM_0_5 = (int) NU_MODNAME(EPWM0_BASE, 0, 5),
PWM_1_0 = (int) NU_MODNAME(EPWM1_BASE, 1, 0),
PWM_1_1 = (int) NU_MODNAME(EPWM1_BASE, 1, 1),
PWM_1_2 = (int) NU_MODNAME(EPWM1_BASE, 1, 2),
PWM_1_3 = (int) NU_MODNAME(EPWM1_BASE, 1, 3),
PWM_1_4 = (int) NU_MODNAME(EPWM1_BASE, 1, 4),
PWM_1_5 = (int) NU_MODNAME(EPWM1_BASE, 1, 5)
} PWMName;
typedef enum {
TIMER_0 = (int) NU_MODNAME(TIMER0_BASE, 0, 0),
TIMER_1 = (int) NU_MODNAME(TIMER1_BASE, 1, 0),
TIMER_2 = (int) NU_MODNAME(TIMER2_BASE, 2, 0),
TIMER_3 = (int) NU_MODNAME(TIMER3_BASE, 3, 0),
} TIMERName;
typedef enum {
RTC_0 = (int) NU_MODNAME(RTC_BASE, 0, 0)
} RTCName;
typedef enum {
DMA_0 = (int) NU_MODNAME(PDMA_BASE, 0, 0)
} DMAName;
typedef enum {
SD_0 = (int) NU_MODNAME(SDH0_BASE, 0, 0),
SD_1 = (int) NU_MODNAME(SDH1_BASE, 1, 0)
} SDName;
typedef enum {
CAN_0 = (int) NU_MODNAME(CAN0_BASE, 0, 0),
CAN_1 = (int) NU_MODNAME(CAN1_BASE, 1, 0)
} CANName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,586 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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 "PeripheralPins.h"
//*** ADC ***
const PinMap PinMap_ADC[] = {
{PB_0, ADC_0_0, SYS_GPB_MFPL_PB0MFP_EADC0_CH0},
{PB_1, ADC_0_1, SYS_GPB_MFPL_PB1MFP_EADC0_CH1},
{PB_2, ADC_0_2, SYS_GPB_MFPL_PB2MFP_EADC0_CH2},
{PB_3, ADC_0_3, SYS_GPB_MFPL_PB3MFP_EADC0_CH3},
{PB_4, ADC_0_4, SYS_GPB_MFPL_PB4MFP_EADC0_CH4},
{PB_5, ADC_0_5, SYS_GPB_MFPL_PB5MFP_EADC0_CH5},
{PB_6, ADC_0_6, SYS_GPB_MFPL_PB6MFP_EADC0_CH6},
{PB_7, ADC_0_7, SYS_GPB_MFPL_PB7MFP_EADC0_CH7},
{PB_8, ADC_0_8, SYS_GPB_MFPH_PB8MFP_EADC0_CH8},
{PB_9, ADC_0_9, SYS_GPB_MFPH_PB9MFP_EADC0_CH9},
{PB_10, ADC_0_10, SYS_GPB_MFPH_PB10MFP_EADC0_CH10},
{PB_11, ADC_0_11, SYS_GPB_MFPH_PB11MFP_EADC0_CH11},
{PB_12, ADC_0_12, SYS_GPB_MFPH_PB12MFP_EADC0_CH12},
{PB_13, ADC_0_13, SYS_GPB_MFPH_PB13MFP_EADC0_CH13},
{PB_14, ADC_0_14, SYS_GPB_MFPH_PB14MFP_EADC0_CH14},
{PB_15, ADC_0_15, SYS_GPB_MFPH_PB15MFP_EADC0_CH15},
{NC, NC, 0}
};
//*** I2C ***
const PinMap PinMap_I2C_SDA[] = {
{PA_0, I2C_2, SYS_GPA_MFPL_PA0MFP_I2C2_SDA},
{PA_2, I2C_1, SYS_GPA_MFPL_PA2MFP_I2C1_SDA},
{PA_4, I2C_0, SYS_GPA_MFPL_PA4MFP_I2C0_SDA},
{PA_6, I2C_1, SYS_GPA_MFPL_PA6MFP_I2C1_SDA},
{PA_10, I2C_2, SYS_GPA_MFPH_PA10MFP_I2C2_SDA},
{PA_13, I2C_1, SYS_GPA_MFPH_PA13MFP_I2C1_SDA},
{PA_15, I2C_2, SYS_GPA_MFPH_PA15MFP_I2C2_SDA},
{PB_0, I2C_1, SYS_GPB_MFPL_PB0MFP_I2C1_SDA},
{PB_4, I2C_0, SYS_GPB_MFPL_PB4MFP_I2C0_SDA},
{PB_10, I2C_1, SYS_GPB_MFPH_PB10MFP_I2C1_SDA},
{PB_12, I2C_2, SYS_GPB_MFPH_PB12MFP_I2C2_SDA},
{PC_0, I2C_0, SYS_GPC_MFPL_PC0MFP_I2C0_SDA},
{PC_4, I2C_1, SYS_GPC_MFPL_PC4MFP_I2C1_SDA},
{PC_8, I2C_0, SYS_GPC_MFPH_PC8MFP_I2C0_SDA},
{PC_11, I2C_0, SYS_GPC_MFPH_PC11MFP_I2C0_SDA},
{PD_0, I2C_2, SYS_GPD_MFPL_PD0MFP_I2C2_SDA},
{PD_4, I2C_1, SYS_GPD_MFPL_PD4MFP_I2C1_SDA},
{PD_6, I2C_0, SYS_GPD_MFPL_PD6MFP_I2C0_SDA},
{PD_8, I2C_2, SYS_GPD_MFPH_PD8MFP_I2C2_SDA},
{PE_0, I2C_1, SYS_GPE_MFPL_PE0MFP_I2C1_SDA},
{PF_1, I2C_1, SYS_GPF_MFPL_PF1MFP_I2C1_SDA},
{PF_2, I2C_0, SYS_GPF_MFPL_PF2MFP_I2C0_SDA},
{PG_1, I2C_0, SYS_GPG_MFPL_PG1MFP_I2C0_SDA},
{PG_3, I2C_1, SYS_GPG_MFPL_PG3MFP_I2C1_SDA},
{PH_3, I2C_0, SYS_GPH_MFPL_PH3MFP_I2C0_SDA},
{PH_9, I2C_2, SYS_GPH_MFPH_PH9MFP_I2C2_SDA},
{NC, NC, 0}
};
const PinMap PinMap_I2C_SCL[] = {
{PA_1, I2C_2, SYS_GPA_MFPL_PA1MFP_I2C2_SCL},
{PA_3, I2C_1, SYS_GPA_MFPL_PA3MFP_I2C1_SCL},
{PA_5, I2C_0, SYS_GPA_MFPL_PA5MFP_I2C0_SCL},
{PA_7, I2C_1, (int) SYS_GPA_MFPL_PA7MFP_I2C1_SCL},
{PA_11, I2C_2, SYS_GPA_MFPH_PA11MFP_I2C2_SCL},
{PA_12, I2C_1, SYS_GPA_MFPH_PA12MFP_I2C1_SCL},
{PA_14, I2C_2, SYS_GPA_MFPH_PA14MFP_I2C2_SCL},
{PB_1, I2C_1, SYS_GPB_MFPL_PB1MFP_I2C1_SCL},
{PB_5, I2C_0, SYS_GPB_MFPL_PB5MFP_I2C0_SCL},
{PB_11, I2C_1, SYS_GPB_MFPH_PB11MFP_I2C1_SCL},
{PB_13, I2C_2, SYS_GPB_MFPH_PB13MFP_I2C2_SCL},
{PC_1, I2C_0, SYS_GPC_MFPL_PC1MFP_I2C0_SCL},
{PC_5, I2C_1, SYS_GPC_MFPL_PC5MFP_I2C1_SCL},
{PC_12, I2C_0, SYS_GPC_MFPH_PC12MFP_I2C0_SCL},
{PD_1, I2C_2, SYS_GPD_MFPL_PD1MFP_I2C2_SCL},
{PD_5, I2C_1, SYS_GPD_MFPL_PD5MFP_I2C1_SCL},
{PD_7, I2C_0, SYS_GPD_MFPL_PD7MFP_I2C0_SCL},
{PD_9, I2C_2, SYS_GPD_MFPH_PD9MFP_I2C2_SCL},
{PE_1, I2C_1, SYS_GPE_MFPL_PE1MFP_I2C1_SCL},
{PE_13, I2C_0, SYS_GPE_MFPH_PE13MFP_I2C0_SCL},
{PF_0, I2C_1, SYS_GPF_MFPL_PF0MFP_I2C1_SCL},
{PF_3, I2C_0, SYS_GPF_MFPL_PF3MFP_I2C0_SCL},
{PG_0, I2C_0, SYS_GPG_MFPL_PG0MFP_I2C0_SCL},
{PG_2, I2C_1, SYS_GPG_MFPL_PG2MFP_I2C1_SCL},
{PH_2, I2C_0, SYS_GPH_MFPL_PH2MFP_I2C0_SCL},
{PH_8, I2C_2, SYS_GPH_MFPH_PH8MFP_I2C2_SCL},
{NC, NC, 0}
};
//*** PWM ***
const PinMap PinMap_PWM[] = {
{PA_0, PWM_0_5, SYS_GPA_MFPL_PA0MFP_EPWM0_CH5},
{PA_1, PWM_0_4, SYS_GPA_MFPL_PA1MFP_EPWM0_CH4},
{PA_2, PWM_0_3, SYS_GPA_MFPL_PA2MFP_EPWM0_CH3},
{PA_3, PWM_0_2, SYS_GPA_MFPL_PA3MFP_EPWM0_CH2},
{PA_4, PWM_0_1, SYS_GPA_MFPL_PA4MFP_EPWM0_CH1},
{PA_5, PWM_0_0, SYS_GPA_MFPL_PA5MFP_EPWM0_CH0},
{PA_6, PWM_1_5, SYS_GPA_MFPL_PA6MFP_EPWM1_CH5},
{PA_7, PWM_1_4, (int) SYS_GPA_MFPL_PA7MFP_EPWM1_CH4},
{PB_0, PWM_0_5, SYS_GPB_MFPL_PB0MFP_EPWM0_CH5},
{NU_PINNAME_BIND(PB_0, PWM_0_5), PWM_0_5, SYS_GPB_MFPL_PB0MFP_EPWM0_CH5},
{PB_0, PWM_1_5, SYS_GPB_MFPL_PB0MFP_EPWM1_CH5},
{NU_PINNAME_BIND(PB_0, PWM_1_5), PWM_1_5, SYS_GPB_MFPL_PB0MFP_EPWM1_CH5},
{PB_1, PWM_0_4, SYS_GPB_MFPL_PB1MFP_EPWM0_CH4},
{NU_PINNAME_BIND(PB_1, PWM_0_4), PWM_0_4, SYS_GPB_MFPL_PB1MFP_EPWM0_CH4},
{PB_1, PWM_1_4, SYS_GPB_MFPL_PB1MFP_EPWM1_CH4},
{NU_PINNAME_BIND(PB_1, PWM_1_4), PWM_1_4, SYS_GPB_MFPL_PB1MFP_EPWM1_CH4},
{PB_2, PWM_0_3, SYS_GPB_MFPL_PB2MFP_EPWM0_CH3},
{PB_3, PWM_0_2, SYS_GPB_MFPL_PB3MFP_EPWM0_CH2},
{PB_4, PWM_0_1, SYS_GPB_MFPL_PB4MFP_EPWM0_CH1},
{PB_5, PWM_0_0, SYS_GPB_MFPL_PB5MFP_EPWM0_CH0},
{PB_6, PWM_1_5, SYS_GPB_MFPL_PB6MFP_EPWM1_CH5},
{PB_7, PWM_1_4, (int) SYS_GPB_MFPL_PB7MFP_EPWM1_CH4},
{PB_12, PWM_1_3, SYS_GPB_MFPH_PB12MFP_EPWM1_CH3},
{PB_13, PWM_1_2, SYS_GPB_MFPH_PB13MFP_EPWM1_CH2},
{PB_14, PWM_1_1, SYS_GPB_MFPH_PB14MFP_EPWM1_CH1},
{PB_15, PWM_1_0, (int) SYS_GPB_MFPH_PB15MFP_EPWM1_CH0},
{PC_0, PWM_1_5, SYS_GPC_MFPL_PC0MFP_EPWM1_CH5},
{PC_1, PWM_1_4, SYS_GPC_MFPL_PC1MFP_EPWM1_CH4},
{PC_2, PWM_1_3, SYS_GPC_MFPL_PC2MFP_EPWM1_CH3},
{PC_3, PWM_1_2, SYS_GPC_MFPL_PC3MFP_EPWM1_CH2},
{PC_4, PWM_1_1, SYS_GPC_MFPL_PC4MFP_EPWM1_CH1},
{PC_5, PWM_1_0, SYS_GPC_MFPL_PC5MFP_EPWM1_CH0},
{PC_6, PWM_1_3, SYS_GPC_MFPL_PC6MFP_EPWM1_CH3},
{PC_7, PWM_1_2, (int) SYS_GPC_MFPL_PC7MFP_EPWM1_CH2},
{PC_8, PWM_1_1, SYS_GPC_MFPH_PC8MFP_EPWM1_CH1},
{PC_9, PWM_1_3, SYS_GPC_MFPH_PC9MFP_EPWM1_CH3},
{PC_10, PWM_1_2, SYS_GPC_MFPH_PC10MFP_EPWM1_CH2},
{PC_11, PWM_1_1, SYS_GPC_MFPH_PC11MFP_EPWM1_CH1},
{PC_12, PWM_1_0, SYS_GPC_MFPH_PC12MFP_EPWM1_CH0},
{PD_14, PWM_0_4, SYS_GPD_MFPH_PD14MFP_EPWM0_CH4},
{PE_2, PWM_0_5, SYS_GPE_MFPL_PE2MFP_EPWM0_CH5},
{PE_3, PWM_0_4, SYS_GPE_MFPL_PE3MFP_EPWM0_CH4},
{PE_4, PWM_0_3, SYS_GPE_MFPL_PE4MFP_EPWM0_CH3},
{PE_5, PWM_0_2, SYS_GPE_MFPL_PE5MFP_EPWM0_CH2},
{PE_6, PWM_0_1, SYS_GPE_MFPL_PE6MFP_EPWM0_CH1},
{PE_7, PWM_0_0, (int) SYS_GPE_MFPL_PE7MFP_EPWM0_CH0},
{PE_8, PWM_0_0, SYS_GPE_MFPH_PE8MFP_EPWM0_CH0},
{PE_9, PWM_0_1, SYS_GPE_MFPH_PE9MFP_EPWM0_CH1},
{PE_10, PWM_0_2, SYS_GPE_MFPH_PE10MFP_EPWM0_CH2},
{PE_11, PWM_0_3, SYS_GPE_MFPH_PE11MFP_EPWM0_CH3},
{PE_12, PWM_0_4, SYS_GPE_MFPH_PE12MFP_EPWM0_CH4},
{PE_13, PWM_0_5, SYS_GPE_MFPH_PE13MFP_EPWM0_CH5},
{NU_PINNAME_BIND(PE_13, PWM_0_5), PWM_0_5, SYS_GPE_MFPH_PE13MFP_EPWM0_CH5},
{PE_13, PWM_1_0, SYS_GPE_MFPH_PE13MFP_EPWM1_CH0},
{NU_PINNAME_BIND(PE_13, PWM_1_0), PWM_1_0, SYS_GPE_MFPH_PE13MFP_EPWM1_CH0},
{PG_5, PWM_0_3, SYS_GPG_MFPL_PG5MFP_EPWM0_CH3},
{PG_6, PWM_0_2, SYS_GPG_MFPL_PG6MFP_EPWM0_CH2},
{PG_7, PWM_0_1, (int) SYS_GPG_MFPL_PG7MFP_EPWM0_CH1},
{PG_8, PWM_0_0, SYS_GPG_MFPH_PG8MFP_EPWM0_CH0},
{PH_11, PWM_0_5, SYS_GPH_MFPH_PH11MFP_EPWM0_CH5},
{NC, NC, 0}
};
//*** SERIAL ***
const PinMap PinMap_UART_TX[] = {
{PA_1, UART_0, SYS_GPA_MFPL_PA1MFP_UART0_TXD},
{PA_3, UART_1, SYS_GPA_MFPL_PA3MFP_UART1_TXD},
{NU_PINNAME_BIND(PA_3, UART_1), UART_1, SYS_GPA_MFPL_PA3MFP_UART1_TXD},
{PA_3, UART_4, SYS_GPA_MFPL_PA3MFP_UART4_TXD},
{NU_PINNAME_BIND(PA_3, UART_4), UART_4, SYS_GPA_MFPL_PA3MFP_UART4_TXD},
{PA_5, UART_5, SYS_GPA_MFPL_PA5MFP_UART5_TXD},
{PA_7, UART_0, SYS_GPA_MFPL_PA7MFP_UART0_TXD},
{PA_9, UART_1, SYS_GPA_MFPH_PA9MFP_UART1_TXD},
{PA_12, UART_4, SYS_GPA_MFPH_PA12MFP_UART4_TXD},
{PA_14, UART_0, SYS_GPA_MFPH_PA14MFP_UART0_TXD},
{PB_1, UART_2, SYS_GPB_MFPL_PB1MFP_UART2_TXD},
{PB_3, UART_1, SYS_GPB_MFPL_PB3MFP_UART1_TXD},
{PB_5, UART_5, SYS_GPB_MFPL_PB5MFP_UART5_TXD},
{PB_7, UART_1, SYS_GPB_MFPL_PB7MFP_UART1_TXD},
{PB_9, UART_0, SYS_GPB_MFPH_PB9MFP_UART0_TXD},
{PB_11, UART_4, SYS_GPB_MFPH_PB11MFP_UART4_TXD},
{PB_13, UART_0, SYS_GPB_MFPH_PB13MFP_UART0_TXD},
{PB_15, UART_3, SYS_GPB_MFPH_PB15MFP_UART3_TXD},
{PC_1, UART_2, SYS_GPC_MFPL_PC1MFP_UART2_TXD},
{PC_3, UART_3, SYS_GPC_MFPL_PC3MFP_UART3_TXD},
{PC_5, UART_2, SYS_GPC_MFPL_PC5MFP_UART2_TXD},
{NU_PINNAME_BIND(PC_5, UART_2), UART_2, SYS_GPC_MFPL_PC5MFP_UART2_TXD},
{PC_5, UART_4, SYS_GPC_MFPL_PC5MFP_UART4_TXD},
{NU_PINNAME_BIND(PC_5, UART_4), UART_4, SYS_GPC_MFPL_PC5MFP_UART4_TXD},
{PC_7, UART_4, SYS_GPC_MFPL_PC7MFP_UART4_TXD},
{PC_10, UART_3, SYS_GPC_MFPH_PC10MFP_UART3_TXD},
{PC_12, UART_0, SYS_GPC_MFPH_PC12MFP_UART0_TXD},
{PC_13, UART_2, SYS_GPC_MFPH_PC13MFP_UART2_TXD},
{PD_1, UART_3, SYS_GPD_MFPL_PD1MFP_UART3_TXD},
{PD_3, UART_0, SYS_GPD_MFPL_PD3MFP_UART0_TXD},
{PD_7, UART_1, SYS_GPD_MFPL_PD7MFP_UART1_TXD},
{PD_11, UART_1, SYS_GPD_MFPH_PD11MFP_UART1_TXD},
{PE_1, UART_3, SYS_GPE_MFPL_PE1MFP_UART3_TXD},
{PE_7, UART_5, (int) SYS_GPE_MFPL_PE7MFP_UART5_TXD},
{PE_8, UART_2, SYS_GPE_MFPH_PE8MFP_UART2_TXD},
{PE_10, UART_3, SYS_GPE_MFPH_PE10MFP_UART3_TXD},
{PE_13, UART_1, SYS_GPE_MFPH_PE13MFP_UART1_TXD},
{PE_14, UART_2, SYS_GPE_MFPH_PE14MFP_UART2_TXD},
{PF_0, UART_1, SYS_GPF_MFPL_PF0MFP_UART1_TXD},
{PF_3, UART_0, SYS_GPF_MFPL_PF3MFP_UART0_TXD},
{PF_4, UART_2, SYS_GPF_MFPL_PF4MFP_UART2_TXD},
{PF_7, UART_4, SYS_GPF_MFPL_PF7MFP_UART4_TXD},
{PG_0, UART_1, SYS_GPG_MFPL_PG0MFP_UART1_TXD},
{PG_1, UART_2, SYS_GPG_MFPL_PG1MFP_UART2_TXD},
{PH_0, UART_5, SYS_GPH_MFPL_PH0MFP_UART5_TXD},
{PH_2, UART_4, SYS_GPH_MFPL_PH2MFP_UART4_TXD},
{PH_8, UART_1, SYS_GPH_MFPH_PH8MFP_UART1_TXD},
{PH_10, UART_0, SYS_GPH_MFPH_PH10MFP_UART0_TXD},
{NU_PINNAME_BIND(PH_10, UART_0), UART_0, SYS_GPH_MFPH_PH10MFP_UART0_TXD},
{PH_10, UART_4, SYS_GPH_MFPH_PH10MFP_UART4_TXD},
{NU_PINNAME_BIND(PH_10, UART_4), UART_4, SYS_GPH_MFPH_PH10MFP_UART4_TXD},
{NC, NC, 0}
};
const PinMap PinMap_UART_RX[] = {
{PA_0, UART_0, SYS_GPA_MFPL_PA0MFP_UART0_RXD},
{PA_2, UART_1, SYS_GPA_MFPL_PA2MFP_UART1_RXD},
{NU_PINNAME_BIND(PA_2, UART_1), UART_1, SYS_GPA_MFPL_PA2MFP_UART1_RXD},
{PA_2, UART_4, SYS_GPA_MFPL_PA2MFP_UART4_RXD},
{NU_PINNAME_BIND(PA_2, UART_4), UART_4, SYS_GPA_MFPL_PA2MFP_UART4_RXD},
{PA_4, UART_5, SYS_GPA_MFPL_PA4MFP_UART5_RXD},
{PA_6, UART_0, SYS_GPA_MFPL_PA6MFP_UART0_RXD},
{PA_8, UART_1, SYS_GPA_MFPH_PA8MFP_UART1_RXD},
{PA_13, UART_4, SYS_GPA_MFPH_PA13MFP_UART4_RXD},
{PA_15, UART_0, SYS_GPA_MFPH_PA15MFP_UART0_RXD},
{PB_0, UART_2, SYS_GPB_MFPL_PB0MFP_UART2_RXD},
{PB_2, UART_1, SYS_GPB_MFPL_PB2MFP_UART1_RXD},
{PB_4, UART_5, SYS_GPB_MFPL_PB4MFP_UART5_RXD},
{PB_6, UART_1, SYS_GPB_MFPL_PB6MFP_UART1_RXD},
{PB_8, UART_0, SYS_GPB_MFPH_PB8MFP_UART0_RXD},
{PB_10, UART_4, SYS_GPB_MFPH_PB10MFP_UART4_RXD},
{PB_12, UART_0, SYS_GPB_MFPH_PB12MFP_UART0_RXD},
{PB_14, UART_3, SYS_GPB_MFPH_PB14MFP_UART3_RXD},
{PC_0, UART_2, SYS_GPC_MFPL_PC0MFP_UART2_RXD},
{PC_2, UART_3, SYS_GPC_MFPL_PC2MFP_UART3_RXD},
{PC_4, UART_2, SYS_GPC_MFPL_PC4MFP_UART2_RXD},
{NU_PINNAME_BIND(PC_4, UART_2), UART_2, SYS_GPC_MFPL_PC4MFP_UART2_RXD},
{PC_4, UART_4, SYS_GPC_MFPL_PC4MFP_UART4_RXD},
{NU_PINNAME_BIND(PC_4, UART_4), UART_4, SYS_GPC_MFPL_PC4MFP_UART4_RXD},
{PC_6, UART_4, SYS_GPC_MFPL_PC6MFP_UART4_RXD},
{PC_8, UART_1, SYS_GPC_MFPH_PC8MFP_UART1_RXD},
{PC_9, UART_3, SYS_GPC_MFPH_PC9MFP_UART3_RXD},
{PC_11, UART_0, SYS_GPC_MFPH_PC11MFP_UART0_RXD},
{PD_0, UART_3, SYS_GPD_MFPL_PD0MFP_UART3_RXD},
{PD_2, UART_0, SYS_GPD_MFPL_PD2MFP_UART0_RXD},
{PD_6, UART_1, SYS_GPD_MFPL_PD6MFP_UART1_RXD},
{PD_10, UART_1, SYS_GPD_MFPH_PD10MFP_UART1_RXD},
{PD_12, UART_2, SYS_GPD_MFPH_PD12MFP_UART2_RXD},
{PE_0, UART_3, SYS_GPE_MFPL_PE0MFP_UART3_RXD},
{PE_6, UART_5, SYS_GPE_MFPL_PE6MFP_UART5_RXD},
{PE_9, UART_2, SYS_GPE_MFPH_PE9MFP_UART2_RXD},
{PE_11, UART_3, SYS_GPE_MFPH_PE11MFP_UART3_RXD},
{PE_15, UART_2, SYS_GPE_MFPH_PE15MFP_UART2_RXD},
{PF_1, UART_1, SYS_GPF_MFPL_PF1MFP_UART1_RXD},
{PF_2, UART_0, SYS_GPF_MFPL_PF2MFP_UART0_RXD},
{PF_5, UART_2, SYS_GPF_MFPL_PF5MFP_UART2_RXD},
{PF_6, UART_4, SYS_GPF_MFPL_PF6MFP_UART4_RXD},
{PG_0, UART_2, SYS_GPG_MFPL_PG0MFP_UART2_RXD},
{PG_1, UART_1, SYS_GPG_MFPL_PG1MFP_UART1_RXD},
{PH_1, UART_5, SYS_GPH_MFPL_PH1MFP_UART5_RXD},
{PH_3, UART_4, SYS_GPH_MFPL_PH3MFP_UART4_RXD},
{PH_9, UART_1, SYS_GPH_MFPH_PH9MFP_UART1_RXD},
{PH_11, UART_0, SYS_GPH_MFPH_PH11MFP_UART0_RXD},
{NU_PINNAME_BIND(PH_11, UART_0), UART_0, SYS_GPH_MFPH_PH11MFP_UART0_RXD},
{PH_11, UART_4, SYS_GPH_MFPH_PH11MFP_UART4_RXD},
{NU_PINNAME_BIND(PH_11, UART_4), UART_4, SYS_GPH_MFPH_PH11MFP_UART4_RXD},
{NC, NC, 0}
};
const PinMap PinMap_UART_RTS[] = {
{PA_0, UART_1, SYS_GPA_MFPL_PA0MFP_UART1_nRTS},
{PA_4, UART_0, SYS_GPA_MFPL_PA4MFP_UART0_nRTS},
{PB_3, UART_5, SYS_GPB_MFPL_PB3MFP_UART5_nRTS},
{PB_8, UART_1, SYS_GPB_MFPH_PB8MFP_UART1_nRTS},
{PB_10, UART_0, SYS_GPB_MFPH_PB10MFP_UART0_nRTS},
{PB_13, UART_3, SYS_GPB_MFPH_PB13MFP_UART3_nRTS},
{PB_14, UART_0, SYS_GPB_MFPH_PB14MFP_UART0_nRTS},
{PC_3, UART_2, SYS_GPC_MFPL_PC3MFP_UART2_nRTS},
{PC_6, UART_0, SYS_GPC_MFPL_PC6MFP_UART0_nRTS},
{PD_3, UART_3, SYS_GPD_MFPL_PD3MFP_UART3_nRTS},
{PD_8, UART_2, SYS_GPD_MFPH_PD8MFP_UART2_nRTS},
{PE_0, UART_4, SYS_GPE_MFPL_PE0MFP_UART4_nRTS},
{PE_12, UART_1, SYS_GPE_MFPH_PE12MFP_UART1_nRTS},
{PE_13, UART_4, SYS_GPE_MFPH_PE13MFP_UART4_nRTS},
{PF_4, UART_2, SYS_GPF_MFPL_PF4MFP_UART2_nRTS},
{PH_2, UART_5, SYS_GPH_MFPL_PH2MFP_UART5_nRTS},
{PH_8, UART_3, SYS_GPH_MFPH_PH8MFP_UART3_nRTS},
{NC, NC, 0}
};
const PinMap PinMap_UART_CTS[] = {
{PA_1, UART_1, SYS_GPA_MFPL_PA1MFP_UART1_nCTS},
{PA_5, UART_0, SYS_GPA_MFPL_PA5MFP_UART0_nCTS},
{PB_2, UART_5, SYS_GPB_MFPL_PB2MFP_UART5_nCTS},
{PB_9, UART_1, SYS_GPB_MFPH_PB9MFP_UART1_nCTS},
{PB_11, UART_0, SYS_GPB_MFPH_PB11MFP_UART0_nCTS},
{PB_12, UART_3, SYS_GPB_MFPH_PB12MFP_UART3_nCTS},
{PB_15, UART_0, SYS_GPB_MFPH_PB15MFP_UART0_nCTS},
{PC_2, UART_2, SYS_GPC_MFPL_PC2MFP_UART2_nCTS},
{PC_7, UART_0, SYS_GPC_MFPL_PC7MFP_UART0_nCTS},
{PC_8, UART_4, SYS_GPC_MFPH_PC8MFP_UART4_nCTS},
{PD_2, UART_3, SYS_GPD_MFPL_PD2MFP_UART3_nCTS},
{PD_9, UART_2, SYS_GPD_MFPH_PD9MFP_UART2_nCTS},
{PE_1, UART_4, SYS_GPE_MFPL_PE1MFP_UART4_nCTS},
{PE_11, UART_1, SYS_GPE_MFPH_PE11MFP_UART1_nCTS},
{PF_5, UART_2, SYS_GPF_MFPL_PF5MFP_UART2_nCTS},
{PH_3, UART_5, SYS_GPH_MFPL_PH3MFP_UART5_nCTS},
{PH_9, UART_3, SYS_GPH_MFPH_PH9MFP_UART3_nCTS},
{NC, NC, 0}
};
//*** SPI ***
const PinMap PinMap_SPI_MOSI[] = {
{PA_0, SPI_0, SYS_GPA_MFPL_PA0MFP_SPI0_MOSI0},
{NU_PINNAME_BIND(PA_0, SPI_0), SPI_0, SYS_GPA_MFPL_PA0MFP_SPI0_MOSI0},
{PA_0, SPI_1, SYS_GPA_MFPL_PA0MFP_SPI1_MOSI},
{NU_PINNAME_BIND(PA_0, SPI_1), SPI_1, SYS_GPA_MFPL_PA0MFP_SPI1_MOSI},
{PA_8, SPI_3, SYS_GPA_MFPH_PA8MFP_SPI3_MOSI},
{PA_15, SPI_3, SYS_GPA_MFPH_PA15MFP_SPI3_MOSI},
{PB_4, SPI_2, SYS_GPB_MFPL_PB4MFP_SPI2_MOSI},
{PB_8, SPI_4, SYS_GPB_MFPH_PB8MFP_SPI4_MOSI},
{PB_12, SPI_1, SYS_GPB_MFPH_PB12MFP_SPI1_MOSI},
{PC_0, SPI_0, SYS_GPC_MFPL_PC0MFP_SPI0_MOSI0},
{PC_2, SPI_2, SYS_GPC_MFPL_PC2MFP_SPI2_MOSI},
{PC_6, SPI_2, SYS_GPC_MFPL_PC6MFP_SPI2_MOSI},
{PC_11, SPI_4, SYS_GPC_MFPH_PC11MFP_SPI4_MOSI},
{PD_0, SPI_1, SYS_GPD_MFPL_PD0MFP_SPI1_MOSI},
{PD_6, SPI_2, SYS_GPD_MFPL_PD6MFP_SPI2_MOSI},
{PE_0, SPI_0, SYS_GPE_MFPL_PE0MFP_SPI0_MOSI0},
{NU_PINNAME_BIND(PE_0, SPI_0), SPI_0, SYS_GPE_MFPL_PE0MFP_SPI0_MOSI0},
{PE_0, SPI_2, SYS_GPE_MFPL_PE0MFP_SPI2_MOSI},
{NU_PINNAME_BIND(PE_0, SPI_2), SPI_2, SYS_GPE_MFPL_PE0MFP_SPI2_MOSI},
{PE_2, SPI_4, SYS_GPE_MFPL_PE2MFP_SPI4_MOSI},
{PE_10, SPI_3, SYS_GPE_MFPH_PE10MFP_SPI3_MOSI},
{PF_6, SPI_1, SYS_GPF_MFPL_PF6MFP_SPI1_MOSI},
{PF_11, SPI_3, SYS_GPF_MFPH_PF11MFP_SPI3_MOSI},
{PG_8, SPI_4, SYS_GPG_MFPH_PG8MFP_SPI4_MOSI},
{PH_5, SPI_2, SYS_GPH_MFPL_PH5MFP_SPI2_MOSI},
{NC, NC, 0}
};
const PinMap PinMap_SPI_MISO[] = {
{PA_1, SPI_0, SYS_GPA_MFPL_PA1MFP_SPI0_MISO0},
{NU_PINNAME_BIND(PA_1, SPI_0), SPI_0, SYS_GPA_MFPL_PA1MFP_SPI0_MISO0},
{PA_1, SPI_1, SYS_GPA_MFPL_PA1MFP_SPI1_MISO},
{NU_PINNAME_BIND(PA_1, SPI_1), SPI_1, SYS_GPA_MFPL_PA1MFP_SPI1_MISO},
{PA_9, SPI_3, SYS_GPA_MFPH_PA9MFP_SPI3_MISO},
{PA_14, SPI_3, SYS_GPA_MFPH_PA14MFP_SPI3_MISO},
{PB_5, SPI_2, SYS_GPB_MFPL_PB5MFP_SPI2_MISO},
{PB_9, SPI_4, SYS_GPB_MFPH_PB9MFP_SPI4_MISO},
{PB_13, SPI_1, SYS_GPB_MFPH_PB13MFP_SPI1_MISO},
{PC_1, SPI_0, SYS_GPC_MFPL_PC1MFP_SPI0_MISO0},
{PC_3, SPI_2, SYS_GPC_MFPL_PC3MFP_SPI2_MISO},
{PC_7, SPI_2, SYS_GPC_MFPL_PC7MFP_SPI2_MISO},
{PC_12, SPI_4, SYS_GPC_MFPH_PC12MFP_SPI4_MISO},
{PD_1, SPI_1, SYS_GPD_MFPL_PD1MFP_SPI1_MISO},
{PD_7, SPI_2, SYS_GPD_MFPL_PD7MFP_SPI2_MISO},
{PE_1, SPI_0, SYS_GPE_MFPL_PE1MFP_SPI0_MISO0},
{NU_PINNAME_BIND(PE_1, SPI_0), SPI_0, SYS_GPE_MFPL_PE1MFP_SPI0_MISO0},
{PE_1, SPI_2, SYS_GPE_MFPL_PE1MFP_SPI2_MISO},
{NU_PINNAME_BIND(PE_1, SPI_2), SPI_2, SYS_GPE_MFPL_PE1MFP_SPI2_MISO},
{PE_3, SPI_4, SYS_GPE_MFPL_PE3MFP_SPI4_MISO},
{PE_9, SPI_3, SYS_GPE_MFPH_PE9MFP_SPI3_MISO},
{PF_7, SPI_1, SYS_GPF_MFPL_PF7MFP_SPI1_MISO},
{PG_4, SPI_3, SYS_GPG_MFPL_PG4MFP_SPI3_MISO},
{PG_7, SPI_4, SYS_GPG_MFPL_PG7MFP_SPI4_MISO},
{PH_4, SPI_2, SYS_GPH_MFPL_PH4MFP_SPI2_MISO},
{NC, NC, 0}
};
const PinMap PinMap_SPI_SCLK[] = {
{PA_2, SPI_0, SYS_GPA_MFPL_PA2MFP_SPI0_CLK},
{NU_PINNAME_BIND(PA_2, SPI_0), SPI_0, SYS_GPA_MFPL_PA2MFP_SPI0_CLK},
{PA_2, SPI_1, SYS_GPA_MFPL_PA2MFP_SPI1_CLK},
{NU_PINNAME_BIND(PA_2, SPI_1), SPI_1, SYS_GPA_MFPL_PA2MFP_SPI1_CLK},
{PA_7, SPI_2, SYS_GPA_MFPL_PA7MFP_SPI2_CLK},
{PA_10, SPI_3, SYS_GPA_MFPH_PA10MFP_SPI3_CLK},
{PA_13, SPI_3, SYS_GPA_MFPH_PA13MFP_SPI3_CLK},
{PB_3, SPI_2, SYS_GPB_MFPL_PB3MFP_SPI2_CLK},
{PB_11, SPI_4, SYS_GPB_MFPH_PB11MFP_SPI4_CLK},
{PB_14, SPI_1, SYS_GPB_MFPH_PB14MFP_SPI1_CLK},
{PC_1, SPI_2, SYS_GPC_MFPL_PC1MFP_SPI2_CLK},
{PC_2, SPI_0, SYS_GPC_MFPL_PC2MFP_SPI0_CLK},
{PC_10, SPI_4, SYS_GPC_MFPH_PC10MFP_SPI4_CLK},
{PC_14, SPI_0, SYS_GPC_MFPH_PC14MFP_SPI0_CLK},
{PD_2, SPI_1, SYS_GPD_MFPL_PD2MFP_SPI1_CLK},
{PD_5, SPI_2, SYS_GPD_MFPL_PD5MFP_SPI2_CLK},
{PE_4, SPI_4, SYS_GPE_MFPL_PE4MFP_SPI4_CLK},
{PE_8, SPI_3, SYS_GPE_MFPH_PE8MFP_SPI3_CLK},
{PF_2, SPI_0, SYS_GPF_MFPL_PF2MFP_SPI0_CLK},
{PF_8, SPI_1, SYS_GPF_MFPH_PF8MFP_SPI1_CLK},
{PG_3, SPI_3, SYS_GPG_MFPL_PG3MFP_SPI3_CLK},
{PG_6, SPI_4, SYS_GPG_MFPL_PG6MFP_SPI4_CLK},
{PH_6, SPI_2, SYS_GPH_MFPL_PH6MFP_SPI2_CLK},
{PH_8, SPI_0, SYS_GPH_MFPH_PH8MFP_SPI0_CLK},
{NU_PINNAME_BIND(PH_8, SPI_0), SPI_0, SYS_GPH_MFPH_PH8MFP_SPI0_CLK},
{PH_8, SPI_2, SYS_GPH_MFPH_PH8MFP_SPI2_CLK},
{NU_PINNAME_BIND(PH_8, SPI_2), SPI_2, SYS_GPH_MFPH_PH8MFP_SPI2_CLK},
{NC, NC, 0}
};
const PinMap PinMap_SPI_SSEL[] = {
{PA_3, SPI_0, SYS_GPA_MFPL_PA3MFP_SPI0_SS},
{NU_PINNAME_BIND(PA_3, SPI_0), SPI_0, SYS_GPA_MFPL_PA3MFP_SPI0_SS},
{PA_3, SPI_1, SYS_GPA_MFPL_PA3MFP_SPI1_SS},
{NU_PINNAME_BIND(PA_3, SPI_1), SPI_1, SYS_GPA_MFPL_PA3MFP_SPI1_SS},
{PA_6, SPI_2, SYS_GPA_MFPL_PA6MFP_SPI2_SS},
{PA_11, SPI_3, SYS_GPA_MFPH_PA11MFP_SPI3_SS},
{PA_12, SPI_3, SYS_GPA_MFPH_PA12MFP_SPI3_SS},
{PB_2, SPI_2, SYS_GPB_MFPL_PB2MFP_SPI2_SS},
{PB_10, SPI_4, SYS_GPB_MFPH_PB10MFP_SPI4_SS},
{PB_15, SPI_1, SYS_GPB_MFPH_PB15MFP_SPI1_SS},
{PC_0, SPI_2, SYS_GPC_MFPL_PC0MFP_SPI2_SS},
{PC_3, SPI_0, SYS_GPC_MFPL_PC3MFP_SPI0_SS},
{PC_9, SPI_4, SYS_GPC_MFPH_PC9MFP_SPI4_SS},
{PD_3, SPI_1, SYS_GPD_MFPL_PD3MFP_SPI1_SS},
{PD_4, SPI_2, SYS_GPD_MFPL_PD4MFP_SPI2_SS},
{PE_5, SPI_4, SYS_GPE_MFPL_PE5MFP_SPI4_SS},
{PE_11, SPI_3, SYS_GPE_MFPH_PE11MFP_SPI3_SS},
{PF_9, SPI_1, SYS_GPF_MFPH_PF9MFP_SPI1_SS},
{PG_2, SPI_3, SYS_GPG_MFPL_PG2MFP_SPI3_SS},
{PG_5, SPI_4, SYS_GPG_MFPL_PG5MFP_SPI4_SS},
{PH_7, SPI_2, SYS_GPH_MFPL_PH7MFP_SPI2_SS},
{PH_9, SPI_0, SYS_GPH_MFPH_PH9MFP_SPI0_SS},
{NU_PINNAME_BIND(PH_9, SPI_0), SPI_0, SYS_GPH_MFPH_PH9MFP_SPI0_SS},
{PH_9, SPI_2, SYS_GPH_MFPH_PH9MFP_SPI2_SS},
{NU_PINNAME_BIND(PH_9, SPI_2), SPI_2, SYS_GPH_MFPH_PH9MFP_SPI2_SS},
{NC, NC, 0}
};
//*** SD ***
const PinMap PinMap_SD_DAT0[] = {
{PA_0, SD_1, SYS_GPA_MFPL_PA0MFP_SD1_DAT0},
{PA_8, SD_1, SYS_GPA_MFPH_PA8MFP_SD1_DAT0},
{PB_2, SD_0, SYS_GPB_MFPL_PB2MFP_SD0_DAT0},
{PE_2, SD_0, SYS_GPE_MFPL_PE2MFP_SD0_DAT0},
{PG_12, SD_1, SYS_GPG_MFPH_PG12MFP_SD1_DAT0},
{NC, NC, 0}
};
const PinMap PinMap_SD_DAT1[] = {
{PA_1, SD_1, SYS_GPA_MFPL_PA1MFP_SD1_DAT1},
{PA_9, SD_1, SYS_GPA_MFPH_PA9MFP_SD1_DAT1},
{PB_3, SD_0, SYS_GPB_MFPL_PB3MFP_SD0_DAT1},
{PE_3, SD_0, SYS_GPE_MFPL_PE3MFP_SD0_DAT1},
{PG_11, SD_1, SYS_GPG_MFPH_PG11MFP_SD1_DAT1},
{NC, NC, 0}
};
const PinMap PinMap_SD_DAT2[] = {
{PA_2, SD_1, SYS_GPA_MFPL_PA2MFP_SD1_DAT2},
{PA_10, SD_1, SYS_GPA_MFPH_PA10MFP_SD1_DAT2},
{PB_4, SD_0, SYS_GPB_MFPL_PB4MFP_SD0_DAT2},
{PE_4, SD_0, SYS_GPE_MFPL_PE4MFP_SD0_DAT2},
{PG_10, SD_1, SYS_GPG_MFPH_PG10MFP_SD1_DAT2},
{NC, NC, 0}
};
const PinMap PinMap_SD_DAT3[] = {
{PA_3, SD_1, SYS_GPA_MFPL_PA3MFP_SD1_DAT3},
{PA_11, SD_1, SYS_GPA_MFPH_PA11MFP_SD1_DAT3},
{PB_5, SD_0, SYS_GPB_MFPL_PB5MFP_SD0_DAT3},
{PE_5, SD_0, SYS_GPE_MFPL_PE5MFP_SD0_DAT3},
{PG_9, SD_1, SYS_GPG_MFPH_PG9MFP_SD1_DAT3},
{NC, NC, 0}
};
const PinMap PinMap_SD_CMD[] = {
{PA_5, SD_1, SYS_GPA_MFPL_PA5MFP_SD1_CMD},
{PB_0, SD_0, SYS_GPB_MFPL_PB0MFP_SD0_CMD},
{PB_7, SD_1, SYS_GPB_MFPL_PB7MFP_SD1_CMD},
{PE_7, SD_0, SYS_GPE_MFPL_PE7MFP_SD0_CMD},
{PG_13, SD_1, SYS_GPG_MFPH_PG13MFP_SD1_CMD},
{NC, NC, 0}
};
const PinMap PinMap_SD_CLK[] = {
{PA_4, SD_1, SYS_GPA_MFPL_PA4MFP_SD1_CLK},
{PB_1, SD_0, SYS_GPB_MFPL_PB1MFP_SD0_CLK},
{PB_6, SD_1, SYS_GPB_MFPL_PB6MFP_SD1_CLK},
{PE_6, SD_0, SYS_GPE_MFPL_PE6MFP_SD0_CLK},
{PG_14, SD_1, SYS_GPG_MFPH_PG14MFP_SD1_CLK},
{NC, NC, 0}
};
const PinMap PinMap_SD_CD[] = {
{PA_6, SD_1, SYS_GPA_MFPL_PA6MFP_SD1_nCD},
{PB_12, SD_0, SYS_GPB_MFPH_PB12MFP_SD0_nCD},
{PD_13, SD_0, SYS_GPD_MFPH_PD13MFP_SD0_nCD},
{PE_14, SD_1, SYS_GPE_MFPH_PE14MFP_SD1_nCD},
{PG_15, SD_1, SYS_GPG_MFPH_PG15MFP_SD1_nCD},
{NC, NC, 0}
};
//*** CAN ***
const PinMap PinMap_CAN_TD[] = {
{PA_5, CAN_0, SYS_GPA_MFPL_PA5MFP_CAN0_TXD},
{PA_12, CAN_0, SYS_GPA_MFPH_PA12MFP_CAN0_TXD},
{PB_7, CAN_1, SYS_GPB_MFPL_PB7MFP_CAN1_TXD},
{PB_11, CAN_0, SYS_GPB_MFPH_PB11MFP_CAN0_TXD},
{PC_3, CAN_1, SYS_GPC_MFPL_PC3MFP_CAN1_TXD},
{PC_5, CAN_0, SYS_GPC_MFPL_PC5MFP_CAN0_TXD},
{PC_10, CAN_1, SYS_GPC_MFPH_PC10MFP_CAN1_TXD},
{PC_13, CAN_1, SYS_GPC_MFPH_PC13MFP_CAN1_TXD},
{PD_11, CAN_0, SYS_GPD_MFPH_PD11MFP_CAN0_TXD},
{PE_7, CAN_1, (int) SYS_GPE_MFPL_PE7MFP_CAN1_TXD},
{PE_14, CAN_0, SYS_GPE_MFPH_PE14MFP_CAN0_TXD},
{PG_0, CAN_1, SYS_GPG_MFPL_PG0MFP_CAN1_TXD},
{NC, NC, 0}
};
const PinMap PinMap_CAN_RD[] = {
{PA_4, CAN_0, SYS_GPA_MFPL_PA4MFP_CAN0_RXD},
{PA_13, CAN_0, SYS_GPA_MFPH_PA13MFP_CAN0_RXD},
{PB_6, CAN_1, SYS_GPB_MFPL_PB6MFP_CAN1_RXD},
{PB_10, CAN_0, SYS_GPB_MFPH_PB10MFP_CAN0_RXD},
{PC_2, CAN_1, SYS_GPC_MFPL_PC2MFP_CAN1_RXD},
{PC_4, CAN_0, SYS_GPC_MFPL_PC4MFP_CAN0_RXD},
{PC_9, CAN_1, SYS_GPC_MFPH_PC9MFP_CAN1_RXD},
{PD_10, CAN_0, SYS_GPD_MFPH_PD10MFP_CAN0_RXD},
{PD_12, CAN_1, SYS_GPD_MFPH_PD12MFP_CAN1_RXD},
{PE_6, CAN_1, SYS_GPE_MFPL_PE6MFP_CAN1_RXD},
{PE_15, CAN_0, SYS_GPE_MFPH_PE15MFP_CAN0_RXD},
{PG_1, CAN_1, SYS_GPG_MFPL_PG1MFP_CAN1_RXD},
{NC, NC, 0}
};

View File

@ -0,0 +1,77 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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_PERIPHERALPINS_H
#define MBED_PERIPHERALPINS_H
#include "pinmap.h"
#include "PeripheralNames.h"
#ifdef __cplusplus
extern "C" {
#endif
//*** GPIO ***
extern const PinMap PinMap_GPIO[];
//*** ADC ***
extern const PinMap PinMap_ADC[];
//*** I2C ***
extern const PinMap PinMap_I2C_SDA[];
extern const PinMap PinMap_I2C_SCL[];
//*** PWM ***
extern const PinMap PinMap_PWM[];
//*** SERIAL ***
extern const PinMap PinMap_UART_TX[];
extern const PinMap PinMap_UART_RX[];
extern const PinMap PinMap_UART_RTS[];
extern const PinMap PinMap_UART_CTS[];
//*** SPI ***
extern const PinMap PinMap_SPI_MOSI[];
extern const PinMap PinMap_SPI_MISO[];
extern const PinMap PinMap_SPI_SCLK[];
extern const PinMap PinMap_SPI_SSEL[];
//*** SD ***
extern const PinMap PinMap_SD_CD[];
extern const PinMap PinMap_SD_CMD[];
extern const PinMap PinMap_SD_CLK[];
extern const PinMap PinMap_SD_DAT0[];
extern const PinMap PinMap_SD_DAT1[];
extern const PinMap PinMap_SD_DAT2[];
extern const PinMap PinMap_SD_DAT3[];
//*** CAN ***
extern PinMap const PinMap_CAN_TD[];
extern PinMap const PinMap_CAN_RD[];
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,132 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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
#define NU_PININDEX_Pos 0
#define NU_PININDEX_Msk (0xFFul << NU_PININDEX_Pos)
#define NU_PINPORT_Pos 8
#define NU_PINPORT_Msk (0xFul << NU_PINPORT_Pos)
#define NU_PIN_MODINDEX_Pos 12
#define NU_PIN_MODINDEX_Msk (0xFul << NU_PIN_MODINDEX_Pos)
#define NU_PIN_BIND_Pos 16
#define NU_PIN_BIND_Msk (0x1ul << NU_PIN_BIND_Pos)
#define NU_PININDEX(PINNAME) (((unsigned int)(PINNAME) & NU_PININDEX_Msk) >> NU_PININDEX_Pos)
#define NU_PINPORT(PINNAME) (((unsigned int)(PINNAME) & NU_PINPORT_Msk) >> NU_PINPORT_Pos)
#define NU_PIN_BIND(PINNAME) (((unsigned int)(PINNAME) & NU_PIN_BIND_Msk) >> NU_PIN_BIND_Pos)
#define NU_PIN_MODINDEX(PINNAME) (((unsigned int)(PINNAME) & NU_PIN_MODINDEX_Msk) >> NU_PIN_MODINDEX_Pos)
#define NU_PINNAME(PORT, PIN) ((((unsigned int) (PORT)) << (NU_PINPORT_Pos)) | (((unsigned int) (PIN)) << NU_PININDEX_Pos))
#define NU_PINNAME_BIND(PINNAME, modname) ((PinName) NU_PINNAME_BIND_(NU_PINPORT(PINNAME), NU_PININDEX(PINNAME), modname))
#define NU_PINNAME_BIND_(PORT, PIN, modname) ((((unsigned int)(PORT)) << NU_PINPORT_Pos) | (((unsigned int)(PIN)) << NU_PININDEX_Pos) | (NU_MODINDEX(modname) << NU_PIN_MODINDEX_Pos) | NU_PIN_BIND_Msk)
#define NU_PORT_BASE(PORT) ((GPIO_T *)(((uint32_t) GPIOA_BASE) + 0x40 * PORT))
#define NU_MFP_POS(PIN) ((PIN % 8) * 4)
#define NU_MFP_MSK(PIN) (0xful << NU_MFP_POS(PIN))
// LEGACY
#define NU_PINNAME_TO_PIN(PINNAME) NU_PININDEX(PINNAME)
#define NU_PINNAME_TO_PORT(PINNAME) NU_PINPORT(PINNAME)
#define NU_PINNAME_TO_MODSUBINDEX(PINNAME) NU_PIN_MODINDEX(PINNAME)
#define NU_PORT_N_PIN_TO_PINNAME(PORT, PIN) NU_PINNAME((PORT), (PIN))
typedef enum {
PIN_INPUT,
PIN_OUTPUT
} PinDirection;
typedef enum {
PullNone = 0,
PullDown,
PullUp,
PushPull,
OpenDrain,
Quasi,
PullDefault = PullUp,
} PinMode;
typedef enum {
// Not connected
NC = (int)0xFFFFFFFF,
// Generic naming
PA_0 = NU_PORT_N_PIN_TO_PINNAME(0, 0), PA_1, PA_2, PA_3, PA_4, PA_5, PA_6, PA_7, PA_8, PA_9, PA_10, PA_11, PA_12, PA_13, PA_14, PA_15,
PB_0 = NU_PORT_N_PIN_TO_PINNAME(1, 0), PB_1, PB_2, PB_3, PB_4, PB_5, PB_6, PB_7, PB_8, PB_9, PB_10, PB_11, PB_12, PB_13, PB_14, PB_15,
PC_0 = NU_PORT_N_PIN_TO_PINNAME(2, 0), PC_1, PC_2, PC_3, PC_4, PC_5, PC_6, PC_7, PC_8, PC_9, PC_10, PC_11, PC_12, PC_13, PC_14,
PD_0 = NU_PORT_N_PIN_TO_PINNAME(3, 0), PD_1, PD_2, PD_3, PD_4, PD_5, PD_6, PD_7, PD_8, PD_9, PD_10, PD_11, PD_12, PD_13, PD_14,
PE_0 = NU_PORT_N_PIN_TO_PINNAME(4, 0), PE_1, PE_2, PE_3, PE_4, PE_5, PE_6, PE_7, PE_8, PE_9, PE_10, PE_11, PE_12, PE_13, PE_14, PE_15,
PF_0 = NU_PORT_N_PIN_TO_PINNAME(5, 0), PF_1, PF_2, PF_3, PF_4, PF_5, PF_6, PF_7, PF_8, PF_9, PF_10, PF_11,
PG_0 = NU_PORT_N_PIN_TO_PINNAME(6, 0), PG_1, PG_2, PG_3, PG_4, PG_5, PG_6, PG_7, PG_8, PG_9, PG_10, PG_11, PG_12, PG_13, PG_14, PG_15,
PH_0 = NU_PORT_N_PIN_TO_PINNAME(7, 0), PH_1, PH_2, PH_3, PH_4, PH_5, PH_6, PH_7, PH_8, PH_9, PH_10, PH_11,
// Arduino UNO naming
A0 = PB_6,
A1 = PB_7,
A2 = PB_8,
A3 = PB_3,
A4 = PB_4,
A5 = PB_5,
D0 = PH_9,
D1 = PH_8,
D2 = PB_9,
D3 = PF_11,
D4 = PG_4,
D5 = PC_11,
D6 = PC_12,
D7 = PC_13,
D8 = PA_5,
D9 = PA_4,
D10 = PA_3,
D11 = PA_0,
D12 = PA_1,
D13 = PA_2,
D14 = PG_3,
D15 = PG_2,
// Note: board-specific
// UART naming
USBTX = PD_3,
USBRX = PD_2,
STDIO_UART_TX = USBTX,
STDIO_UART_RX = USBRX,
// LED naming
LED_RED = PH_0,
LED_YELLOW = PH_1,
LED_GREEN = PH_2,
LED1 = LED_RED,
LED2 = LED_YELLOW,
LED3 = LED_GREEN,
LED4 = LED1, // No real LED. Just for passing ATS.
// Button naming
SW2 = PC_10,
SW3 = PC_9,
} PinName;
#ifdef __cplusplus
}
#endif
#endif // MBED_PINNAMES_H

View File

@ -0,0 +1,38 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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_PORTNAMES_H
#define MBED_PORTNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PortA = 0,
PortB = 1,
PortC = 2,
PortD = 3,
PortE = 4,
PortF = 5,
PortG = 6,
PortH = 7
} PortName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,24 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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
#define DEVICE_ID_LENGTH 24
#include "objects.h"
#endif

View File

@ -0,0 +1,72 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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 "analogin_api.h"
void mbed_sdk_init(void)
{
// NOTE: Support singleton semantics to be called from other init functions
static int inited = 0;
if (inited) {
return;
}
inited = 1;
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Unlock protected registers */
SYS_UnlockReg();
/* Enable HIRC clock (Internal RC 22.1184MHz) */
CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);
/* Enable HXT clock (external XTAL 12MHz) */
CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);
/* Enable LIRC for lp_ticker */
CLK_EnableXtalRC(CLK_PWRCTL_LIRCEN_Msk);
/* Enable LXT for RTC */
CLK_EnableXtalRC(CLK_PWRCTL_LXTEN_Msk);
/* Wait for HIRC clock ready */
CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
/* Wait for HXT clock ready */
CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
/* Wait for LIRC clock ready */
CLK_WaitClockReady(CLK_STATUS_LIRCSTB_Msk);
/* Wait for LXT clock ready */
CLK_WaitClockReady(CLK_STATUS_LXTSTB_Msk);
/* Select HCLK clock source as HIRC and HCLK clock divider as 1 */
CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));
/* Set core clock as 192000000 from PLL */
CLK_SetCoreClock(192000000);
/* Set PCLK0/PCLK1 to HCLK/2 */
CLK->PCLKDIV = (CLK_PCLKDIV_PCLK0DIV2 | CLK_PCLKDIV_PCLK1DIV2); // PCLK divider set 2
#if DEVICE_ANALOGIN
/* Vref connect to internal */
SYS->VREFCTL = (SYS->VREFCTL & ~SYS_VREFCTL_VREFCTL_Msk) | SYS_VREFCTL_VREF_3_0V;
#endif
/* Update System Core Clock */
/* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */
SystemCoreClockUpdate();
/* Lock protected registers */
SYS_LockReg();
}

View File

@ -0,0 +1,139 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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 "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#include "dma_api.h"
#ifdef __cplusplus
extern "C" {
#endif
struct gpio_irq_s {
//IRQn_Type irq_n;
//uint32_t irq_index;
//uint32_t event;
PinName pin;
uint32_t irq_handler;
uint32_t irq_id;
};
struct port_s {
PortName port;
uint32_t mask;
PinDirection direction;
};
struct analogin_s {
ADCName adc;
//PinName pin;
};
struct serial_s {
UARTName uart;
PinName pin_tx;
PinName pin_rx;
uint32_t baudrate;
uint32_t databits;
uint32_t parity;
uint32_t stopbits;
void (*vec)(void);
uint32_t irq_handler;
uint32_t irq_id;
uint32_t irq_en;
uint32_t inten_msk;
// Async transfer related fields
DMAUsage dma_usage_tx;
DMAUsage dma_usage_rx;
int dma_chn_id_tx;
int dma_chn_id_rx;
uint32_t event;
void (*irq_handler_tx_async)(void);
void (*irq_handler_rx_async)(void);
};
struct spi_s {
SPIName spi;
PinName pin_miso;
PinName pin_mosi;
PinName pin_sclk;
PinName pin_ssel;
//void (*vec)(void);
// Async transfer related fields
DMAUsage dma_usage;
int dma_chn_id_tx;
int dma_chn_id_rx;
uint32_t event;
//void (*irq_handler_tx_async)(void);
//void (*irq_handler_rx_async)(void);
};
struct i2c_s {
I2CName i2c;
//void (*vec)(void);
int slaveaddr_state;
uint32_t tran_ctrl;
char * tran_beg;
char * tran_pos;
char * tran_end;
int inten;
// Async transfer related fields
DMAUsage dma_usage;
uint32_t event;
int stop;
uint32_t address;
};
struct pwmout_s {
PWMName pwm;
//PinName pin;
uint32_t period_us;
uint32_t pulsewidth_us;
};
struct sleep_s {
int powerdown;
};
struct trng_s {
uint8_t dummy;
};
struct can_s {
CANName can;
int index;
};
#ifdef __cplusplus
}
#endif
#include "gpio_object.h"
#endif

View File

@ -0,0 +1,105 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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 "analogin_api.h"
#if DEVICE_ANALOGIN
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
#include "nu_modutil.h"
static uint32_t eadc_modinit_mask = 0;
static const struct nu_modinit_s adc_modinit_tab[] = {
{ADC_0_0, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_1, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_2, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_3, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_4, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_5, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_6, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_7, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_8, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_9, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_10, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_11, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_12, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_13, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_14, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
{ADC_0_15, EADC_MODULE, 0, CLK_CLKDIV0_EADC(8), EADC_RST, ADC0_IRQn, NULL},
};
void analogin_init(analogin_t *obj, PinName pin)
{
obj->adc = (ADCName) pinmap_peripheral(pin, PinMap_ADC);
MBED_ASSERT(obj->adc != (ADCName) NC);
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->adc);
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
// NOTE: All channels (identified by ADCName) share a ADC module. This reset will also affect other channels of the same ADC module.
if (! eadc_modinit_mask) {
// Reset this module if no channel enabled
SYS_ResetModule(modinit->rsetidx);
// Select clock source of paired channels
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable clock of paired channels
CLK_EnableModuleClock(modinit->clkidx);
// Set the ADC internal sampling time, input mode as single-end and enable the A/D converter
EADC_Open(eadc_base, EADC_CTL_DIFFEN_SINGLE_END);
}
uint32_t chn = NU_MODSUBINDEX(obj->adc);
// Wire pinout
pinmap_pinout(pin, PinMap_ADC);
// Configure the sample module Nmod for analog input channel Nch and software trigger source
EADC_ConfigSampleModule(eadc_base, chn, EADC_SOFTWARE_TRIGGER, chn);
eadc_modinit_mask |= 1 << chn;
}
uint16_t analogin_read_u16(analogin_t *obj)
{
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
uint32_t chn = NU_MODSUBINDEX(obj->adc);
EADC_START_CONV(eadc_base, 1 << chn);
while (EADC_GET_DATA_VALID_FLAG(eadc_base, 1 << chn) != ((uint32_t) (1 << chn)));
uint16_t conv_res_12 = EADC_GET_CONV_DATA(eadc_base, chn);
// Just 12 bits are effective. Convert to 16 bits.
// conv_res_12: 0000 b11b10b9b8 b7b6b5b4 b3b2b1b0
// conv_res_16: b11b10b9b8 b7b6b5b4 b3b2b1b0 b11b10b9b8
uint16_t conv_res_16 = (conv_res_12 << 4) | (conv_res_12 >> 8);
return conv_res_16;
}
float analogin_read(analogin_t *obj)
{
uint16_t value = analogin_read_u16(obj);
return (float) value * (1.0f / (float) 0xFFFF);
}
#endif

View File

@ -0,0 +1,355 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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 "can_api.h"
#include "m480_gpio.h"
#include "m480_can.h"
#if DEVICE_CAN
#include <string.h>
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
#include "nu_modutil.h"
#include "nu_miscutil.h"
#include "nu_bitutil.h"
#include "mbed_critical.h"
#define NU_CAN_DEBUG 0
#define CAN_NUM 2
static uint32_t can_irq_ids[CAN_NUM] = {0};
static can_irq_handler can0_irq_handler;
static can_irq_handler can1_irq_handler;
extern uint32_t CAN_GetCANBitRate(CAN_T *tCAN);
extern void CAN_EnterInitMode(CAN_T *tCAN, uint8_t u8Mask);
extern void CAN_LeaveInitMode(CAN_T *tCAN);
extern void CAN_LeaveTestMode(CAN_T *tCAN);
extern void CAN_EnterTestMode(CAN_T *tCAN, uint8_t u8TestMask);
static const struct nu_modinit_s can_modinit_tab[] = {
{CAN_0, CAN0_MODULE, 0, 0, CAN0_RST, CAN0_IRQn, NULL},
{CAN_1, CAN1_MODULE, 0, 0, CAN1_RST, CAN1_IRQn, NULL},
{NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL}
};
void can_init_freq(can_t *obj, PinName rd, PinName td, int hz)
{
uint32_t can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD);
uint32_t can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD);
obj->can = (CANName)pinmap_merge(can_td, can_rd);
MBED_ASSERT((int)obj->can != NC);
const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->can);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
NVIC_DisableIRQ(CAN0_IRQn);
NVIC_DisableIRQ(CAN1_IRQn);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
if(obj->can == CAN_1) {
obj->index = 1;
} else
obj->index = 0;
pinmap_pinout(td, PinMap_CAN_TD);
pinmap_pinout(rd, PinMap_CAN_RD);
#if 0
/* TBD: For M487 mbed Board Transmitter Setting (RS Pin) */
GPIO_SetMode(PA, BIT2| BIT3, GPIO_MODE_OUTPUT);
PA2 = 0x00;
PA3 = 0x00;
#endif
CAN_Open((CAN_T *)NU_MODBASE(obj->can), hz, CAN_NORMAL_MODE);
can_filter(obj, 0, 0, CANStandard, 0);
}
void can_init(can_t *obj, PinName rd, PinName td)
{
can_init_freq(obj, rd, td, 500000);
}
void can_free(can_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->can);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
CLK_DisableModuleClock(modinit->clkidx);
}
int can_frequency(can_t *obj, int hz)
{
CAN_SetBaudRate((CAN_T *)NU_MODBASE(obj->can), hz);
return CAN_GetCANBitRate((CAN_T *)NU_MODBASE(obj->can));
}
static void can_irq(CANName name, int id)
{
CAN_T *can = (CAN_T *)NU_MODBASE(name);
uint32_t u8IIDRstatus;
u8IIDRstatus = can->IIDR;
if(u8IIDRstatus == 0x00008000) { /* Check Status Interrupt Flag (Error status Int and Status change Int) */
/**************************/
/* Status Change interrupt*/
/**************************/
if(can->STATUS & CAN_STATUS_RXOK_Msk) {
can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/
if(id)
can1_irq_handler(can_irq_ids[id], IRQ_RX);
else
can0_irq_handler(can_irq_ids[id], IRQ_RX);
}
if(can->STATUS & CAN_STATUS_TXOK_Msk) {
can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/
if(id)
can1_irq_handler(can_irq_ids[id], IRQ_TX);
else
can0_irq_handler(can_irq_ids[id], IRQ_TX);
}
/**************************/
/* Error Status interrupt */
/**************************/
if(can->STATUS & CAN_STATUS_EWARN_Msk) {
if(id)
can1_irq_handler(can_irq_ids[id], IRQ_ERROR);
else
can0_irq_handler(can_irq_ids[id], IRQ_ERROR);
}
if(can->STATUS & CAN_STATUS_BOFF_Msk) {
if(id)
can1_irq_handler(can_irq_ids[id], IRQ_BUS);
else
can0_irq_handler(can_irq_ids[id], IRQ_BUS);
}
} else if (u8IIDRstatus!=0) {
if(id)
can1_irq_handler(can_irq_ids[id], IRQ_OVERRUN);
else
can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN);
CAN_CLR_INT_PENDING_BIT(can, ((can->IIDR) -1)); /* Clear Interrupt Pending */
} else if(can->WU_STATUS == 1) {
can->WU_STATUS = 0; /* Write '0' to clear */
if(id)
can1_irq_handler(can_irq_ids[id], IRQ_WAKEUP);
else
can0_irq_handler(can_irq_ids[id], IRQ_WAKEUP);
}
}
void CAN0_IRQHandler(void)
{
can_irq(CAN_0, 0);
}
void CAN1_IRQHandler(void)
{
can_irq(CAN_1, 1);
}
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
{
if(obj->index)
can1_irq_handler = handler;
else
can0_irq_handler = handler;
can_irq_ids[obj->index] = id;
}
void can_irq_free(can_t *obj)
{
CAN_DisableInt((CAN_T *)NU_MODBASE(obj->can), (CAN_CON_IE_Msk|CAN_CON_SIE_Msk|CAN_CON_EIE_Msk));
can_irq_ids[obj->index] = 0;
if(!obj->index)
NVIC_DisableIRQ(CAN0_IRQn);
else
NVIC_DisableIRQ(CAN1_IRQn);
}
void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable)
{
uint8_t u8Mask;
u8Mask = ((enable != 0 )? CAN_CON_IE_Msk :0);
switch (irq) {
case IRQ_ERROR:
case IRQ_BUS:
case IRQ_PASSIVE:
u8Mask = u8Mask | CAN_CON_EIE_Msk | CAN_CON_SIE_Msk;
break;
case IRQ_RX:
case IRQ_TX:
case IRQ_OVERRUN:
case IRQ_WAKEUP:
u8Mask = u8Mask | CAN_CON_SIE_Msk;
break;
default:
break;
}
CAN_EnterInitMode((CAN_T*)NU_MODBASE(obj->can), u8Mask);
CAN_LeaveInitMode((CAN_T*)NU_MODBASE(obj->can));
if(!obj->index) {
NVIC_SetVector(CAN0_IRQn, (uint32_t)&CAN0_IRQHandler);
NVIC_EnableIRQ(CAN0_IRQn);
} else {
NVIC_SetVector(CAN1_IRQn, (uint32_t)&CAN1_IRQHandler);
NVIC_EnableIRQ(CAN1_IRQn);
}
}
int can_write(can_t *obj, CAN_Message msg, int cc)
{
STR_CANMSG_T CMsg;
CMsg.IdType = (uint32_t)msg.format;
CMsg.FrameType = (uint32_t)!msg.type;
CMsg.Id = msg.id;
CMsg.DLC = msg.len;
memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8);
return CAN_Transmit((CAN_T *)(NU_MODBASE(obj->can)), cc, &CMsg);
}
int can_read(can_t *obj, CAN_Message *msg, int handle)
{
STR_CANMSG_T CMsg;
if(!CAN_Receive((CAN_T *)(NU_MODBASE(obj->can)), handle, &CMsg))
return 0;
msg->format = (CANFormat)CMsg.IdType;
msg->type = (CANType)!CMsg.FrameType;
msg->id = CMsg.Id;
msg->len = CMsg.DLC;
memcpy(&msg->data[0], &CMsg.Data[0], 8);
return 1;
}
int can_mode(can_t *obj, CanMode mode)
{
int success = 0;
switch (mode) {
case MODE_RESET:
CAN_LeaveTestMode((CAN_T*)NU_MODBASE(obj->can));
success = 1;
break;
case MODE_NORMAL:
CAN_EnterTestMode((CAN_T*)NU_MODBASE(obj->can), CAN_TEST_BASIC_Msk);
success = 1;
break;
case MODE_SILENT:
CAN_EnterTestMode((CAN_T*)NU_MODBASE(obj->can), CAN_TEST_SILENT_Msk);
success = 1;
break;
case MODE_TEST_LOCAL:
case MODE_TEST_GLOBAL:
CAN_EnterTestMode((CAN_T*)NU_MODBASE(obj->can), CAN_TEST_LBACK_Msk);
success = 1;
break;
case MODE_TEST_SILENT:
CAN_EnterTestMode((CAN_T*)NU_MODBASE(obj->can), CAN_TEST_SILENT_Msk | CAN_TEST_LBACK_Msk);
success = 1;
break;
default:
success = 0;
break;
}
return success;
}
int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle)
{
return CAN_SetRxMsg((CAN_T *)NU_MODBASE(obj->can), handle, (uint32_t)format, id);
}
void can_reset(can_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->can, can_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == (int) obj->can);
// Reset this module
SYS_ResetModule(modinit->rsetidx);
}
unsigned char can_rderror(can_t *obj)
{
CAN_T *can = (CAN_T *)NU_MODBASE(obj->can);
return ((can->ERR>>8)&0xFF);
}
unsigned char can_tderror(can_t *obj)
{
CAN_T *can = (CAN_T *)NU_MODBASE(obj->can);
return ((can->ERR)&0xFF);
}
void can_monitor(can_t *obj, int silent)
{
CAN_EnterTestMode((CAN_T *)NU_MODBASE(obj->can), CAN_TEST_SILENT_Msk);
}
#endif // DEVICE_CAN

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
/**************************************************************************//**
* @file acmp.c
* @version V1.00
* @brief M480 series Analog Comparator(ACMP) driver source file
*
* @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "M480.h"
/** @addtogroup M480_Device_Driver M480 Device Driver
@{
*/
/** @addtogroup M480_ACMP_Driver ACMP Driver
@{
*/
/** @addtogroup M480_ACMP_EXPORTED_FUNCTIONS ACMP Exported Functions
@{
*/
/**
* @brief Configure the specified ACMP module
*
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum Comparator number.
* @param[in] u32NegSrc Comparator negative input selection. Including:
* - \ref ACMP_CTL_NEGSEL_PIN
* - \ref ACMP_CTL_NEGSEL_CRV
* - \ref ACMP_CTL_NEGSEL_VBG
* - \ref ACMP_CTL_NEGSEL_DAC
* @param[in] u32HysSel The hysteresis function option. Including:
* - \ref ACMP_CTL_HYSTERESIS_30MV
* - \ref ACMP_CTL_HYSTERESIS_20MV
* - \ref ACMP_CTL_HYSTERESIS_10MV
* - \ref ACMP_CTL_HYSTERESIS_DISABLE
*
* @return None
*
* @details Configure hysteresis function, select the source of negative input and enable analog comparator.
*/
void ACMP_Open(ACMP_T *acmp, uint32_t u32ChNum, uint32_t u32NegSrc, uint32_t u32HysSel)
{
acmp->CTL[u32ChNum] = (acmp->CTL[u32ChNum] & (~(ACMP_CTL_NEGSEL_Msk | ACMP_CTL_HYSSEL_Msk))) | (u32NegSrc | u32HysSel | ACMP_CTL_ACMPEN_Msk);
}
/**
* @brief Close analog comparator
*
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum Comparator number.
*
* @return None
*
* @details This function will clear ACMPEN bit of ACMP_CTL register to disable analog comparator.
*/
void ACMP_Close(ACMP_T *acmp, uint32_t u32ChNum)
{
acmp->CTL[u32ChNum] &= (~ACMP_CTL_ACMPEN_Msk);
}
/*@}*/ /* end of group M480_ACMP_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group M480_ACMP_Driver */
/*@}*/ /* end of group M480_Device_Driver */
/*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,414 @@
/**************************************************************************//**
* @file ACMP.h
* @version V1.00
* @brief M480 Series ACMP Driver Header File
*
* @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#ifndef __ACMP_H__
#define __ACMP_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup M480_Device_Driver M480 Device Driver
@{
*/
/** @addtogroup M480_ACMP_Driver ACMP Driver
@{
*/
/** @addtogroup M480_ACMP_EXPORTED_CONSTANTS ACMP Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* ACMP_CTL constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define ACMP_CTL_FILTSEL_OFF (0UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for filter function disabled. \hideinitializer */
#define ACMP_CTL_FILTSEL_1PCLK (1UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for 1 PCLK filter count. \hideinitializer */
#define ACMP_CTL_FILTSEL_2PCLK (2UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for 2 PCLK filter count. \hideinitializer */
#define ACMP_CTL_FILTSEL_4PCLK (3UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for 4 PCLK filter count. \hideinitializer */
#define ACMP_CTL_FILTSEL_8PCLK (4UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for 8 PCLK filter count. \hideinitializer */
#define ACMP_CTL_FILTSEL_16PCLK (5UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for 16 PCLK filter count. \hideinitializer */
#define ACMP_CTL_FILTSEL_32PCLK (6UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for 32 PCLK filter count. \hideinitializer */
#define ACMP_CTL_FILTSEL_64PCLK (7UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for 64 PCLK filter count. \hideinitializer */
#define ACMP_CTL_INTPOL_RF (0UL << ACMP_CTL_INTPOL_Pos) /*!< ACMP_CTL setting for selecting rising edge and falling edge as interrupt condition. \hideinitializer */
#define ACMP_CTL_INTPOL_R (1UL << ACMP_CTL_INTPOL_Pos) /*!< ACMP_CTL setting for selecting rising edge as interrupt condition. \hideinitializer */
#define ACMP_CTL_INTPOL_F (2UL << ACMP_CTL_INTPOL_Pos) /*!< ACMP_CTL setting for selecting falling edge as interrupt condition. \hideinitializer */
#define ACMP_CTL_POSSEL_P0 (0UL << ACMP_CTL_POSSEL_Pos) /*!< ACMP_CTL setting for selecting ACMPx_P0 pin as the source of ACMP V+. \hideinitializer */
#define ACMP_CTL_POSSEL_P1 (1UL << ACMP_CTL_POSSEL_Pos) /*!< ACMP_CTL setting for selecting ACMPx_P1 pin as the source of ACMP V+. \hideinitializer */
#define ACMP_CTL_POSSEL_P2 (2UL << ACMP_CTL_POSSEL_Pos) /*!< ACMP_CTL setting for selecting ACMPx_P2 pin as the source of ACMP V+. \hideinitializer */
#define ACMP_CTL_POSSEL_P3 (3UL << ACMP_CTL_POSSEL_Pos) /*!< ACMP_CTL setting for selecting ACMPx_P3 pin as the source of ACMP V+. \hideinitializer */
#define ACMP_CTL_NEGSEL_PIN (0UL << ACMP_CTL_NEGSEL_Pos) /*!< ACMP_CTL setting for selecting the voltage of ACMP negative input pin as the source of ACMP V-. \hideinitializer */
#define ACMP_CTL_NEGSEL_CRV (1UL << ACMP_CTL_NEGSEL_Pos) /*!< ACMP_CTL setting for selecting internal comparator reference voltage as the source of ACMP V-. \hideinitializer */
#define ACMP_CTL_NEGSEL_VBG (2UL << ACMP_CTL_NEGSEL_Pos) /*!< ACMP_CTL setting for selecting internal Band-gap voltage as the source of ACMP V-. \hideinitializer */
#define ACMP_CTL_NEGSEL_DAC (3UL << ACMP_CTL_NEGSEL_Pos) /*!< ACMP_CTL setting for selecting DAC output voltage as the source of ACMP V-. \hideinitializer */
#define ACMP_CTL_HYSTERESIS_30MV (3UL << ACMP_CTL_HYSSEL_Pos) /*!< ACMP_CTL setting for enabling the hysteresis function at 30mV. \hideinitializer */
#define ACMP_CTL_HYSTERESIS_20MV (2UL << ACMP_CTL_HYSSEL_Pos) /*!< ACMP_CTL setting for enabling the hysteresis function at 20mV. \hideinitializer */
#define ACMP_CTL_HYSTERESIS_10MV (1UL << ACMP_CTL_HYSSEL_Pos) /*!< ACMP_CTL setting for enabling the hysteresis function at 10mV. \hideinitializer */
#define ACMP_CTL_HYSTERESIS_DISABLE (0UL << ACMP_CTL_HYSSEL_Pos) /*!< ACMP_CTL setting for disabling the hysteresis function. \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* ACMP_VREF constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define ACMP_VREF_CRVSSEL_VDDA (0UL << ACMP_VREF_CRVSSEL_Pos) /*!< ACMP_VREF setting for selecting analog supply voltage VDDA as the CRV source voltage \hideinitializer */
#define ACMP_VREF_CRVSSEL_INTVREF (1UL << ACMP_VREF_CRVSSEL_Pos) /*!< ACMP_VREF setting for selecting internal reference voltage as the CRV source voltage \hideinitializer */
/*@}*/ /* end of group M480_ACMP_EXPORTED_CONSTANTS */
/** @addtogroup M480_ACMP_EXPORTED_FUNCTIONS ACMP Exported Functions
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* Define Macros and functions */
/*---------------------------------------------------------------------------------------------------------*/
/**
* @brief This macro is used to enable output inverse function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set ACMPOINV bit of ACMP_CTL register to enable output inverse function.
* \hideinitializer
*/
#define ACMP_ENABLE_OUTPUT_INVERSE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_ACMPOINV_Msk)
/**
* @brief This macro is used to disable output inverse function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear ACMPOINV bit of ACMP_CTL register to disable output inverse function.
* \hideinitializer
*/
#define ACMP_DISABLE_OUTPUT_INVERSE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_ACMPOINV_Msk)
/**
* @brief This macro is used to select ACMP negative input source
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @param[in] u32Src is comparator negative input selection. Including:
* - \ref ACMP_CTL_NEGSEL_PIN
* - \ref ACMP_CTL_NEGSEL_CRV
* - \ref ACMP_CTL_NEGSEL_VBG
* - \ref ACMP_CTL_NEGSEL_DAC
* @return None
* @details This macro will set NEGSEL (ACMP_CTL[5:4]) to determine the source of negative input.
* \hideinitializer
*/
#define ACMP_SET_NEG_SRC(acmp, u32ChNum, u32Src) ((acmp)->CTL[(u32ChNum)] = ((acmp)->CTL[(u32ChNum)] & ~ACMP_CTL_NEGSEL_Msk) | (u32Src))
/**
* @brief This macro is used to enable hysteresis function and set hysteresis to 30mV
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* \hideinitializer
*/
#define ACMP_ENABLE_HYSTERESIS(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_HYSTERESIS_30MV)
/**
* @brief This macro is used to disable hysteresis function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear HYSEL bits of ACMP_CTL register to disable hysteresis function.
* \hideinitializer
*/
#define ACMP_DISABLE_HYSTERESIS(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_HYSSEL_Msk)
/**
* @brief This macro is used to select hysteresis level
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @param[in] u32HysSel The hysteresis function option. Including:
* - \ref ACMP_CTL_HYSTERESIS_30MV
* - \ref ACMP_CTL_HYSTERESIS_20MV
* - \ref ACMP_CTL_HYSTERESIS_10MV
* - \ref ACMP_CTL_HYSTERESIS_DISABLE
* \hideinitializer
* @return None
*/
#define ACMP_CONFIG_HYSTERESIS(acmp, u32ChNum, u32HysSel) ((acmp)->CTL[(u32ChNum)] = ((acmp)->CTL[(u32ChNum)] & ~ACMP_CTL_HYSSEL_Msk) | (u32HysSel))
/**
* @brief This macro is used to enable interrupt
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set ACMPIE bit of ACMP_CTL register to enable interrupt function.
* If wake-up function is enabled, the wake-up interrupt will be enabled as well.
* \hideinitializer
*/
#define ACMP_ENABLE_INT(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_ACMPIE_Msk)
/**
* @brief This macro is used to disable interrupt
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear ACMPIE bit of ACMP_CTL register to disable interrupt function.
* \hideinitializer
*/
#define ACMP_DISABLE_INT(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_ACMPIE_Msk)
/**
* @brief This macro is used to enable ACMP
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set ACMPEN bit of ACMP_CTL register to enable analog comparator.
* \hideinitializer
*/
#define ACMP_ENABLE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_ACMPEN_Msk)
/**
* @brief This macro is used to disable ACMP
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear ACMPEN bit of ACMP_CTL register to disable analog comparator.
* \hideinitializer
*/
#define ACMP_DISABLE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_ACMPEN_Msk)
/**
* @brief This macro is used to get ACMP output value
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return ACMP output value
* @details This macro will return the ACMP output value.
* \hideinitializer
*/
#define ACMP_GET_OUTPUT(acmp, u32ChNum) (((acmp)->STATUS & (ACMP_STATUS_ACMPO0_Msk<<((u32ChNum))))?1:0)
/**
* @brief This macro is used to get ACMP interrupt flag
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return ACMP interrupt occurred (1) or not (0)
* @details This macro will return the ACMP interrupt flag.
* \hideinitializer
*/
#define ACMP_GET_INT_FLAG(acmp, u32ChNum) (((acmp)->STATUS & (ACMP_STATUS_ACMPIF0_Msk<<((u32ChNum))))?1:0)
/**
* @brief This macro is used to clear ACMP interrupt flag
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will write 1 to ACMPIFn bit of ACMP_STATUS register to clear interrupt flag.
* \hideinitializer
*/
#define ACMP_CLR_INT_FLAG(acmp, u32ChNum) ((acmp)->STATUS = (ACMP_STATUS_ACMPIF0_Msk<<((u32ChNum))))
/**
* @brief This macro is used to clear ACMP wake-up interrupt flag
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will write 1 to WKIFn bit of ACMP_STATUS register to clear interrupt flag.
* \hideinitializer
*/
#define ACMP_CLR_WAKEUP_INT_FLAG(acmp, u32ChNum) ((acmp)->STATUS = (ACMP_STATUS_WKIF0_Msk<<((u32ChNum))))
/**
* @brief This macro is used to enable ACMP wake-up function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set WKEN (ACMP_CTL[16]) to enable ACMP wake-up function.
* \hideinitializer
*/
#define ACMP_ENABLE_WAKEUP(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_WKEN_Msk)
/**
* @brief This macro is used to disable ACMP wake-up function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear WKEN (ACMP_CTL[16]) to disable ACMP wake-up function.
* \hideinitializer
*/
#define ACMP_DISABLE_WAKEUP(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_WKEN_Msk)
/**
* @brief This macro is used to select ACMP positive input pin
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @param[in] u32Pin Comparator positive pin selection. Including:
* - \ref ACMP_CTL_POSSEL_P0
* - \ref ACMP_CTL_POSSEL_P1
* - \ref ACMP_CTL_POSSEL_P2
* - \ref ACMP_CTL_POSSEL_P3
* @return None
* @details This macro will set POSSEL (ACMP_CTL[7:6]) to determine the comparator positive input pin.
* \hideinitializer
*/
#define ACMP_SELECT_P(acmp, u32ChNum, u32Pin) ((acmp)->CTL[(u32ChNum)] = ((acmp)->CTL[(u32ChNum)] & ~ACMP_CTL_POSSEL_Msk) | (u32Pin))
/**
* @brief This macro is used to enable ACMP filter function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set OUTSEL (ACMP_CTL[12]) to enable output filter function.
* \hideinitializer
*/
#define ACMP_ENABLE_FILTER(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_OUTSEL_Msk)
/**
* @brief This macro is used to disable ACMP filter function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear OUTSEL (ACMP_CTL[12]) to disable output filter function.
* \hideinitializer
*/
#define ACMP_DISABLE_FILTER(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_OUTSEL_Msk)
/**
* @brief This macro is used to set ACMP filter function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @param[in] u32Cnt is comparator filter count setting.
* - \ref ACMP_CTL_FILTSEL_OFF
* - \ref ACMP_CTL_FILTSEL_1PCLK
* - \ref ACMP_CTL_FILTSEL_2PCLK
* - \ref ACMP_CTL_FILTSEL_4PCLK
* - \ref ACMP_CTL_FILTSEL_8PCLK
* - \ref ACMP_CTL_FILTSEL_16PCLK
* - \ref ACMP_CTL_FILTSEL_32PCLK
* - \ref ACMP_CTL_FILTSEL_64PCLK
* @return None
* @details When ACMP output filter function is enabled, the output sampling count is determined by FILTSEL (ACMP_CTL[15:13]).
* \hideinitializer
*/
#define ACMP_SET_FILTER(acmp, u32ChNum, u32Cnt) ((acmp)->CTL[(u32ChNum)] = ((acmp)->CTL[(u32ChNum)] & ~ACMP_CTL_FILTSEL_Msk) | (u32Cnt))
/**
* @brief This macro is used to select comparator reference voltage
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32Level The comparator reference voltage setting.
* The formula is:
* comparator reference voltage = CRV source voltage x (1/6 + u32Level/24)
* The range of u32Level is 0 ~ 15.
* @return None
* @details When CRV is selected as ACMP negative input source, the CRV level is determined by CRVCTL (ACMP_VREF[3:0]).
* \hideinitializer
*/
#define ACMP_CRV_SEL(acmp, u32Level) ((acmp)->VREF = ((acmp)->VREF & ~ACMP_VREF_CRVCTL_Msk) | ((u32Level)<<ACMP_VREF_CRVCTL_Pos))
/**
* @brief This macro is used to select the source of CRV
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32Src is the source of CRV. Including:
* - \ref ACMP_VREF_CRVSSEL_VDDA
* - \ref ACMP_VREF_CRVSSEL_INTVREF
* @return None
* @details The source of CRV can be VDDA or internal reference voltage. The internal reference voltage level is determined by SYS_VREFCTL register.
* \hideinitializer
*/
#define ACMP_SELECT_CRV_SRC(acmp, u32Src) ((acmp)->VREF = ((acmp)->VREF & ~ACMP_VREF_CRVSSEL_Msk) | (u32Src))
/**
* @brief This macro is used to select ACMP interrupt condition
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @param[in] u32Cond Comparator interrupt condition selection. Including:
* - \ref ACMP_CTL_INTPOL_RF
* - \ref ACMP_CTL_INTPOL_R
* - \ref ACMP_CTL_INTPOL_F
* @return None
* @details The ACMP output interrupt condition can be rising edge, falling edge or any edge.
* \hideinitializer
*/
#define ACMP_SELECT_INT_COND(acmp, u32ChNum, u32Cond) ((acmp)->CTL[(u32ChNum)] = ((acmp)->CTL[(u32ChNum)] & ~ACMP_CTL_INTPOL_Msk) | (u32Cond))
/**
* @brief This macro is used to enable ACMP window latch mode
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set WLATEN (ACMP_CTL[17]) to enable ACMP window latch mode.
* When ACMP0/1_WLAT pin is at high level, ACMPO0/1 passes through window latch
* block; when ACMP0/1_WLAT pin is at low level, the output of window latch block,
* WLATOUT, is frozen.
* \hideinitializer
*/
#define ACMP_ENABLE_WINDOW_LATCH(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_WLATEN_Msk)
/**
* @brief This macro is used to disable ACMP window latch mode
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear WLATEN (ACMP_CTL[17]) to disable ACMP window latch mode.
* \hideinitializer
*/
#define ACMP_DISABLE_WINDOW_LATCH(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_WLATEN_Msk)
/**
* @brief This macro is used to enable ACMP window compare mode
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set WCMPSEL (ACMP_CTL[18]) to enable ACMP window compare mode.
* When window compare mode is enabled, user can connect the specific analog voltage
* source to either the positive inputs of both comparators or the negative inputs of
* both comparators. The upper bound and lower bound of the designated range are
* determined by the voltages applied to the other inputs of both comparators. If the
* output of a comparator is low and the other comparator outputs high, which means two
* comparators implies the upper and lower bound. User can directly monitor a specific
* analog voltage source via ACMPWO (ACMP_STATUS[16]).
* \hideinitializer
*/
#define ACMP_ENABLE_WINDOW_COMPARE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_WCMPSEL_Msk)
/**
* @brief This macro is used to disable ACMP window compare mode
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear WCMPSEL (ACMP_CTL[18]) to disable ACMP window compare mode.
* \hideinitializer
*/
#define ACMP_DISABLE_WINDOW_COMPARE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_WCMPSEL_Msk)
/* Function prototype declaration */
void ACMP_Open(ACMP_T *acmp, uint32_t u32ChNum, uint32_t u32NegSrc, uint32_t u32HysSel);
void ACMP_Close(ACMP_T *acmp, uint32_t u32ChNum);
/*@}*/ /* end of group M480_ACMP_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group M480_ACMP_Driver */
/*@}*/ /* end of group M480_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __ACMP_H__ */
/*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,703 @@
/**************************************************************************//**
* @file bpwm.c
* @version V1.00
* @brief M480 series BPWM driver source file
*
* @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "M480.h"
/** @addtogroup M480_Device_Driver M480 Device Driver
@{
*/
/** @addtogroup M480_BPWM_Driver BPWM Driver
@{
*/
/** @addtogroup M480_BPWM_EXPORTED_FUNCTIONS BPWM Exported Functions
@{
*/
/**
* @brief Configure BPWM capture and get the nearest unit time.
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32UnitTimeNsec The unit time of counter
* @param[in] u32CaptureEdge The condition to latch the counter. This parameter is not used
* @return The nearest unit time in nano second.
* @details This function is used to Configure BPWM capture and get the nearest unit time.
*/
uint32_t BPWM_ConfigCaptureChannel(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32UnitTimeNsec, uint32_t u32CaptureEdge)
{
uint32_t u32Src;
uint32_t u32PWMClockSrc;
uint32_t u32NearestUnitTimeNsec;
uint16_t u16Prescale = 1U, u16CNR = 0xFFFFU;
if(bpwm == BPWM0) {
u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_BPWM0SEL_Msk;
} else { /* (bpwm == BPWM1) */
u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_BPWM1SEL_Msk;
}
if(u32Src == 0U) {
/* clock source is from PLL clock */
u32PWMClockSrc = CLK_GetPLLClockFreq();
} else {
/* clock source is from PCLK */
SystemCoreClockUpdate();
if(bpwm == BPWM0) {
u32PWMClockSrc = CLK_GetPCLK0Freq();
} else {/* (bpwm == BPWM1) */
u32PWMClockSrc = CLK_GetPCLK1Freq();
}
}
u32PWMClockSrc /= 1000UL;
for(u16Prescale = 1U; u16Prescale <= 0x1000U; u16Prescale++) {
uint32_t u32Exit = 0U;
u32NearestUnitTimeNsec = (1000000UL * u16Prescale) / u32PWMClockSrc;
if(u32NearestUnitTimeNsec < u32UnitTimeNsec) {
if (u16Prescale == 0x1000U) { /* limit to the maximum unit time(nano second) */
u32Exit = 1U;
} else {
u32Exit = 0U;
}
if (!(1000000UL * (u16Prescale + 1UL) > (u32NearestUnitTimeNsec * u32PWMClockSrc))) {
u32Exit = 1U;
} else {
u32Exit = 0U;
}
} else {
u32Exit = 1U;
}
if (u32Exit == 1U) {
break;
} else {}
}
/* convert to real register value */
/* all channels share a prescaler */
u16Prescale -= 1U;
BPWM_SET_PRESCALER(bpwm, u32ChannelNum, u16Prescale);
/* set BPWM to down count type(edge aligned) */
(bpwm)->CTL1 = (1UL);
BPWM_SET_CNR(bpwm, u32ChannelNum, u16CNR);
return (u32NearestUnitTimeNsec);
}
/**
* @brief This function Configure BPWM generator and get the nearest frequency in edge aligned auto-reload mode
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32Frequency Target generator frequency
* @param[in] u32DutyCycle Target generator duty cycle percentage. Valid range are between 0 ~ 100. 10 means 10%, 20 means 20%...
* @return Nearest frequency clock in nano second
* @note Since all channels shares a prescaler. Call this API to configure BPWM frequency may affect
* existing frequency of other channel.
*/
uint32_t BPWM_ConfigOutputChannel(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Frequency, uint32_t u32DutyCycle)
{
uint32_t u32Src;
uint32_t u32PWMClockSrc;
uint32_t i;
uint32_t u32Prescale = 1U, u32CNR = 0xFFFFU;
if(bpwm == BPWM0) {
u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_BPWM0SEL_Msk;
} else { /* (bpwm == BPWM1) */
u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_BPWM1SEL_Msk;
}
if(u32Src == 0U) {
/* clock source is from PLL clock */
u32PWMClockSrc = CLK_GetPLLClockFreq();
} else {
/* clock source is from PCLK */
SystemCoreClockUpdate();
if(bpwm == BPWM0) {
u32PWMClockSrc = CLK_GetPCLK0Freq();
} else { /* (bpwm == BPWM1) */
u32PWMClockSrc = CLK_GetPCLK1Freq();
}
}
for(u32Prescale = 1U; u32Prescale < 0xFFFU; u32Prescale++) { /* prescale could be 0~0xFFF */
i = (u32PWMClockSrc / u32Frequency) / u32Prescale;
/* If target value is larger than CNR, need to use a larger prescaler */
if(i < (0x10000U)) {
u32CNR = i;
break;
}
}
/* Store return value here 'cos we're gonna change u16Prescale & u16CNR to the real value to fill into register */
i = u32PWMClockSrc / (u32Prescale * u32CNR);
/* convert to real register value */
/* all channels share a prescaler */
u32Prescale -= 1U;
BPWM_SET_PRESCALER(bpwm, u32ChannelNum, u32Prescale);
/* set BPWM to down count type(edge aligned) */
(bpwm)->CTL1 = (1UL);
u32CNR -= 1U;
BPWM_SET_CNR(bpwm, u32ChannelNum, u32CNR);
if(u32DutyCycle) {
BPWM_SET_CMR(bpwm, u32ChannelNum, u32DutyCycle * (u32CNR + 1UL) / 100UL - 1UL);
(bpwm)->WGCTL0 &= ~((BPWM_WGCTL0_PRDPCTLn_Msk | BPWM_WGCTL0_ZPCTLn_Msk) << (u32ChannelNum * 2U));
(bpwm)->WGCTL0 |= (BPWM_OUTPUT_LOW << ((u32ChannelNum * (2U)) + (uint32_t)BPWM_WGCTL0_PRDPCTLn_Pos));
(bpwm)->WGCTL1 &= ~((BPWM_WGCTL1_CMPDCTLn_Msk | BPWM_WGCTL1_CMPUCTLn_Msk) << (u32ChannelNum * 2U));
(bpwm)->WGCTL1 |= (BPWM_OUTPUT_HIGH << (u32ChannelNum * (2U) + (uint32_t)BPWM_WGCTL1_CMPDCTLn_Pos));
} else {
BPWM_SET_CMR(bpwm, u32ChannelNum, 0U);
(bpwm)->WGCTL0 &= ~((BPWM_WGCTL0_PRDPCTLn_Msk | BPWM_WGCTL0_ZPCTLn_Msk) << (u32ChannelNum * 2U));
(bpwm)->WGCTL0 |= (BPWM_OUTPUT_LOW << (u32ChannelNum * 2U + (uint32_t)BPWM_WGCTL0_ZPCTLn_Pos));
(bpwm)->WGCTL1 &= ~((BPWM_WGCTL1_CMPDCTLn_Msk | BPWM_WGCTL1_CMPUCTLn_Msk) << (u32ChannelNum * 2U));
(bpwm)->WGCTL1 |= (BPWM_OUTPUT_HIGH << (u32ChannelNum * 2U + (uint32_t)BPWM_WGCTL1_CMPDCTLn_Pos));
}
return(i);
}
/**
* @brief Start BPWM module
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelMask Combination of enabled channels. This parameter is not used.
* @return None
* @details This function is used to start BPWM module.
* @note All channels share one counter.
*/
void BPWM_Start(BPWM_T *bpwm, uint32_t u32ChannelMask)
{
(bpwm)->CNTEN = BPWM_CNTEN_CNTEN0_Msk;
}
/**
* @brief Stop BPWM module
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelMask Combination of enabled channels. This parameter is not used.
* @return None
* @details This function is used to stop BPWM module.
* @note All channels share one period.
*/
void BPWM_Stop(BPWM_T *bpwm, uint32_t u32ChannelMask)
{
(bpwm)->PERIOD = 0U;
}
/**
* @brief Stop BPWM generation immediately by clear channel enable bit
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelMask Combination of enabled channels. This parameter is not used.
* @return None
* @details This function is used to stop BPWM generation immediately by clear channel enable bit.
* @note All channels share one counter.
*/
void BPWM_ForceStop(BPWM_T *bpwm, uint32_t u32ChannelMask)
{
(bpwm)->CNTEN &= ~BPWM_CNTEN_CNTEN0_Msk;
}
/**
* @brief Enable selected channel to trigger EADC
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32Condition The condition to trigger EADC. Combination of following conditions:
* - \ref BPWM_TRIGGER_EADC_EVEN_ZERO_POINT
* - \ref BPWM_TRIGGER_EADC_EVEN_PERIOD_POINT
* - \ref BPWM_TRIGGER_EADC_EVEN_ZERO_OR_PERIOD_POINT
* - \ref BPWM_TRIGGER_EADC_EVEN_CMP_UP_COUNT_POINT
* - \ref BPWM_TRIGGER_EADC_EVEN_CMP_DOWN_COUNT_POINT
* - \ref BPWM_TRIGGER_EADC_ODD_CMP_UP_COUNT_POINT
* - \ref BPWM_TRIGGER_EADC_ODD_CMP_DOWN_COUNT_POINT
* @return None
* @details This function is used to enable selected channel to trigger EADC
*/
void BPWM_EnableEADCTrigger(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Condition)
{
if(u32ChannelNum < 4U) {
(bpwm)->EADCTS0 &= ~((BPWM_EADCTS0_TRGSEL0_Msk) << (u32ChannelNum * 8U));
(bpwm)->EADCTS0 |= ((BPWM_EADCTS0_TRGEN0_Msk | u32Condition) << (u32ChannelNum * 8U));
} else {
(bpwm)->EADCTS1 &= ~((BPWM_EADCTS1_TRGSEL4_Msk) << ((u32ChannelNum - 4U) * 8U));
(bpwm)->EADCTS1 |= ((BPWM_EADCTS1_TRGEN4_Msk | u32Condition) << ((u32ChannelNum - 4U) * 8U));
}
}
/**
* @brief Disable selected channel to trigger EADC
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~3
* @return None
* @details This function is used to disable selected channel to trigger EADC
*/
void BPWM_DisableEADCTrigger(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
if(u32ChannelNum < 4U) {
(bpwm)->EADCTS0 &= ~(BPWM_EADCTS0_TRGEN0_Msk << (u32ChannelNum * 8U));
} else {
(bpwm)->EADCTS1 &= ~(BPWM_EADCTS1_TRGEN4_Msk << ((u32ChannelNum - 4U) * 8U));
}
}
/**
* @brief Clear selected channel trigger EADC flag
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32Condition This parameter is not used
* @return None
* @details This function is used to clear selected channel trigger EADC flag
*/
void BPWM_ClearEADCTriggerFlag(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Condition)
{
(bpwm)->STATUS = (BPWM_STATUS_EADCTRGn_Msk << u32ChannelNum);
}
/**
* @brief Get selected channel trigger EADC flag
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @retval 0 The specified channel trigger EADC to start of conversion flag is not set
* @retval 1 The specified channel trigger EADC to start of conversion flag is set
* @details This function is used to get BPWM trigger EADC to start of conversion flag for specified channel
*/
uint32_t BPWM_GetEADCTriggerFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
return (((bpwm)->STATUS & (BPWM_STATUS_EADCTRGn_Msk << u32ChannelNum)) ? 1UL : 0UL);
}
/**
* @brief Enable capture of selected channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
* Bit 0 is channel 0, bit 1 is channel 1...
* @return None
* @details This function is used to enable capture of selected channel(s)
*/
void BPWM_EnableCapture(BPWM_T *bpwm, uint32_t u32ChannelMask)
{
(bpwm)->CAPINEN |= u32ChannelMask;
(bpwm)->CAPCTL |= u32ChannelMask;
}
/**
* @brief Disable capture of selected channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
* Bit 0 is channel 0, bit 1 is channel 1...
* @return None
* @details This function is used to disable capture of selected channel(s)
*/
void BPWM_DisableCapture(BPWM_T *bpwm, uint32_t u32ChannelMask)
{
(bpwm)->CAPINEN &= ~u32ChannelMask;
(bpwm)->CAPCTL &= ~u32ChannelMask;
}
/**
* @brief Enables BPWM output generation of selected channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
* Set bit 0 to 1 enables channel 0 output, set bit 1 to 1 enables channel 1 output...
* @return None
* @details This function is used to enables BPWM output generation of selected channel(s)
*/
void BPWM_EnableOutput(BPWM_T *bpwm, uint32_t u32ChannelMask)
{
(bpwm)->POEN |= u32ChannelMask;
}
/**
* @brief Disables BPWM output generation of selected channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel
* Set bit 0 to 1 disables channel 0 output, set bit 1 to 1 disables channel 1 output...
* @return None
* @details This function is used to disables BPWM output generation of selected channel(s)
*/
void BPWM_DisableOutput(BPWM_T *bpwm, uint32_t u32ChannelMask)
{
(bpwm)->POEN &= ~u32ChannelMask;
}
/**
* @brief Enable capture interrupt of selected channel.
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32Edge Rising or falling edge to latch counter.
* - \ref BPWM_CAPTURE_INT_RISING_LATCH
* - \ref BPWM_CAPTURE_INT_FALLING_LATCH
* @return None
* @details This function is used to enable capture interrupt of selected channel.
*/
void BPWM_EnableCaptureInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Edge)
{
(bpwm)->CAPIEN |= (u32Edge << u32ChannelNum);
}
/**
* @brief Disable capture interrupt of selected channel.
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32Edge Rising or falling edge to latch counter.
* - \ref BPWM_CAPTURE_INT_RISING_LATCH
* - \ref BPWM_CAPTURE_INT_FALLING_LATCH
* @return None
* @details This function is used to disable capture interrupt of selected channel.
*/
void BPWM_DisableCaptureInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Edge)
{
(bpwm)->CAPIEN &= ~(u32Edge << u32ChannelNum);
}
/**
* @brief Clear capture interrupt of selected channel.
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32Edge Rising or falling edge to latch counter.
* - \ref BPWM_CAPTURE_INT_RISING_LATCH
* - \ref BPWM_CAPTURE_INT_FALLING_LATCH
* @return None
* @details This function is used to clear capture interrupt of selected channel.
*/
void BPWM_ClearCaptureIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Edge)
{
(bpwm)->CAPIF = (u32Edge << u32ChannelNum);
}
/**
* @brief Get capture interrupt of selected channel.
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @retval 0 No capture interrupt
* @retval 1 Rising edge latch interrupt
* @retval 2 Falling edge latch interrupt
* @retval 3 Rising and falling latch interrupt
* @details This function is used to get capture interrupt of selected channel.
*/
uint32_t BPWM_GetCaptureIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
return (((((bpwm)->CAPIF & (BPWM_CAPIF_CAPFIFn_Msk << u32ChannelNum)) ? 1UL : 0UL) << 1) | \
(((bpwm)->CAPIF & (BPWM_CAPIF_CAPRIFn_Msk << u32ChannelNum)) ? 1UL : 0UL));
}
/**
* @brief Enable duty interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32IntDutyType Duty interrupt type, could be either
* - \ref BPWM_DUTY_INT_DOWN_COUNT_MATCH_CMP
* - \ref BPWM_DUTY_INT_UP_COUNT_MATCH_CMP
* @return None
* @details This function is used to enable duty interrupt of selected channel.
*/
void BPWM_EnableDutyInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType)
{
(bpwm)->INTEN |= (u32IntDutyType << u32ChannelNum);
}
/**
* @brief Disable duty interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @return None
* @details This function is used to disable duty interrupt of selected channel
*/
void BPWM_DisableDutyInt(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->INTEN &= ~((uint32_t)(BPWM_DUTY_INT_DOWN_COUNT_MATCH_CMP | BPWM_DUTY_INT_UP_COUNT_MATCH_CMP) << u32ChannelNum);
}
/**
* @brief Clear duty interrupt flag of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @return None
* @details This function is used to clear duty interrupt flag of selected channel
*/
void BPWM_ClearDutyIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->INTSTS = (BPWM_INTSTS_CMPUIFn_Msk | BPWM_INTSTS_CMPDIFn_Msk) << u32ChannelNum;
}
/**
* @brief Get duty interrupt flag of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @return Duty interrupt flag of specified channel
* @retval 0 Duty interrupt did not occur
* @retval 1 Duty interrupt occurred
* @details This function is used to get duty interrupt flag of selected channel
*/
uint32_t BPWM_GetDutyIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
return ((((bpwm)->INTSTS & ((BPWM_INTSTS_CMPDIFn_Msk | BPWM_INTSTS_CMPUIFn_Msk) << u32ChannelNum))) ? 1UL : 0UL);
}
/**
* @brief Enable period interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @param[in] u32IntPeriodType Period interrupt type. This parameter is not used.
* @return None
* @details This function is used to enable period interrupt of selected channel.
* @note All channels share channel 0's setting.
*/
void BPWM_EnablePeriodInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType)
{
(bpwm)->INTEN |= BPWM_INTEN_PIEN0_Msk;
}
/**
* @brief Disable period interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return None
* @details This function is used to disable period interrupt of selected channel.
* @note All channels share channel 0's setting.
*/
void BPWM_DisablePeriodInt(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->INTEN &= ~BPWM_INTEN_PIEN0_Msk;
}
/**
* @brief Clear period interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return None
* @details This function is used to clear period interrupt of selected channel
* @note All channels share channel 0's setting.
*/
void BPWM_ClearPeriodIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->INTSTS = BPWM_INTSTS_PIF0_Msk;
}
/**
* @brief Get period interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return Period interrupt flag of specified channel
* @retval 0 Period interrupt did not occur
* @retval 1 Period interrupt occurred
* @details This function is used to get period interrupt of selected channel
* @note All channels share channel 0's setting.
*/
uint32_t BPWM_GetPeriodIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
return (((bpwm)->INTSTS & BPWM_INTSTS_PIF0_Msk) ? 1UL : 0UL);
}
/**
* @brief Enable zero interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return None
* @details This function is used to enable zero interrupt of selected channel.
* @note All channels share channel 0's setting.
*/
void BPWM_EnableZeroInt(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->INTEN |= BPWM_INTEN_ZIEN0_Msk;
}
/**
* @brief Disable zero interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return None
* @details This function is used to disable zero interrupt of selected channel.
* @note All channels share channel 0's setting.
*/
void BPWM_DisableZeroInt(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->INTEN &= ~BPWM_INTEN_ZIEN0_Msk;
}
/**
* @brief Clear zero interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return None
* @details This function is used to clear zero interrupt of selected channel.
* @note All channels share channel 0's setting.
*/
void BPWM_ClearZeroIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->INTSTS = BPWM_INTSTS_ZIF0_Msk;
}
/**
* @brief Get zero interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return zero interrupt flag of specified channel
* @retval 0 zero interrupt did not occur
* @retval 1 zero interrupt occurred
* @details This function is used to get zero interrupt of selected channel.
* @note All channels share channel 0's setting.
*/
uint32_t BPWM_GetZeroIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
return (((bpwm)->INTSTS & BPWM_INTSTS_ZIF0_Msk) ? 1UL : 0UL);
}
/**
* @brief Enable load mode of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32LoadMode BPWM counter loading mode.
* - \ref BPWM_LOAD_MODE_IMMEDIATE
* - \ref BPWM_LOAD_MODE_CENTER
* @return None
* @details This function is used to enable load mode of selected channel.
*/
void BPWM_EnableLoadMode(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32LoadMode)
{
(bpwm)->CTL0 |= (u32LoadMode << u32ChannelNum);
}
/**
* @brief Disable load mode of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32LoadMode PWM counter loading mode.
* - \ref BPWM_LOAD_MODE_IMMEDIATE
* - \ref BPWM_LOAD_MODE_CENTER
* @return None
* @details This function is used to disable load mode of selected channel.
*/
void BPWM_DisableLoadMode(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32LoadMode)
{
(bpwm)->CTL0 &= ~(u32LoadMode << u32ChannelNum);
}
/**
* @brief Enable BPWM SYNC input pin inverse function
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @param[in] u32ClkSrcSel BPWM external clock source.
* - \ref BPWM_CLKSRC_BPWM_CLK
* - \ref BPWM_CLKSRC_TIMER0
* - \ref BPWM_CLKSRC_TIMER1
* - \ref BPWM_CLKSRC_TIMER2
* - \ref BPWM_CLKSRC_TIMER3
* @return None
* @details This function is used to enable BPWM SYNC input pin inverse function.
* @note All channels share channel 0's setting.
*/
void BPWM_SetClockSource(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32ClkSrcSel)
{
(bpwm)->CLKSRC = (u32ClkSrcSel);
}
/**
* @brief Get the time-base counter reached its maximum value flag of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return Count to max interrupt flag of specified channel
* @retval 0 Count to max interrupt did not occur
* @retval 1 Count to max interrupt occurred
* @details This function is used to get the time-base counter reached its maximum value flag of selected channel.
* @note All channels share channel 0's setting.
*/
uint32_t BPWM_GetWrapAroundFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
return (((bpwm)->STATUS & BPWM_STATUS_CNTMAX0_Msk) ? 1UL : 0UL);
}
/**
* @brief Clear the time-base counter reached its maximum value flag of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return None
* @details This function is used to clear the time-base counter reached its maximum value flag of selected channel.
* @note All channels share channel 0's setting.
*/
void BPWM_ClearWrapAroundFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->STATUS = BPWM_STATUS_CNTMAX0_Msk;
}
/*@}*/ /* end of group M480_BPWM_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group M480_BPWM_Driver */
/*@}*/ /* end of group M480_Device_Driver */
/*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,319 @@
/**************************************************************************//**
* @file bpwm.h
* @version V1.00
* @brief M480 series PWM driver header file
*
* @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __BPWM_H__
#define __BPWM_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup M480_Device_Driver M480 Device Driver
@{
*/
/** @addtogroup M480_BPWM_Driver BPWM Driver
@{
*/
/** @addtogroup M480_BPWM_EXPORTED_CONSTANTS BPWM Exported Constants
@{
*/
#define BPWM_CHANNEL_NUM (6) /*!< BPWM channel number \hideinitializer */
#define BPWM_CH_0_MASK (0x1UL) /*!< BPWM channel 0 mask \hideinitializer */
#define BPWM_CH_1_MASK (0x2UL) /*!< BPWM channel 1 mask \hideinitializer */
#define BPWM_CH_2_MASK (0x4UL) /*!< BPWM channel 2 mask \hideinitializer */
#define BPWM_CH_3_MASK (0x8UL) /*!< BPWM channel 3 mask \hideinitializer */
#define BPWM_CH_4_MASK (0x10UL) /*!< BPWM channel 4 mask \hideinitializer */
#define BPWM_CH_5_MASK (0x20UL) /*!< BPWM channel 5 mask \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Counter Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_UP_COUNTER (0UL) /*!< Up counter type \hideinitializer */
#define BPWM_DOWN_COUNTER (1UL) /*!< Down counter type \hideinitializer */
#define BPWM_UP_DOWN_COUNTER (2UL) /*!< Up-Down counter type \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Aligned Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_EDGE_ALIGNED (1UL) /*!< BPWM working in edge aligned type(down count) \hideinitializer */
#define BPWM_CENTER_ALIGNED (2UL) /*!< BPWM working in center aligned type \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Output Level Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_OUTPUT_NOTHING (0UL) /*!< BPWM output nothing \hideinitializer */
#define BPWM_OUTPUT_LOW (1UL) /*!< BPWM output low \hideinitializer */
#define BPWM_OUTPUT_HIGH (2UL) /*!< BPWM output high \hideinitializer */
#define BPWM_OUTPUT_TOGGLE (3UL) /*!< BPWM output toggle \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Trigger Source Select Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_TRIGGER_EADC_EVEN_ZERO_POINT (0UL) /*!< BPWM trigger EADC while counter of even channel matches zero point \hideinitializer */
#define BPWM_TRIGGER_EADC_EVEN_PERIOD_POINT (1UL) /*!< BPWM trigger EADC while counter of even channel matches period point \hideinitializer */
#define BPWM_TRIGGER_EADC_EVEN_ZERO_OR_PERIOD_POINT (2UL) /*!< BPWM trigger EADC while counter of even channel matches zero or period point \hideinitializer */
#define BPWM_TRIGGER_EADC_EVEN_CMP_UP_COUNT_POINT (3UL) /*!< BPWM trigger EADC while counter of even channel matches up count to comparator point \hideinitializer */
#define BPWM_TRIGGER_EADC_EVEN_CMP_DOWN_COUNT_POINT (4UL) /*!< BPWM trigger EADC while counter of even channel matches down count to comparator point \hideinitializer */
#define BPWM_TRIGGER_EADC_ODD_CMP_UP_COUNT_POINT (8UL) /*!< BPWM trigger EADC while counter of odd channel matches up count to comparator point \hideinitializer */
#define BPWM_TRIGGER_EADC_ODD_CMP_DOWN_COUNT_POINT (9UL) /*!< BPWM trigger EADC while counter of odd channel matches down count to comparator point \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Capture Control Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_CAPTURE_INT_RISING_LATCH (1UL) /*!< BPWM capture interrupt if channel has rising transition \hideinitializer */
#define BPWM_CAPTURE_INT_FALLING_LATCH (0x100UL) /*!< BPWM capture interrupt if channel has falling transition \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Duty Interrupt Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_DUTY_INT_DOWN_COUNT_MATCH_CMP (1 << BPWM_INTEN_CMPDIENn_Pos) /*!< BPWM duty interrupt triggered if down count match comparator \hideinitializer */
#define BPWM_DUTY_INT_UP_COUNT_MATCH_CMP (1 << BPWM_INTEN_CMPUIENn_Pos) /*!< BPWM duty interrupt triggered if up down match comparator \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Load Mode Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_LOAD_MODE_IMMEDIATE (1 << BPWM_CTL0_IMMLDENn_Pos) /*!< BPWM immediately load mode \hideinitializer */
#define BPWM_LOAD_MODE_CENTER (1 << BPWM_CTL0_CTRLDn_Pos) /*!< BPWM center load mode \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Clock Source Select Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_CLKSRC_BPWM_CLK (0UL) /*!< BPWM Clock source selects to BPWM0_CLK or BPWM1_CLK \hideinitializer */
#define BPWM_CLKSRC_TIMER0 (1UL) /*!< BPWM Clock source selects to TIMER0 overflow \hideinitializer */
#define BPWM_CLKSRC_TIMER1 (2UL) /*!< BPWM Clock source selects to TIMER1 overflow \hideinitializer */
#define BPWM_CLKSRC_TIMER2 (3UL) /*!< BPWM Clock source selects to TIMER2 overflow \hideinitializer */
#define BPWM_CLKSRC_TIMER3 (4UL) /*!< BPWM Clock source selects to TIMER3 overflow \hideinitializer */
/*@}*/ /* end of group M480_BPWM_EXPORTED_CONSTANTS */
/** @addtogroup M480_BPWM_EXPORTED_FUNCTIONS BPWM Exported Functions
@{
*/
/**
* @brief Enable timer synchronous mode of specified channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelMask Combination of enabled channels. This parameter is not used.
* @return None
* @details This macro is used to enable timer synchronous mode of specified channel(s).
* @note All channels share channel 0's setting.
* \hideinitializer
*/
#define BPWM_ENABLE_TIMER_SYNC(bpwm, u32ChannelMask) ((bpwm)->SSCTL |= BPWM_SSCTL_SSEN0_Msk)
/**
* @brief Disable timer synchronous mode of specified channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelMask Combination of enabled channels. This parameter is not used.
* @return None
* @details This macro is used to disable timer synchronous mode of specified channel(s).
* @note All channels share channel 0's setting.
* \hideinitializer
*/
#define BPWM_DISABLE_TIMER_SYNC(bpwm, u32ChannelMask) ((bpwm)->SSCTL &= ~BPWM_SSCTL_SSEN0_Msk)
/**
* @brief This macro enable output inverter of specified channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel
* Bit 0 represents channel 0, bit 1 represents channel 1...
* @return None
* \hideinitializer
*/
#define BPWM_ENABLE_OUTPUT_INVERTER(bpwm, u32ChannelMask) ((bpwm)->POLCTL = (u32ChannelMask))
/**
* @brief This macro get captured rising data
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @return None
* \hideinitializer
*/
#define BPWM_GET_CAPTURE_RISING_DATA(bpwm, u32ChannelNum) (*(__IO uint32_t *) (&((bpwm)->RCAPDAT0) + 2 * (u32ChannelNum)))
/**
* @brief This macro get captured falling data
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @return None
* \hideinitializer
*/
#define BPWM_GET_CAPTURE_FALLING_DATA(bpwm, u32ChannelNum) (*(__IO uint32_t *) (&((bpwm)->FCAPDAT0) + 2 * (u32ChannelNum)))
/**
* @brief This macro mask output logic to high or low
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel
* Bit 0 represents channel 0, bit 1 represents channel 1...
* @param[in] u32LevelMask Output logic to high or low
* @return None
* @details This macro is used to mask output logic to high or low of specified channel(s).
* @note If u32ChannelMask parameter is 0, then mask function will be disabled.
* \hideinitializer
*/
#define BPWM_MASK_OUTPUT(bpwm, u32ChannelMask, u32LevelMask) \
{ \
(bpwm)->MSKEN = (u32ChannelMask); \
(bpwm)->MSK = (u32LevelMask); \
}
/**
* @brief This macro set the prescaler of all channels
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @param[in] u32Prescaler Clock prescaler of specified channel. Valid values are between 1 ~ 0xFFF
* @return None
* \hideinitializer
*/
#define BPWM_SET_PRESCALER(bpwm, u32ChannelNum, u32Prescaler) ((bpwm)->CLKPSC = (u32Prescaler))
/**
* @brief This macro set the duty of the selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32CMR Duty of specified channel. Valid values are between 0~0xFFFF
* @return None
* @note This new setting will take effect on next BPWM period
* \hideinitializer
*/
#define BPWM_SET_CMR(bpwm, u32ChannelNum, u32CMR) ((bpwm)->CMPDAT[(u32ChannelNum)] = (u32CMR))
/**
* @brief This macro set the period of all channels
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @param[in] u32CNR Period of specified channel. Valid values are between 0~0xFFFF
* @return None
* @note This new setting will take effect on next BPWM period
* @note BPWM counter will stop if period length set to 0
* \hideinitializer
*/
#define BPWM_SET_CNR(bpwm, u32ChannelNum, u32CNR) ((bpwm)->PERIOD = (u32CNR))
/**
* @brief This macro set the BPWM aligned type
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelMask Combination of enabled channels. This parameter is not used.
* @param[in] u32AlignedType BPWM aligned type, valid values are:
* - \ref BPWM_EDGE_ALIGNED
* - \ref BPWM_CENTER_ALIGNED
* @return None
* @note All channels share channel 0's setting.
* \hideinitializer
*/
#define BPWM_SET_ALIGNED_TYPE(bpwm, u32ChannelMask, u32AlignedType) ((bpwm)->CTL1 = (u32AlignedType))
/**
* @brief Clear counter of channel 0
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelMask Combination of enabled channels. This parameter is not used.
* @return None
* @details This macro is used to clear counter of channel 0
* \hideinitializer
*/
#define BPWM_CLR_COUNTER(bpwm, u32ChannelMask) ((bpwm)->CNTCLR = (BPWM_CNTCLR_CNTCLR0_Msk))
/**
* @brief Set output level at zero, compare up, period(center) and compare down of specified channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel
* Bit 0 represents channel 0, bit 1 represents channel 1...
* @param[in] u32ZeroLevel output level at zero point, valid values are:
* - \ref BPWM_OUTPUT_NOTHING
* - \ref BPWM_OUTPUT_LOW
* - \ref BPWM_OUTPUT_HIGH
* - \ref BPWM_OUTPUT_TOGGLE
* @param[in] u32CmpUpLevel output level at compare up point, valid values are:
* - \ref BPWM_OUTPUT_NOTHING
* - \ref BPWM_OUTPUT_LOW
* - \ref BPWM_OUTPUT_HIGH
* - \ref BPWM_OUTPUT_TOGGLE
* @param[in] u32PeriodLevel output level at period(center) point, valid values are:
* - \ref BPWM_OUTPUT_NOTHING
* - \ref BPWM_OUTPUT_LOW
* - \ref BPWM_OUTPUT_HIGH
* - \ref BPWM_OUTPUT_TOGGLE
* @param[in] u32CmpDownLevel output level at compare down point, valid values are:
* - \ref BPWM_OUTPUT_NOTHING
* - \ref BPWM_OUTPUT_LOW
* - \ref BPWM_OUTPUT_HIGH
* - \ref BPWM_OUTPUT_TOGGLE
* @return None
* @details This macro is used to Set output level at zero, compare up, period(center) and compare down of specified channel(s)
* \hideinitializer
*/
#define BPWM_SET_OUTPUT_LEVEL(bpwm, u32ChannelMask, u32ZeroLevel, u32CmpUpLevel, u32PeriodLevel, u32CmpDownLevel) \
do{ \
int i; \
for(i = 0; i < 6; i++) { \
if((u32ChannelMask) & (1 << i)) { \
(bpwm)->WGCTL0 = (((bpwm)->WGCTL0 & ~(3UL << (2 * i))) | ((u32ZeroLevel) << (2 * i))); \
(bpwm)->WGCTL0 = (((bpwm)->WGCTL0 & ~(3UL << (BPWM_WGCTL0_PRDPCTLn_Pos + (2 * i)))) | ((u32PeriodLevel) << (BPWM_WGCTL0_PRDPCTLn_Pos + (2 * i)))); \
(bpwm)->WGCTL1 = (((bpwm)->WGCTL1 & ~(3UL << (2 * i))) | ((u32CmpUpLevel) << (2 * i))); \
(bpwm)->WGCTL1 = (((bpwm)->WGCTL1 & ~(3UL << (BPWM_WGCTL1_CMPDCTLn_Pos + (2 * i)))) | ((u32CmpDownLevel) << (BPWM_WGCTL1_CMPDCTLn_Pos + (2 * i)))); \
} \
} \
}while(0)
/*---------------------------------------------------------------------------------------------------------*/
/* Define BPWM functions prototype */
/*---------------------------------------------------------------------------------------------------------*/
uint32_t BPWM_ConfigCaptureChannel(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32UnitTimeNsec, uint32_t u32CaptureEdge);
uint32_t BPWM_ConfigOutputChannel(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Frequency, uint32_t u32DutyCycle);
void BPWM_Start(BPWM_T *bpwm, uint32_t u32ChannelMask);
void BPWM_Stop(BPWM_T *bpwm, uint32_t u32ChannelMask);
void BPWM_ForceStop(BPWM_T *bpwm, uint32_t u32ChannelMask);
void BPWM_EnableEADCTrigger(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Condition);
void BPWM_DisableEADCTrigger(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_ClearEADCTriggerFlag(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Condition);
uint32_t BPWM_GetEADCTriggerFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_EnableCapture(BPWM_T *bpwm, uint32_t u32ChannelMask);
void BPWM_DisableCapture(BPWM_T *bpwm, uint32_t u32ChannelMask);
void BPWM_EnableOutput(BPWM_T *bpwm, uint32_t u32ChannelMask);
void BPWM_DisableOutput(BPWM_T *bpwm, uint32_t u32ChannelMask);
void BPWM_EnableCaptureInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Edge);
void BPWM_DisableCaptureInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Edge);
void BPWM_ClearCaptureIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Edge);
uint32_t BPWM_GetCaptureIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_EnableDutyInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType);
void BPWM_DisableDutyInt(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_ClearDutyIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
uint32_t BPWM_GetDutyIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_EnablePeriodInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType);
void BPWM_DisablePeriodInt(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_ClearPeriodIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
uint32_t BPWM_GetPeriodIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_EnableZeroInt(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_DisableZeroInt(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_ClearZeroIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
uint32_t BPWM_GetZeroIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_EnableLoadMode(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32LoadMode);
void BPWM_DisableLoadMode(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32LoadMode);
void BPWM_SetClockSource(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32ClkSrcSel);
uint32_t BPWM_GetWrapAroundFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_ClearWrapAroundFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
/*@}*/ /* end of group M480_BPWM_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group M480_BPWM_Driver */
/*@}*/ /* end of group M480_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __BPWM_H__ */
/*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,180 @@
/**************************************************************************//**
* @file can.h
* @version V2.00
* @brief M480 Series CAN Driver Header File
*
* @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#ifndef __CAN_H__
#define __CAN_H__
#include "M480.h"
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup M480_Device_Driver M480 Device Driver
@{
*/
/** @addtogroup M480_CAN_Driver CAN Driver
@{
*/
/** @addtogroup M480_CAN_EXPORTED_CONSTANTS CAN Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* CAN Test Mode Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define CAN_NORMAL_MODE 0ul /*!< CAN select normal mode \hideinitializer */
#define CAN_BASIC_MODE 1ul /*!< CAN select basic mode \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Message ID Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define CAN_STD_ID 0ul /*!< CAN select standard ID \hideinitializer */
#define CAN_EXT_ID 1ul /*!< CAN select extended ID \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Message Frame Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define CAN_REMOTE_FRAME 0ul /*!< CAN frame select remote frame \hideinitializer */
#define CAN_DATA_FRAME 1ul /*!< CAN frame select data frame \hideinitializer */
/*@}*/ /* end of group M480_CAN_EXPORTED_CONSTANTS */
/** @addtogroup M480_CAN_EXPORTED_STRUCTS CAN Exported Structs
@{
*/
/**
* @details CAN message structure
*/
typedef struct {
uint32_t IdType; /*!< ID type */
uint32_t FrameType; /*!< Frame type */
uint32_t Id; /*!< Message ID */
uint8_t DLC; /*!< Data length */
uint8_t Data[8]; /*!< Data */
} STR_CANMSG_T;
/**
* @details CAN mask message structure
*/
typedef struct {
uint8_t u8Xtd; /*!< Extended ID */
uint8_t u8Dir; /*!< Direction */
uint32_t u32Id; /*!< Message ID */
uint8_t u8IdType; /*!< ID type*/
} STR_CANMASK_T;
/*@}*/ /* end of group M480_CAN_EXPORTED_STRUCTS */
/** @cond HIDDEN_SYMBOLS */
#define MSG(id) (id)
/** @endcond HIDDEN_SYMBOLS */
/** @addtogroup M480_CAN_EXPORTED_FUNCTIONS CAN Exported Functions
@{
*/
/**
* @brief Get interrupt status.
*
* @param[in] can The base address of can module.
*
* @return CAN module status register value.
*
* @details Status Interrupt is generated by bits BOff (CAN_STATUS[7]), EWarn (CAN_STATUS[6]),
* EPass (CAN_STATUS[5]), RxOk (CAN_STATUS[4]), TxOk (CAN_STATUS[3]), and LEC (CAN_STATUS[2:0]).
* \hideinitializer
*/
#define CAN_GET_INT_STATUS(can) ((can)->STATUS)
/**
* @brief Get specified interrupt pending status.
*
* @param[in] can The base address of can module.
*
* @return The source of the interrupt.
*
* @details If several interrupts are pending, the CAN Interrupt Register will point to the pending interrupt
* with the highest priority, disregarding their chronological order.
* \hideinitializer
*/
#define CAN_GET_INT_PENDING_STATUS(can) ((can)->IIDR)
/**
* @brief Disable wake-up function.
*
* @param[in] can The base address of can module.
*
* @return None
*
* @details The macro is used to disable wake-up function.
* \hideinitializer
*/
#define CAN_DISABLE_WAKEUP(can) ((can)->WU_EN = 0ul)
/**
* @brief Enable wake-up function.
*
* @param[in] can The base address of can module.
*
* @return None
*
* @details User can wake-up system when there is a falling edge in the CAN_Rx pin.
* \hideinitializer
*/
#define CAN_ENABLE_WAKEUP(can) ((can)->WU_EN = CAN_WU_EN_WAKUP_EN_Msk)
/**
* @brief Get specified Message Object new data into bit value.
*
* @param[in] can The base address of can module.
* @param[in] u32MsgNum Specified Message Object number, valid value are from 0 to 31.
*
* @return Specified Message Object new data into bit value.
*
* @details The NewDat bit (CAN_IFn_MCON[15]) of a specific Message Object can be set/reset by the software through the IFn Message Interface Registers
* or by the Message Handler after reception of a Data Frame or after a successful transmission.
* \hideinitializer
*/
#define CAN_GET_NEW_DATA_IN_BIT(can, u32MsgNum) ((u32MsgNum) < 16 ? (can)->NDAT1 & (1 << (u32MsgNum)) : (can)->NDAT2 & (1 << ((u32MsgNum)-16)))
/*---------------------------------------------------------------------------------------------------------*/
/* Define CAN functions prototype */
/*---------------------------------------------------------------------------------------------------------*/
uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate);
uint32_t CAN_Open(CAN_T *tCAN, uint32_t u32BaudRate, uint32_t u32Mode);
void CAN_Close(CAN_T *tCAN);
void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum);
void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask);
void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask);
int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg);
int32_t CAN_Receive(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg);
int32_t CAN_SetMultiRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32MsgCount, uint32_t u32IDType, uint32_t u32ID);
int32_t CAN_SetRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32IDType, uint32_t u32ID);
int32_t CAN_SetRxMsgAndMsk(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32IDType, uint32_t u32ID, uint32_t u32IDMask);
int32_t CAN_SetTxMsg(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg);
int32_t CAN_TriggerTxMsg(CAN_T *tCAN, uint32_t u32MsgNum);
/*@}*/ /* end of group M480_CAN_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group M480_CAN_Driver */
/*@}*/ /* end of group M480_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif /*__CAN_H__ */
/*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More