Initial support for PSoC 6.

pull/8491/head
Adrien Chardon 2017-07-03 11:54:39 +02:00 committed by Leszek Rusinowicz
parent 1608fbbe54
commit 2c533d4693
141 changed files with 61826 additions and 0 deletions

View File

@ -0,0 +1,90 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) XXX
* 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. Neither the name of ARM Limited nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_PERIPHERALNAMES_H
#define MBED_PERIPHERALNAMES_H
#include "cmsis.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
// typedef enum {
// ADC_1 = (int)ADC1_BASE,
// ADC_2 = (int)ADC2_BASE,
// ADC_3 = (int)ADC3_BASE,
// } ADCName;
// typedef enum {
// DAC_1 = (int)DAC_BASE,
// } DACName;
// typedef enum {
// UART_1 = (int)USART1_BASE,
// UART_2 = (int)USART2_BASE,
// UART_3 = (int)USART3_BASE,
// } UARTName;
#define STDIO_UART_TX CY_UART_TX
#define STDIO_UART_RX CY_UART_RX
// typedef enum {
// SPI_1 = (int)SPI1_BASE,
// SPI_2 = (int)SPI2_BASE,
// SPI_3 = (int)SPI3_BASE,
// } SPIName;
// typedef enum {
// I2C_0 = (int)I2C0_BASE,
// I2C_1 = (int)I2C1_BASE,
// } I2CName;
// typedef enum {
// PWM_0 = (int)PWM_CH0_BASE,
// PWM_1 = (int)PWM_CH1_BASE,
// PWM_2 = (int)PWM_CH2_BASE,
// PWM_3 = (int)PWM_CH3_BASE,
// PWM_4 = (int)PWM_CH4_BASE,
// PWM_5 = (int)PWM_CH5_BASE,
// PWM_6 = (int)PWM_CH6_BASE,
// PWM_7 = (int)PWM_CH7_BASE,
// } PWMName;
// typedef enum {
// CAN_1 = (int)CAN1_BASE,
// } CANName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,84 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) XXX
* 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. Neither the name of ARM Limited nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_PERIPHERALPINS_H
#define MBED_PERIPHERALPINS_H
#include "pinmap.h"
#include "PeripheralNames.h"
// //*** ADC ***
// #ifdef DEVICE_ANALOGIN
// extern const PinMap PinMap_ADC[];
// #endif
// //*** DAC ***
// #ifdef DEVICE_ANALOGOUT
// extern const PinMap PinMap_DAC[];
// #endif
// //*** I2C ***
// #if DEVICE_I2C
// extern const PinMap PinMap_I2C_SDA[];
// extern const PinMap PinMap_I2C_SCL[];
// #endif
// //*** PWM ***
// #if DEVICE_PWMOUT
// extern const PinMap PinMap_PWM[];
// #endif
// //*** SERIAL ***
// #ifdef DEVICE_SERIAL
// extern const PinMap PinMap_UART_TX[];
// extern const PinMap PinMap_UART_RX[];
// #endif
// //*** I2C ***
// #ifdef DEVICE_I2C
// extern const PinMap PinMap_I2C_SDA[];
// extern const PinMap PinMap_I2C_SCL[];
// #endif
// //*** SPI ***
// #ifdef DEVICE_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[];
// #endif
// //*** CAN ***
// #ifdef DEVICE_CAN
// extern const PinMap PinMap_CAN_RD[];
// extern const PinMap PinMap_CAN_TD[];
// #endif
#endif

View File

@ -0,0 +1,67 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2016, STMicroelectronics
* 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. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_PINNAMESTYPES_H
#define MBED_PINNAMESTYPES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
// PinName[15-0] = Port[15-8] + Pin[7-0]
#define CYPRESS_PIN(pinname) ((pinname) & 0xFF)
#define CYPRESS_PORT(pinname) (((pinname) >> 8) & 0xFF)
typedef enum {
PIN_INPUT = 0,
PIN_OUTPUT
} PinDirection;
typedef enum {
PullNone = 0,
PullUp = 1,
PullDown = 2,
OpenDrainPullUp = 3,
OpenDrainNoPull = 4,
OpenDrainPullDown = 5,
PushPullNoPull = PullNone,
PushPullPullUp = PullUp,
PushPullPullDown = PullDown,
OpenDrain = OpenDrainPullUp,
PullDefault = PullNone
} PinMode;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,61 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) XXX
* 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. Neither the name of ARM Limited nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_PORTNAMES_H
#define MBED_PORTNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
// Port[7-0]
typedef enum {
Port0 = 0x0,
Port1 = 0x1,
Port2 = 0x2,
Port3 = 0x3,
Port4 = 0x4,
Port5 = 0x5,
Port6 = 0x6,
Port7 = 0x7,
Port8 = 0x8,
Port9 = 0x9,
Port10 = 0xA,
Port11 = 0xB,
Port12 = 0xC,
Port13 = 0xD,
Port14 = 0xE,
Port15 = 0xF
} PortName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,131 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) XXX
* 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. Neither the name of ARM Limited nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#include "PeripheralNames.h"
#include "PeripheralPins.h"
#include "pinmap.h"
// //*** ADC ***
// const PinMap PinMap_ADC[] = {
// {PC_15, ADC_0, STM_PIN_DATA_EXT(WIZ_MODE_AF, WIZ_GPIO_PULLUP, Px_AFSR_AF3)}, // ADC0_IN0
// {PC_14, ADC_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_PULLUP, Px_AFSR_AF3)}, // ADC0_IN1
// {PC_13, ADC_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_PULLUP, Px_AFSR_AF3)}, // ADC0_IN2
// {PC_12, ADC_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_PULLUP, Px_AFSR_AF3)}, // ADC0_IN3
// {PC_11, ADC_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_PULLUP, Px_AFSR_AF3)}, // ADC0_IN4
// {PC_10, ADC_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_PULLUP, Px_AFSR_AF3)}, // ADC0_IN5
// {PC_9 , ADC_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_PULLUP, Px_AFSR_AF3)}, // ADC0_IN6
// {PC_8 , ADC_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_PULLUP, Px_AFSR_AF3)}, // ADC0_IN7
// {NC, NC, 0}
// };
// //*** DAC ***
// const PinMap PinMap_DAC[] = {
// {PA_4, DAC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // OUT1
// {PA_5, DAC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // OUT2 (Warning: LED1 is also on this pin)
// {NC, NC, 0}
// };
// //*** SERIAL ***
// const PinMap PinMap_UART_TX[] = {
// {PA_13, UART_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_PULLUP, Px_AFSR_AF0)},
// {PC_2, UART_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_PULLUP, Px_AFSR_AF0)},
// {PC_10, UART_2, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_PULLUP, Px_AFSR_AF0)},
// {NC, NC, 0}
// };
// const PinMap PinMap_UART_RX[] = {
// {PA_14, UART_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_PULLUP, Px_AFSR_AF0)},
// {PC_3, UART_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_PULLUP, Px_AFSR_AF0)},
// {PC_11, UART_2, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_PULLUP, Px_AFSR_AF0)},
// {NC, NC, 0}
// };
// //*** I2C ***
// const PinMap PinMap_I2C_SDA[] = {
// {PA_10, I2C_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
// {PC_9, I2C_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {PC_5, I2C_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
// {PA_6, I2C_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {NC, NC, 0}
// };
// const PinMap PinMap_I2C_SCL[] = {
// {PA_9, I2C_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
// {PC_8, I2C_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {PC_4, I2C_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
// {PA_5, I2C_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {NC, NC, 0}
// };
// //*** SPI ***
// const PinMap PinMap_SPI_SCLK[] = {
// {PA_6 , SPI_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
// {PB_1 , SPI_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
// {PC_13, SPI_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {PA_12, SPI_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {NC , NC , 0}
// };
// const PinMap PinMap_SPI_MOSI[] = {
// {PA_8 , SPI_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
// {PB_3 , SPI_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
// {PC_15, SPI_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {PA_14, SPI_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {NC , NC , 0}
// };
// const PinMap PinMap_SPI_MISO[] = {
// {PA_7 , SPI_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
// {PB_2 , SPI_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
// {PC_14, SPI_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {PA_13, SPI_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {NC , NC , 0}
// };
// const PinMap PinMap_SPI_SSEL[] = {
// {PA_5 , SPI_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
// {PB_0 , SPI_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
// {PC_12, SPI_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {PA_11, SPI_1, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {NC , NC , 0}
// };
// //*** PWM ***
// const PinMap PinMap_PWM[] = {
// {PA_0 , PWM_6, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {PA_1 , PWM_7, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {PA_5 , PWM_2, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF3)},
// {PA_7 , PWM_4, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF3)},
// {PA_8 , PWM_5, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF3)},
// {PA_9 , PWM_6, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF3)},
// {PA_10, PWM_7, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF3)},
// {PC_0 , PWM_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {PC_2 , PWM_2, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {PC_4 , PWM_4, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {PC_5 , PWM_5, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {PC_8 , PWM_0, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)},
// {PC_10, PWM_2, WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF2)},
// {NC , NC , WIZ_PIN_DATA(WIZ_MODE_AF, WIZ_GPIO_NOPULL, Px_AFSR_AF0)}
// };

View File

@ -0,0 +1,251 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) XXX
* 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. Neither the name of ARM Limited nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_PINNAMES_H
#define MBED_PINNAMES_H
#include "cmsis.h"
#include "PinNamesTypes.h"
#include "PortNames.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CY_UART_RX P5_0
#define CY_UART_TX P5_1
// PinName[15-0] = Port[15-8] + Pin[7-0]
typedef enum {
P0_0 = (Port0 << 8) + 0x00,
P0_1 = (Port0 << 8) + 0x01,
P0_2 = (Port0 << 8) + 0x02,
P0_3 = (Port0 << 8) + 0x03,
P0_4 = (Port0 << 8) + 0x04,
P0_5 = (Port0 << 8) + 0x05,
P0_6 = (Port0 << 8) + 0x06,
P0_7 = (Port0 << 8) + 0x07,
P1_0 = (Port1 << 8) + 0x00,
P1_1 = (Port1 << 8) + 0x01,
P1_2 = (Port1 << 8) + 0x02,
P1_3 = (Port1 << 8) + 0x03,
P1_4 = (Port1 << 8) + 0x04,
P1_5 = (Port1 << 8) + 0x05,
P1_6 = (Port1 << 8) + 0x06,
P1_7 = (Port1 << 8) + 0x07,
P2_0 = (Port2 << 8) + 0x00,
P2_1 = (Port2 << 8) + 0x01,
P2_2 = (Port2 << 8) + 0x02,
P2_3 = (Port2 << 8) + 0x03,
P2_4 = (Port2 << 8) + 0x04,
P2_5 = (Port2 << 8) + 0x05,
P2_6 = (Port2 << 8) + 0x06,
P2_7 = (Port2 << 8) + 0x07,
P3_0 = (Port3 << 8) + 0x00,
P3_1 = (Port3 << 8) + 0x01,
P3_2 = (Port3 << 8) + 0x02,
P3_3 = (Port3 << 8) + 0x03,
P3_4 = (Port3 << 8) + 0x04,
P3_5 = (Port3 << 8) + 0x05,
P3_6 = (Port3 << 8) + 0x06,
P3_7 = (Port3 << 8) + 0x07,
P4_0 = (Port4 << 8) + 0x00,
P4_1 = (Port4 << 8) + 0x01,
P4_2 = (Port4 << 8) + 0x02,
P4_3 = (Port4 << 8) + 0x03,
P4_4 = (Port4 << 8) + 0x04,
P4_5 = (Port4 << 8) + 0x05,
P4_6 = (Port4 << 8) + 0x06,
P4_7 = (Port4 << 8) + 0x07,
P5_0 = (Port5 << 8) + 0x00,
P5_1 = (Port5 << 8) + 0x01,
P5_2 = (Port5 << 8) + 0x02,
P5_3 = (Port5 << 8) + 0x03,
P5_4 = (Port5 << 8) + 0x04,
P5_5 = (Port5 << 8) + 0x05,
P5_6 = (Port5 << 8) + 0x06,
P5_7 = (Port5 << 8) + 0x07,
P6_0 = (Port6 << 8) + 0x00,
P6_1 = (Port6 << 8) + 0x01,
P6_2 = (Port6 << 8) + 0x02,
P6_3 = (Port6 << 8) + 0x03,
P6_4 = (Port6 << 8) + 0x04,
P6_5 = (Port6 << 8) + 0x05,
P6_6 = (Port6 << 8) + 0x06,
P6_7 = (Port6 << 8) + 0x07,
P7_0 = (Port7 << 8) + 0x00,
P7_1 = (Port7 << 8) + 0x01,
P7_2 = (Port7 << 8) + 0x02,
P7_3 = (Port7 << 8) + 0x03,
P7_4 = (Port7 << 8) + 0x04,
P7_5 = (Port7 << 8) + 0x05,
P7_6 = (Port7 << 8) + 0x06,
P7_7 = (Port7 << 8) + 0x07,
P8_0 = (Port8 << 8) + 0x00,
P8_1 = (Port8 << 8) + 0x01,
P8_2 = (Port8 << 8) + 0x02,
P8_3 = (Port8 << 8) + 0x03,
P8_4 = (Port8 << 8) + 0x04,
P8_5 = (Port8 << 8) + 0x05,
P8_6 = (Port8 << 8) + 0x06,
P8_7 = (Port8 << 8) + 0x07,
P9_0 = (Port9 << 8) + 0x00,
P9_1 = (Port9 << 8) + 0x01,
P9_2 = (Port9 << 8) + 0x02,
P9_3 = (Port9 << 8) + 0x03,
P9_4 = (Port9 << 8) + 0x04,
P9_5 = (Port9 << 8) + 0x05,
P9_6 = (Port9 << 8) + 0x06,
P9_7 = (Port9 << 8) + 0x07,
P10_0 = (Port10 << 8) + 0x00,
P10_1 = (Port10 << 8) + 0x01,
P10_2 = (Port10 << 8) + 0x02,
P10_3 = (Port10 << 8) + 0x03,
P10_4 = (Port10 << 8) + 0x04,
P10_5 = (Port10 << 8) + 0x05,
P10_6 = (Port10 << 8) + 0x06,
P10_7 = (Port10 << 8) + 0x07,
P11_0 = (Port11 << 8) + 0x00,
P11_1 = (Port11 << 8) + 0x01,
P11_2 = (Port11 << 8) + 0x02,
P11_3 = (Port11 << 8) + 0x03,
P11_4 = (Port11 << 8) + 0x04,
P11_5 = (Port11 << 8) + 0x05,
P11_6 = (Port11 << 8) + 0x06,
P11_7 = (Port11 << 8) + 0x07,
P12_0 = (Port12 << 8) + 0x00,
P12_1 = (Port12 << 8) + 0x01,
P12_2 = (Port12 << 8) + 0x02,
P12_3 = (Port12 << 8) + 0x03,
P12_4 = (Port12 << 8) + 0x04,
P12_5 = (Port12 << 8) + 0x05,
P12_6 = (Port12 << 8) + 0x06,
P12_7 = (Port12 << 8) + 0x07,
P13_0 = (Port13 << 8) + 0x00,
P13_1 = (Port13 << 8) + 0x01,
P13_2 = (Port13 << 8) + 0x02,
P13_3 = (Port13 << 8) + 0x03,
P13_4 = (Port13 << 8) + 0x04,
P13_5 = (Port13 << 8) + 0x05,
P13_6 = (Port13 << 8) + 0x06,
P13_7 = (Port13 << 8) + 0x07,
P14_0 = (Port14 << 8) + 0x00,
P14_1 = (Port14 << 8) + 0x01,
P14_2 = (Port14 << 8) + 0x02,
P14_3 = (Port14 << 8) + 0x03,
P14_4 = (Port14 << 8) + 0x04,
P14_5 = (Port14 << 8) + 0x05,
P14_6 = (Port14 << 8) + 0x06,
P14_7 = (Port14 << 8) + 0x07,
P15_0 = (Port15 << 8) + 0x00,
P15_1 = (Port15 << 8) + 0x01,
P15_2 = (Port15 << 8) + 0x02,
P15_3 = (Port15 << 8) + 0x03,
P15_4 = (Port15 << 8) + 0x04,
P15_5 = (Port15 << 8) + 0x05,
P15_6 = (Port15 << 8) + 0x06,
P15_7 = (Port15 << 8) + 0x07,
// Arduino connector namings
A0 = P10_0,
A1 = P10_1,
A2 = P10_2,
A3 = P10_3,
A4 = P10_4,
A5 = P10_5,
D0 = P5_0,
D1 = P5_1,
D2 = P5_2,
D3 = P5_3,
D4 = P5_4,
D5 = P5_5,
D6 = P5_6,
D7 = P0_2,
D8 = P13_0,
D9 = P13_1,
D10 = P12_3,
D11 = P12_0,
D12 = P12_1,
D13 = P12_2,
// Generic signals namings
LED_RED = P0_3,
LED_GREEN = P1_1,
LED_BLUE = P11_1,
SWITCH2 = P0_4,
LED1 = LED_RED,
LED2 = LED_GREEN,
LED3 = LED_BLUE,
LED4 = LED_RED,
USER_BUTTON = SWITCH2,
BUTTON1 = USER_BUTTON,
// Standardized interfaces names
SERIAL_TX = CY_UART_TX,
SERIAL_RX = CY_UART_RX,
USBTX = CY_UART_TX,
USBRX = CY_UART_RX,
// I2C_SCL = PB_8,
// I2C_SDA = PB_9,
// SPI_MOSI = PA_7,
// SPI_MISO = PA_6,
// SPI_SCK = PA_5,
// SPI_CS = PB_6,
// PWM_OUT = PB_3,
// Not connected
NC = (int)0xFFFFFFFF
} PinName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,39 @@
// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches.
// Check the 'features' section of the target description in 'targets.json' for more details.
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) XXX
* 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. Neither the name of ARM Limited nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_DEVICE_H
#define MBED_DEVICE_H
#include "objects.h"
#include "project.h"
#endif

View File

@ -0,0 +1,328 @@
/***************************************************************************//**
* \file cy8c6x7_cm0plus.ld
* \version 1.0
*
* \brief Linker file for the GNU C compiler.
*
* \note The entry point location is fixed and starts at 0x10000000. The valid
* application image should be placed there.
*
* \note The linker files included with the PDL template projects must be generic
* and handle all common use cases. Your project may not use every section
* defined in the linker files. In that case you may see warnings during the
* build process. In your project, you can simply comment out or remove the
* relevant code in the linker file.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
ENTRY(Reset_Handler)
/* Force symbol to be entered in the output file as an undefined symbol. Doing
* this may, for example, trigger linking of additional modules from standard
* libraries. You may list several symbols for each EXTERN, and you may use
* EXTERN multiple times. This command has the same effect as the -u command-line
* option.
*/
EXTERN(Reset_Handler)
EXTERN(vectors)
EXTERN(ram_vectors)
EXTERN(cychipprotect)
EXTERN(cymeta)
/* Flash */
__cy_memory_0_start = 0x10000000;
__cy_memory_0_length = 0x00100000;
__cy_memory_0_row_size = 0x200;
/* Working Flash */
__cy_memory_1_start = 0x14000000;
__cy_memory_1_length = 0x8000;
__cy_memory_1_row_size = 0x200;
/* XIP */
__cy_memory_2_start = 0x18000000;
__cy_memory_2_length = 0x08000000;
__cy_memory_2_row_size = 0x200;
/* Linker script to configure memory regions. */
MEMORY
{
rom (rx) : ORIGIN = 0x10000000, LENGTH = 0x00080000
wrom (rx) : ORIGIN = 0x14000000, LENGTH = 0x8000
xip (rx) : ORIGIN = 0x18000000, LENGTH = 0x08000000
ram_cm0p (rwx) : ORIGIN = 0x08000000, LENGTH = 0x00024000
}
/* Library configurations */
GROUP(libgcc.a libc.a libm.a libnosys.a)
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
* __Vectors_End
* __Vectors_Size
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
/* Cortex-M0+ ROM vector table */
. = ALIGN(4);
__Vectors = . ;
KEEP(*(.vectors))
. = ALIGN(4);
__Vectors_End = .;
__Vectors_Size = __Vectors_End - __Vectors;
__end__ = .;
. = ALIGN(4);
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
/* Read-only code (constants). */
*(.rodata .rodata.* .constdata .constdata.* .conststring .conststring.*)
KEEP(*(.eh_frame*))
} > rom
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > rom
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > rom
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_psoc6ble_cm0plus.S */
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
/* Copy interrupt vectors from flash to RAM */
LONG (__Vectors) /* From */
LONG (__ram_vectors_start__) /* To */
LONG (__Vectors_End - __Vectors) /* Size */
/* Copy data section to RAM */
LONG (__etext) /* From */
LONG (__data_start__) /* To */
LONG (__data_end__ - __data_start__) /* Size */
__copy_table_end__ = .;
} > rom
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_psoc6ble_cm0plus.S */
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
__zero_table_end__ = .;
} > rom
__etext = . ;
.ramVectors (NOLOAD) : ALIGN(8)
{
__ram_vectors_start__ = .;
KEEP(*(.ram_vectors))
__ram_vectors_end__ = .;
} > ram_cm0p
.data __ram_vectors_end__ : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
__data_end__ = .;
} > ram_cm0p
/* Place variables in the section that should not be initialized during the
* device startup.
*/
.noinit (NOLOAD) : ALIGN(8)
{
KEEP(*(.noinit))
} > ram_cm0p
/* The uninitialized global or static variables are placed in this section.
*
* The NOLOAD attribute tells linker that .bss section does not consume
* any space in the image. The NOLOAD attribute changes the .bss type to
* NOBITS, and that makes linker to A) not allocate section in memory, and
* A) put information to clear the section with all zeros during application
* loading.
*
* Without the NOLOAD attribute, the .bss section might get PROGBITS type.
* This makes linker to A) allocate zeroed section in memory, and B) copy
* this section to RAM during application loading.
*/
.bss (NOLOAD):
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > ram_cm0p
.heap (NOLOAD):
{
__HeapBase = .;
__end__ = .;
end = __end__;
KEEP(*(.heap*))
__HeapLimit = .;
} > ram_cm0p
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (NOLOAD):
{
KEEP(*(.stack*))
} > ram_cm0p
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(ram_cm0p) + LENGTH(ram_cm0p);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
/* The section is used for BLE bonding data storage. */
ble_bond_data 0x14000000 :
{
__ble_bond_data_start = . ;
KEEP(*(.ble_bond_data))
__ble_bond_data_end = . ;
} > wrom
/* Places the code in the Execute in Place (XIP) section. See the smif driver
* documentation for details.
*/
.xip 0x18000000 :
{
. = ALIGN(4);
__xip_data_start = . ;
KEEP(*(.xip))
__xip_data_end = . ;
} > xip
/* These sections are used for additional metadata (silicon revision,
* Silicon/JTAG ID, etc.) storage.
*/
.cymeta 0x90500000 : { KEEP(*(.cymeta)) } :NONE
.cychipprotect 0x90600000 : { KEEP(*(.cychipprotect)) } :NONE
}
/* EOF */

View File

@ -0,0 +1,101 @@
/***************************************************************************//**
* \file cy_syslib_core_armcc.s
* \version 1.0
*
* \brief Assembly routines for GNU as.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
.syntax unified
.text
.thumb
/*******************************************************************************
* Function Name: Cy_SysLib_DelayCycles
****************************************************************************//**
*
* Delays for the specified number of cycles.
*
* \param uint32_t cycles: The number of cycles to delay.
*
*******************************************************************************/
/* void Cy_SysLib_DelayCycles(uint32_t cycles) */
.align 3 /* Align to 8 byte boundary (2^n) */
.global Cy_SysLib_DelayCycles
.func Cy_SysLib_DelayCycles, Cy_SysLib_DelayCycles
.type Cy_SysLib_DelayCycles, %function
.thumb_func
Cy_SysLib_DelayCycles: /* cycles bytes */
ADDS r0, r0, #2 /* 1 2 Round to nearest multiple of 4 */
LSRS r0, r0, #2 /* 1 2 Divide by 4 and set flags */
BEQ Cy_DelayCycles_done /* 2 2 Skip if 0 */
Cy_DelayCycles_loop:
/* For CM0+ branch instruction takes 2 CPU cycles */
ADDS r0, r0, #1 /* 1 2 Increment counter */
SUBS r0, r0, #2 /* 1 2 Decrement counter by 2 */
BNE Cy_DelayCycles_loop /* 2 2 2 CPU cycles (if branch is taken)*/
NOP /* 1 2 Loop alignment padding */
Cy_DelayCycles_done:
NOP /* 1 2 Loop alignment padding */
BX lr /* 3 2 */
.endfunc
/*******************************************************************************
* Function Name: Cy_SysLib_EnterCriticalSection
****************************************************************************//**
*
* Cy_SysLib_EnterCriticalSection disables interrupts and returns a value
* indicating whether interrupts were previously enabled.
*
* Note Implementation of Cy_SysLib_EnterCriticalSection manipulates the IRQ
* enable bit with interrupts still enabled.
*
* \return Returns 0 if interrupts were previously enabled or 1 if interrupts
* were previously disabled.
*
*******************************************************************************/
/* uint8_t Cy_SysLib_EnterCriticalSection(void) */
.global Cy_SysLib_EnterCriticalSection
.func Cy_SysLib_EnterCriticalSection, Cy_SysLib_EnterCriticalSection
.type Cy_SysLib_EnterCriticalSection, %function
.thumb_func
Cy_SysLib_EnterCriticalSection:
MRS r0, PRIMASK /* Save and return interrupt state */
CPSID I /* Disable interrupts */
BX lr
.endfunc
/*******************************************************************************
* Function Name: Cy_SysLib_ExitCriticalSection
****************************************************************************//**
*
* Re-enables interrupts if they were enabled before
* Cy_SysLib_EnterCriticalSection() was called. The argument should be the value
* returned from \ref Cy_SysLib_EnterCriticalSection().
*
* \param uint8_t savedIntrStatus:
* Saved interrupt status returned by the \ref Cy_SysLib_EnterCriticalSection().
*
*******************************************************************************/
/* void Cy_SysLib_ExitCriticalSection(uint8_t savedIntrStatus) */
.global Cy_SysLib_ExitCriticalSection
.func Cy_SysLib_ExitCriticalSection, Cy_SysLib_ExitCriticalSection
.type Cy_SysLib_ExitCriticalSection, %function
.thumb_func
Cy_SysLib_ExitCriticalSection:
MSR PRIMASK, r0 /* Restore interrupt state */
BX lr
.endfunc
.end
/* [] END OF FILE */

View File

@ -0,0 +1,423 @@
/**************************************************************************//**
* @file startup_psoc6ble_cm0plus.s
* @brief CMSIS Core Device Startup File for
* ARMCM0plus Device Series
* @version V5.00
* @date 02. March 2016
******************************************************************************/
/*
* Copyright (c) 2009-2016 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
*
* 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.
*/
/* Address of the NMI handler */
#define CY_NMI_HANLDER_ADDR 0x0000000D
/* The Cortex-M4 VTOR register */
#define CY_CORTEX_M4_VTOR_ADDR 0x402102C0
/* The CPU VTOR register */
#define CY_CPU_VTOR_ADDR 0xE000ED08
/* Copy flash vectors and data section to RAM */
#define __STARTUP_COPY_MULTIPLE
/* Clear single BSS section */
#define __STARTUP_CLEAR_BSS
.syntax unified
.arch armv6-m
.section .stack
.align 3
#ifdef __STACK_SIZE
.equ Stack_Size, __STACK_SIZE
#else
.equ Stack_Size, 0x00001000
#endif
.globl __StackTop
.globl __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
.section .heap
.align 3
#ifdef __HEAP_SIZE
.equ Heap_Size, __HEAP_SIZE
#else
.equ Heap_Size, 0x00000400
#endif
.globl __HeapBase
.globl __HeapLimit
__HeapBase:
.if Heap_Size
.space Heap_Size
.endif
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
.section .vectors
.align 2
.globl __Vectors
__Vectors:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long CY_NMI_HANLDER_ADDR /* NMI Handler */
.long HardFault_Handler /* Hard Fault Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* External interrupts Power Mode Description */
.long ioss_interrupts_gpio_0_IRQHandler /* DeepSleep GPIO Port Interrupt #0 */
.long ioss_interrupts_gpio_1_IRQHandler /* DeepSleep GPIO Port Interrupt #1 */
.long ioss_interrupts_gpio_2_IRQHandler /* DeepSleep GPIO Port Interrupt #2 */
.long ioss_interrupts_gpio_3_IRQHandler /* DeepSleep GPIO Port Interrupt #3 */
.long ioss_interrupts_gpio_4_IRQHandler /* DeepSleep GPIO Port Interrupt #4 */
.long ioss_interrupts_gpio_5_IRQHandler /* DeepSleep GPIO Port Interrupt #5 */
.long ioss_interrupts_gpio_6_IRQHandler /* DeepSleep GPIO Port Interrupt #6 */
.long ioss_interrupts_gpio_7_IRQHandler /* DeepSleep GPIO Port Interrupt #7 */
.long ioss_interrupts_gpio_8_IRQHandler /* DeepSleep GPIO Port Interrupt #8 */
.long ioss_interrupts_gpio_9_IRQHandler /* DeepSleep GPIO Port Interrupt #9 */
.long ioss_interrupts_gpio_10_IRQHandler /* DeepSleep GPIO Port Interrupt #10 */
.long ioss_interrupts_gpio_11_IRQHandler /* DeepSleep GPIO Port Interrupt #11 */
.long ioss_interrupts_gpio_12_IRQHandler /* DeepSleep GPIO Port Interrupt #12 */
.long ioss_interrupts_gpio_13_IRQHandler /* DeepSleep GPIO Port Interrupt #13 */
.long ioss_interrupts_gpio_14_IRQHandler /* DeepSleep GPIO Port Interrupt #14 */
.long ioss_interrupt_gpio_IRQHandler /* DeepSleep GPIO All Ports */
.long ioss_interrupt_vdd_IRQHandler /* DeepSleep GPIO Supply Detect Interrupt */
.long lpcomp_interrupt_IRQHandler /* DeepSleep Low Power Comparator Interrupt */
.long scb_8_interrupt_IRQHandler /* DeepSleep Serial Communication Block #8 (DeepSleep capable) */
.long srss_interrupt_mcwdt_0_IRQHandler /* DeepSleep Multi Counter Watchdog Timer interrupt */
.long srss_interrupt_mcwdt_1_IRQHandler /* DeepSleep Multi Counter Watchdog Timer interrupt */
.long srss_interrupt_backup_IRQHandler /* DeepSleep Backup domain interrupt */
.long srss_interrupt_IRQHandler /* DeepSleep Other combined Interrupts for SRSS (LVD, WDT, CLKCAL) */
.long pass_interrupt_ctbs_IRQHandler /* DeepSleep CTBm Interrupt (all CTBms) */
.long bless_interrupt_IRQHandler /* DeepSleep Bluetooth Radio interrupt */
.long cpuss_interrupts_ipc_0_IRQHandler /* DeepSleep CPUSS Inter Process Communication Interrupt #0 */
.long cpuss_interrupts_ipc_1_IRQHandler /* DeepSleep CPUSS Inter Process Communication Interrupt #1 */
.long cpuss_interrupts_ipc_2_IRQHandler /* DeepSleep CPUSS Inter Process Communication Interrupt #2 */
.long cpuss_interrupts_ipc_3_IRQHandler /* DeepSleep CPUSS Inter Process Communication Interrupt #3 */
.long cpuss_interrupts_ipc_4_IRQHandler /* DeepSleep CPUSS Inter Process Communication Interrupt #4 */
.long cpuss_interrupts_ipc_5_IRQHandler /* DeepSleep CPUSS Inter Process Communication Interrupt #5 */
.long cpuss_interrupts_ipc_6_IRQHandler /* DeepSleep CPUSS Inter Process Communication Interrupt #6 */
.size __Vectors, . - __Vectors
.equ __VectorsSize, . - __Vectors
.section .ram_vectors
.align 2
.globl __ramVectors
__ramVectors:
.space __VectorsSize
.size __ramVectors, . - __ramVectors
.text
.thumb
.thumb_func
.align 2
/* Device startup customization */
.weak Cy_OnResetUser
.func Cy_OnResetUser, Cy_OnResetUser
.type Cy_OnResetUser, %function
Cy_OnResetUser:
bx lr
.size Cy_OnResetUser, . - Cy_OnResetUser
.endfunc
/* Saves and disables the interrupts */
.global Cy_SaveIRQ
.func Cy_SaveIRQ, Cy_SaveIRQ
.type Cy_SaveIRQ, %function
Cy_SaveIRQ:
mrs r0, PRIMASK
cpsid i
bx lr
.size Cy_SaveIRQ, . - Cy_SaveIRQ
.endfunc
/* Restores the interrupts */
.global Cy_RestoreIRQ
.func Cy_RestoreIRQ, Cy_RestoreIRQ
.type Cy_RestoreIRQ, %function
Cy_RestoreIRQ:
msr PRIMASK, r0
bx lr
.size Cy_RestoreIRQ, . - Cy_RestoreIRQ
.endfunc
/* Reset handler */
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
bl Cy_OnResetUser
cpsid i
/* Firstly it copies data from read only memory to RAM. There are two schemes
* to copy. One can copy more than one sections. Another can only copy
* one section. The former scheme needs more instructions and read-only
* data to implement than the latter.
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
#ifdef __STARTUP_COPY_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of triplets, each of which specify:
* offset 0: LMA of start of a section to copy from
* offset 4: VMA of start of a section to copy to
* offset 8: size of the section to copy. Must be multiply of 4
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r4, =__copy_table_start__
ldr r5, =__copy_table_end__
.L_loop0:
cmp r4, r5
bge .L_loop0_done
ldr r1, [r4]
ldr r2, [r4, #4]
ldr r3, [r4, #8]
.L_loop0_0:
subs r3, #4
blt .L_loop0_0_done
ldr r0, [r1, r3]
str r0, [r2, r3]
b .L_loop0_0
.L_loop0_0_done:
adds r4, #12
b .L_loop0
.L_loop0_done:
#else
/* Single section scheme.
*
* The ranges of copy from/to are specified by following symbols
* __etext: LMA of start of the section to copy from. Usually end of text
* __data_start__: VMA of start of the section to copy to
* __data_end__: VMA of end of the section to copy to
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
subs r3, r2
ble .L_loop1_done
.L_loop1:
subs r3, #4
ldr r0, [r1,r3]
str r0, [r2,r3]
bgt .L_loop1
.L_loop1_done:
#endif /*__STARTUP_COPY_MULTIPLE */
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
* There are two schemes too. One can clear multiple BSS sections. Another
* can only clear one section. The former is more size expensive than the
* latter.
*
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
* Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
*/
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of tuples specifying:
* offset 0: Start of a BSS section
* offset 4: Size of this BSS section. Must be multiply of 4
*/
ldr r3, =__zero_table_start__
ldr r4, =__zero_table_end__
.L_loop2:
cmp r3, r4
bge .L_loop2_done
ldr r1, [r3]
ldr r2, [r3, #4]
movs r0, 0
.L_loop2_0:
subs r2, #4
blt .L_loop2_0_done
str r0, [r1, r2]
b .L_loop2_0
.L_loop2_0_done:
adds r3, #8
b .L_loop2
.L_loop2_done:
#elif defined (__STARTUP_CLEAR_BSS)
/* Single BSS section scheme.
*
* The BSS section is specified by following symbols
* __bss_start__: start of the BSS section.
* __bss_end__: end of the BSS section.
*
* Both addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__bss_start__
ldr r2, =__bss_end__
movs r0, 0
subs r2, r1
ble .L_loop3_done
.L_loop3:
subs r2, #4
str r0, [r1, r2]
bgt .L_loop3
.L_loop3_done:
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
/* Update Vector Table Offset Register. */
ldr r0, =__ramVectors
ldr r1, =CY_CPU_VTOR_ADDR
str r0, [r1]
dsb 0xF
#ifndef __NO_SYSTEM_INIT
bl SystemInit
#endif
bl _start
/* Should never get here */
b .
.pool
.size Reset_Handler, . - Reset_Handler
.align 1
.thumb_func
.weak Default_Handler
.type Default_Handler, %function
Default_Handler:
b .
.size Default_Handler, . - Default_Handler
.weak Cy_SysLib_FaultHandler
.type Cy_SysLib_FaultHandler, %function
Cy_SysLib_FaultHandler:
b .
.size Cy_SysLib_FaultHandler, . - Cy_SysLib_FaultHandler
.type Fault_Handler, %function
Fault_Handler:
/* Storing LR content for Creator call stack trace */
push {LR}
movs r0, #4
mov r1, LR
tst r0, r1
beq .L_MSP
mrs r0, PSP
b .L_API_call
.L_MSP:
mrs r0, MSP
.L_API_call:
/* Compensation of stack pointer address due to pushing 4 bytes of LR */
adds r0, r0, #4
bl Cy_SysLib_FaultHandler
b .
.size Fault_Handler, . - Fault_Handler
.macro def_fault_Handler fault_handler_name
.weak \fault_handler_name
.set \fault_handler_name, Fault_Handler
.endm
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.set \handler_name, Default_Handler
.endm
def_irq_handler NMI_Handler
def_fault_Handler HardFault_Handler
def_irq_handler SVC_Handler
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
def_irq_handler ioss_interrupts_gpio_0_IRQHandler
def_irq_handler ioss_interrupts_gpio_1_IRQHandler
def_irq_handler ioss_interrupts_gpio_2_IRQHandler
def_irq_handler ioss_interrupts_gpio_3_IRQHandler
def_irq_handler ioss_interrupts_gpio_4_IRQHandler
def_irq_handler ioss_interrupts_gpio_5_IRQHandler
def_irq_handler ioss_interrupts_gpio_6_IRQHandler
def_irq_handler ioss_interrupts_gpio_7_IRQHandler
def_irq_handler ioss_interrupts_gpio_8_IRQHandler
def_irq_handler ioss_interrupts_gpio_9_IRQHandler
def_irq_handler ioss_interrupts_gpio_10_IRQHandler
def_irq_handler ioss_interrupts_gpio_11_IRQHandler
def_irq_handler ioss_interrupts_gpio_12_IRQHandler
def_irq_handler ioss_interrupts_gpio_13_IRQHandler
def_irq_handler ioss_interrupts_gpio_14_IRQHandler
def_irq_handler ioss_interrupt_gpio_IRQHandler
def_irq_handler ioss_interrupt_vdd_IRQHandler
def_irq_handler lpcomp_interrupt_IRQHandler
def_irq_handler scb_8_interrupt_IRQHandler
def_irq_handler srss_interrupt_mcwdt_0_IRQHandler
def_irq_handler srss_interrupt_mcwdt_1_IRQHandler
def_irq_handler srss_interrupt_backup_IRQHandler
def_irq_handler srss_interrupt_IRQHandler
def_irq_handler pass_interrupt_ctbs_IRQHandler
def_irq_handler bless_interrupt_IRQHandler
def_irq_handler cpuss_interrupts_ipc_0_IRQHandler
def_irq_handler cpuss_interrupts_ipc_1_IRQHandler
def_irq_handler cpuss_interrupts_ipc_2_IRQHandler
def_irq_handler cpuss_interrupts_ipc_3_IRQHandler
def_irq_handler cpuss_interrupts_ipc_4_IRQHandler
def_irq_handler cpuss_interrupts_ipc_5_IRQHandler
def_irq_handler cpuss_interrupts_ipc_6_IRQHandler
.end
/* [] END OF FILE */

View File

@ -0,0 +1,38 @@
/* mbed Microcontroller Library
* A generic CMSIS include header
*******************************************************************************
* Copyright (c) XXX
* 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. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_CMSIS_H
#define MBED_CMSIS_H
#include "cy8c637bzi_bld74.h" // IRQn - could include "include/cy_device_headers.h"
#include "core_cm0plus.h" // NVIC
#endif

View File

@ -0,0 +1,85 @@
/***************************************************************************//**
* \file cy_device_headers.h
*
* \brief
* Common header file to be included by the drivers.
*
* \note
* Generated 2/9/2017 by CyDeviceHeaderGenerator v1.1.0.47
* from the register map configuration rev#961378
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#ifndef _CY_DEVICE_HEADERS_H_
#define _CY_DEVICE_HEADERS_H_
#if defined (CY8C622PSVP)
#include "cy8c622psvp.h"
#elif defined (CY8C622PSVP_DUAL)
#include "cy8c622psvp_dual.h"
#elif defined (CY8C616FMI_BL603)
#include "cy8c616fmi_bl603.h"
#elif defined (CY8C616FMI_BL673)
#include "cy8c616fmi_bl673.h"
#elif defined (CY8C616LQI_BL601)
#include "cy8c616lqi_bl601.h"
#elif defined (CY8C616LQI_BL671)
#include "cy8c616lqi_bl671.h"
#elif defined (CY8C617FMI_BL603)
#include "cy8c617fmi_bl603.h"
#elif defined (CY8C617FMI_BLD73)
#include "cy8c617fmi_bld73.h"
#elif defined (CY8C626FMI_BL603)
#include "cy8c626fmi_bl603.h"
#elif defined (CY8C626BZI_BL604)
#include "cy8c626bzi_bl604.h"
#elif defined (CY8C626BZI_BL674)
#include "cy8c626bzi_bl674.h"
#elif defined (CY8C627BZI_BL604)
#include "cy8c627bzi_bl604.h"
#elif defined (CY8C627FMI_BLD73)
#include "cy8c627fmi_bld73.h"
#elif defined (CY8C627BZI_BLD74)
#include "cy8c627bzi_bld74.h"
#elif defined (CY8C636BZI_BL604)
#include "cy8c636bzi_bl604.h"
#elif defined (CY8C636BZI_BL674)
#include "cy8c636bzi_bl674.h"
#elif defined (CY8C636FMI_BL603)
#include "cy8c636fmi_bl603.h"
#elif defined (CY8C636FMI_BL673)
#include "cy8c636fmi_bl673.h"
#elif defined (CY8C636LQI_BL601)
#include "cy8c636lqi_bl601.h"
#elif defined (CY8C636LQI_BL671)
#include "cy8c636lqi_bl671.h"
#elif defined (CY8C637BZI_BLD04)
#include "cy8c637bzi_bld04.h"
#elif defined (CY8C637BZI_BLD74)
#include "cy8c637bzi_bld74.h"
#elif defined (CY8C637FMI_BLD03)
#include "cy8c637fmi_bld03.h"
#elif defined (CY8C637FMI_BLD73)
#include "cy8c637fmi_bld73.h"
#elif defined (CY8C637LQI_BLD01)
#include "cy8c637lqi_bld01.h"
#elif defined (CY8C637LQI_BLD71)
#include "cy8c637lqi_bld71.h"
#elif defined (CY8C68237FM_BLE)
#include "cy8c68237fm_ble.h"
#elif defined (CY8C68237BZ_BLE)
#include "cy8c68237bz_ble.h"
#else
#error Undefined part number
#endif
#endif /* _CY_DEVICE_HEADERS_H_ */
/* [] END OF FILE */

View File

@ -0,0 +1,667 @@
/***************************************************************************//**
* \file system_psoc6ble_cm0plus.c
* \version 1.0
*
* The device system-source file.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "system_psoc6ble_cm0plus.h"
#include "cy_device_headers.h"
#include "ipc/cy_ipc_drv.h"
#include "ipc/cy_ipc_pipe.h"
#include "ipc/cy_ipc_lock.h"
#include "sysint/cy_sysint.h"
/*******************************************************************************
* Inter Process Communication (IPC)
*******************************************************************************/
cy_stc_ipc_pipe_ep_t cy_ipc_pipe_sysEpArray[CPUSS_IPC_IPC_NR];
uint32_t ipcLockArray[CY_IPC_LOCK_COUNT/CY_IPC_LOCKS_PER_WORD];
cy_ipc_pipe_callback_ptr_t ipc_pipe_cyPipeCbArray[CY_IPC_CYPIPE_CLIENT_CNT];
/*******************************************************************************
* SystemCoreClockUpdate()
*******************************************************************************/
/** Default HFClk frequency in Hz */
#define CY_HFCLK0_FREQ_HZ_DEFAULT ( 8000000UL)
/** Default PeriClk frequency in Hz */
#define CY_PERICLK_FREQ_HZ_DEFAULT (4000000UL)
/** Default SlowClk system core frequency in Hz */
#define CY_SYSTEM_CLOCK_FREQ_HZ_DEFAULT (4000000UL)
#define CY_IMO_FREQ_HZ ( 8000000UL)
#ifndef CY_EXT_FREQ_HZ
#define CY_EXT_FREQ_HZ (24000000UL)
#endif
#ifndef CY_ECO_FREQ_HZ
#define CY_ECO_FREQ_HZ (24000000UL)
#endif
#if defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL)
#ifndef CY_ALTHF_FREQ_HZ
#define CY_ALTHF_FREQ_HZ (32000000UL)
#endif
uint32_t cy_BleEcoClockFreqHz = CY_ALTHF_FREQ_HZ;
#endif /* defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL) */
#define CY_ROOT_PATH_SRC_IMO (0UL)
#define CY_ROOT_PATH_SRC_EXT (1UL)
#define CY_ROOT_PATH_SRC_ECO (2UL)
#define CY_ROOT_PATH_SRC_ALTHF (3UL)
/** Holds the SlowClk system core clock, which is the system clock frequency supplied to the SysTick timer and the
* processor core clock. This variable can be used by debuggers to query the frequency of the debug timer or to configure
* the trace clock speed.
*
* \attention Compilers must be configured to avoid removing this variable in case the application program is not using
* it. Debugging systems require the variable to be physically present in memory so that it can be examined to configure
* the debugger. */
uint32_t SystemCoreClock = CY_SYSTEM_CLOCK_FREQ_HZ_DEFAULT;
/** Holds the HFClk0 clock frequency. Updated by \ref SystemCoreClockUpdate(). */
uint32_t cy_Hfclk0FreqHz = CY_HFCLK0_FREQ_HZ_DEFAULT;
/** Holds the PeriClk clock frequency. Updated by \ref SystemCoreClockUpdate(). */
uint32_t cy_PeriClkFreqHz = CY_PERICLK_FREQ_HZ_DEFAULT;
/* Do not use these definitions directly in your application */
#define CY_DELAY_MS_OVERFLOW_THRESHOLD (0x8000u)
#define CY_DELAY_1K_THRESHOLD (1000u)
#define CY_DELAY_1K_MINUS_1_THRESHOLD (CY_DELAY_1K_THRESHOLD - 1u)
#define CY_DELAY_1M_THRESHOLD (1000000u)
#define CY_DELAY_1M_MINUS_1_THRESHOLD (CY_DELAY_1M_THRESHOLD - 1u)
uint32_t cy_delayFreqHz = CY_SYSTEM_CLOCK_FREQ_HZ_DEFAULT;
uint32_t cy_delayFreqKhz = (CY_SYSTEM_CLOCK_FREQ_HZ_DEFAULT + CY_DELAY_1K_MINUS_1_THRESHOLD) / CY_DELAY_1K_THRESHOLD;
uint8_t cy_delayFreqMhz = (uint8_t)((CY_SYSTEM_CLOCK_FREQ_HZ_DEFAULT + CY_DELAY_1M_MINUS_1_THRESHOLD) / CY_DELAY_1M_THRESHOLD);
uint32_t cy_delay32kMs = CY_DELAY_MS_OVERFLOW_THRESHOLD * ((CY_SYSTEM_CLOCK_FREQ_HZ_DEFAULT + CY_DELAY_1K_MINUS_1_THRESHOLD) /
CY_DELAY_1K_THRESHOLD);
/*******************************************************************************
* Table Of Content (TOC)
*******************************************************************************/
typedef struct {
uint32_t securityImageAddr; /** Address of security image */
uint32_t flashBootAddr; /** Address of Flash Boot stored in SFLASH */
uint32_t flashBootSize; /** Size of Flash Boot (in bytes) */
uint32_t objectOneAddr; /** Address of next object (0 if none) */
uint32_t objectOneSize; /** Size of next object (0 if none) */
uint32_t objectTwoAddr; /** Address of next object (0 if none) */
uint32_t objectTwoSize; /** Size of next object (0 if none) */
uint32_t objectThreeAddr; /** Address of next object (0 if none) */
uint32_t objectThreeSize; /** Size of next object (0 if none) */
uint32_t userAppAddr; /** Address of start of User Application */
uint32_t userAppSize; /** Size of the User Application */
uint32_t keyStorageAddr; /** Address of Key Storage Flash Blocks. */
uint32_t keyStorageSize; /** Size of key storage area in bytes. */
uint32_t smifConfigAddr; /** SMIF Configuration Table */
uint32_t reserved[113u];
uint32_t crc; /** 0x1FC CRC16-CCITT */
} Cy_TOC_Type;
#define CY_TOC_BASE (0x100FFE00UL)
#define CY_TOC ((Cy_TOC_Type*) CY_TOC_BASE)
#ifndef CY_TOC_FLASH_BOOT_ADDR
#define CY_TOC_FLASH_BOOT_ADDR (0x160020D8UL)
#endif
#ifndef CY_TOC_FLASH_BOOT_SIZE
#define CY_TOC_FLASH_BOOT_SIZE (0x2000UL)
#endif
#ifndef CY_TOC_SMIF_CONFIG_ADDR
#define CY_TOC_SMIF_CONFIG_ADDR (0xFFFFFFFFUL)
#endif
#ifndef CY_TOC_USER_APP_ADDR
#define CY_TOC_USER_APP_ADDR (0x10000000UL)
#endif
#ifndef CY_TOC_USER_APP_SIZE
#define CY_TOC_USER_APP_SIZE (0x80000UL)
#endif
#ifdef CY_TOC_PRESENT
#if defined(__GNUC__) || defined(__ARMCC_VERSION)
__attribute__ ((__section__(".cy_toc"), used))
#elif defined(__ICCARM__)
#pragma location=".cy_toc"
#endif
Cy_TOC_Type cyToc = {
.flashBootAddr = CY_TOC_FLASH_BOOT_ADDR,
.flashBootSize = CY_TOC_FLASH_BOOT_SIZE,
.smifConfigAddr = CY_TOC_SMIF_CONFIG_ADDR,
.userAppAddr = CY_TOC_USER_APP_ADDR,
.userAppSize = CY_TOC_USER_APP_SIZE
};
#endif
/*******************************************************************************
* SystemInit()
*******************************************************************************/
#define CY_WDT_LOCK_BIT0 ((uint32_t)0x01u << 30u)
#define CY_WDT_LOCK_BIT1 ((uint32_t)0x01u << 31u)
/* CLK_FLL_CONFIG default values, from MXS40-IP-SRSS */
#define CY_FB_CLK_FLL_CONFIG_VALUE (0x01000000u)
#define CY_FB_CLK_FLL_CONFIG2_VALUE (0x00020001u)
#define CY_FB_CLK_FLL_CONFIG3_VALUE (0x00002800u)
#define CY_FB_CLK_FLL_CONFIG4_VALUE (0x000000FFu)
/*******************************************************************************
* Function Name: SystemInit
****************************************************************************//**
*
* Initializes the system.
*
*******************************************************************************/
void SystemInit(void)
{
/* Restores FLL to default state as it is not restored by ROM code */
uint32_t copy = SRSS->CLK_FLL_CONFIG;
copy &= ~SRSS_CLK_FLL_CONFIG_FLL_ENABLE_Msk;
SRSS->CLK_FLL_CONFIG = copy;
copy = SRSS->CLK_ROOT_SELECT[0u];
copy &= ~SRSS_CLK_ROOT_SELECT_ROOT_DIV_Msk; /* Set ROOT_DIV = 0*/
SRSS->CLK_ROOT_SELECT[0u] = copy;
SRSS->CLK_FLL_CONFIG = CY_FB_CLK_FLL_CONFIG_VALUE;
SRSS->CLK_FLL_CONFIG2 = CY_FB_CLK_FLL_CONFIG2_VALUE;
SRSS->CLK_FLL_CONFIG3 = CY_FB_CLK_FLL_CONFIG3_VALUE;
SRSS->CLK_FLL_CONFIG4 = CY_FB_CLK_FLL_CONFIG4_VALUE;
/* Unlock and disable WDT */
SRSS->WDT_CTL = ((SRSS->WDT_CTL & (uint32_t)(~SRSS_WDT_CTL_WDT_LOCK_Msk)) | CY_WDT_LOCK_BIT0);
SRSS->WDT_CTL = (SRSS->WDT_CTL | CY_WDT_LOCK_BIT1);
SRSS->WDT_CTL &= (~ (uint32_t) SRSS_WDT_CTL_WDT_EN_Msk);
Cy_SystemInit();
SystemCoreClockUpdate();
Cy_SystemInitIpc();
Cy_SMIF_StartupCallBack();
}
/*******************************************************************************
* Function Name: Cy_SystemInit
****************************************************************************//**
*
* The function is called during device startup. Once project compiled as part of
* the PSoC Creator project, the Cy_SystemInit() function is generated by the
* PSoC Creator.
*
* The function generated by PSoC Creator performs all of the necessary device
* configuration based on the design settings. This includes settings from the
* Design Wide Resources (DWR) such as Clocks and Pins as well as any component
* configuration that is necessary.
*
*******************************************************************************/
__WEAK void Cy_SystemInit(void)
{
/* Empty weak function. The actual implementation to be in the PSoC Creator
* generated strong function.
*/
}
/*******************************************************************************
* Function Name: Cy_SMIF_StartupCallBack
****************************************************************************//**
*
* The function is called during device startup. Once SMIF functionality is
* required, user should implement the function as described by the SMIF
* documentation.
*
******************************************************************************/
__WEAK void Cy_SMIF_StartupCallBack(void)
{
/* Empty weak function. The actual implementation to be in the user's
* strong function.
*/
}
/*******************************************************************************
* Function Name: SystemCoreClockUpdate
****************************************************************************//**
*
* Get Core Clock Frequency.
*
* Update \ref SystemCoreClock, \ref cy_Hfclk0FreqHz, and \ref cy_PeriClkFreqHz.
*
*******************************************************************************/
void SystemCoreClockUpdate (void)
{
uint32_t srcFreqHz;
uint32_t pathFreqHz;
uint32_t slowClkDiv;
uint32_t periClkDiv;
uint32_t rootPath;
uint32_t srcClk;
/* Get root path clock for the high-frequency clock # 0 */
rootPath = _FLD2VAL(SRSS_CLK_ROOT_SELECT_ROOT_MUX, SRSS->CLK_ROOT_SELECT[0u]);
/* Get source of the root path clock */
srcClk = _FLD2VAL(SRSS_CLK_PATH_SELECT_PATH_MUX, SRSS->CLK_PATH_SELECT[rootPath]);
/* Get frequency of the source */
switch (srcClk)
{
case CY_ROOT_PATH_SRC_IMO:
srcFreqHz = CY_IMO_FREQ_HZ;
break;
case CY_ROOT_PATH_SRC_EXT:
srcFreqHz = CY_EXT_FREQ_HZ;
break;
case CY_ROOT_PATH_SRC_ECO:
srcFreqHz = CY_ECO_FREQ_HZ;
break;
#if defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL)
case CY_ROOT_PATH_SRC_ALTHF:
srcFreqHz = cy_BleEcoClockFreqHz;
break;
#endif /* defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL) */
default:
srcFreqHz = CY_EXT_FREQ_HZ;
break;
}
if (rootPath == 0UL)
{
/* FLL */
bool fllLocked = ( 0UL != _FLD2VAL(SRSS_CLK_FLL_STATUS_LOCKED, SRSS->CLK_FLL_STATUS));
bool fllOutputOutput = ( 3UL == _FLD2VAL(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, SRSS->CLK_FLL_CONFIG3));
bool fllOutputAuto = ((0UL == _FLD2VAL(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, SRSS->CLK_FLL_CONFIG3)) ||
(1UL == _FLD2VAL(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, SRSS->CLK_FLL_CONFIG3)));
if ((fllOutputAuto && fllLocked) || fllOutputOutput)
{
uint32_t fllMult;
uint32_t refDiv;
uint32_t outputDiv;
fllMult = _FLD2VAL(SRSS_CLK_FLL_CONFIG_FLL_MULT, SRSS->CLK_FLL_CONFIG);
refDiv = _FLD2VAL(SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV, SRSS->CLK_FLL_CONFIG2);
outputDiv = _FLD2VAL(SRSS_CLK_FLL_CONFIG_FLL_OUTPUT_DIV, SRSS->CLK_FLL_CONFIG) + 1UL;
pathFreqHz = ((srcFreqHz / refDiv) * fllMult) / outputDiv;
}
else
{
pathFreqHz = srcFreqHz;
}
}
else if (rootPath == 1UL)
{
/* PLL */
bool pllLocked = ( 0UL != _FLD2VAL(SRSS_CLK_PLL_STATUS_LOCKED, SRSS->CLK_PLL_STATUS[0UL]));
bool pllOutputOutput = ( 3UL == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS->CLK_PLL_CONFIG[0UL]));
bool pllOutputAuto = ((0UL == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS->CLK_PLL_CONFIG[0UL])) ||
(1UL == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS->CLK_PLL_CONFIG[0UL])));
if ((pllOutputAuto && pllLocked) || pllOutputOutput)
{
uint32_t feedbackDiv;
uint32_t referenceDiv;
uint32_t outputDiv;
feedbackDiv = _FLD2VAL(SRSS_CLK_PLL_CONFIG_FEEDBACK_DIV, SRSS->CLK_PLL_CONFIG[0UL]);
referenceDiv = _FLD2VAL(SRSS_CLK_PLL_CONFIG_REFERENCE_DIV, SRSS->CLK_PLL_CONFIG[0UL]);
outputDiv = _FLD2VAL(SRSS_CLK_PLL_CONFIG_OUTPUT_DIV, SRSS->CLK_PLL_CONFIG[0UL]);
pathFreqHz = ((srcFreqHz * feedbackDiv) / referenceDiv) / outputDiv;
}
else
{
pathFreqHz = srcFreqHz;
}
}
else
{
/* Direct */
pathFreqHz = srcFreqHz;
}
/* Get frequency after hf_clk pre-divider */
pathFreqHz = pathFreqHz >> _FLD2VAL(SRSS_CLK_ROOT_SELECT_ROOT_DIV, SRSS->CLK_ROOT_SELECT[0u]);
cy_Hfclk0FreqHz = pathFreqHz;
/* Slow Clock Divider */
slowClkDiv = 1u + _FLD2VAL(CPUSS_CM0_CLOCK_CTL_SLOW_INT_DIV, CPUSS->CM0_CLOCK_CTL);
/* Peripheral Clock Divider */
periClkDiv = 1u + _FLD2VAL(CPUSS_CM0_CLOCK_CTL_PERI_INT_DIV, CPUSS->CM0_CLOCK_CTL);
pathFreqHz = pathFreqHz / periClkDiv;
cy_PeriClkFreqHz = pathFreqHz;
pathFreqHz = pathFreqHz / slowClkDiv;
SystemCoreClock = pathFreqHz;
/* Sets clock frequency for Delay API */
cy_delayFreqHz = SystemCoreClock;
cy_delayFreqMhz = (uint8_t)((cy_delayFreqHz + CY_DELAY_1M_MINUS_1_THRESHOLD) / CY_DELAY_1M_THRESHOLD);
cy_delayFreqKhz = (cy_delayFreqHz + CY_DELAY_1K_MINUS_1_THRESHOLD) / CY_DELAY_1K_THRESHOLD;
cy_delay32kMs = CY_DELAY_MS_OVERFLOW_THRESHOLD * cy_delayFreqKhz;
}
/*******************************************************************************
* Function Name: Cy_SystemInitIpcCyPipeIsr
****************************************************************************//**
*
* This is the Interrupt Service Routine for the Cypress Pipe.
*
*******************************************************************************/
void Cy_SystemInitIpcCyPipeIsr(void)
{
Cy_IPC_PIPE_ExecCallback(&cy_ipc_pipe_sysEpArray[CY_IPC_EP_CYPIPE_ADDR]);
}
/*******************************************************************************
* Function Name: Cy_SystemInitIpc
****************************************************************************//**
*
* Performs initial IPC configuration.
*
*******************************************************************************/
void Cy_SystemInitIpc(void)
{
cy_stc_sysint_t ipc_intr_cypipeConfig;
Cy_IPC_PIPE_Config(cy_ipc_pipe_sysEpArray);
#if (CY_CPU_CORTEX_M0P)
/* Initialize the lock subsystem. Should be called only on one CPU. */
(void) Cy_IPC_LOCK_Init(CY_IPC_LOCK_COUNT, ipcLockArray);
#endif /* (CY_CPU_CORTEX_M0P) */
/* Initialize the pipe endpoints */
Cy_IPC_PIPE_Init(CY_IPC_EP_CYPIPE_ADDR, ipc_pipe_cyPipeCbArray, CY_IPC_CYPIPE_CLIENT_CNT, CY_IPC_CYPIPE_CONFIG);
/* Configure interrupts */
ipc_intr_cypipeConfig.intrSrc = CY_IPC_INTR_CYPIPE_SRC;
ipc_intr_cypipeConfig.intrCm0p = CY_IPC_INTR_CYPIPE_CM0SRC;
ipc_intr_cypipeConfig.intrPriority = CY_IPC_INTR_CYPIPE_PRIO;
Cy_SysInt_Init(&ipc_intr_cypipeConfig, &Cy_SystemInitIpcCyPipeIsr);
#if (CY_CPU_CORTEX_M0P)
NVIC_EnableIRQ((IRQn_Type)ipc_intr_cypipeConfig.intrCm0p);
#else
NVIC_EnableIRQ((IRQn_Type)ipc_intr_cypipeConfig.intrSrc);
#endif
}
/*******************************************************************************
* Function Name: Cy_SysGetCM4Status
****************************************************************************//**
*
* Gets the Cortex-M4 core mode.
*
* \return \ref group_startup_macro
*
*******************************************************************************/
uint32_t Cy_SysGetCM4Status(void)
{
uint32_t returnValue;
uint32_t regValue;
regValue = CPUSS->CM4_PWR_CTL & CPUSS_CM4_PWR_CTL_Msk;
switch(regValue)
{
case CPUSS_CM4_PWR_CTL_DISABLED:
returnValue = CY_SYS_CM4_STATUS_DISABLED;
break;
case CPUSS_CM4_PWR_CTL_RETAINED:
returnValue = CY_SYS_CM4_STATUS_RETAINED;
break;
case CPUSS_CM4_PWR_CTL_ENABLED:
returnValue = CY_SYS_CM4_STATUS_ENABLED;
break;
case CPUSS_CM4_PWR_CTL_RESET_MODE:
returnValue = CY_SYS_CM4_STATUS_RESET;
break;
default:
returnValue = CY_SYS_CM4_STATUS_UNKNOWN;
break;
}
return (returnValue);
}
/*******************************************************************************
* Function Name: Cy_SysEnableCM4
****************************************************************************//**
*
* Enables the Cortex-M4 core. The CPU is enabled once if it was in the disabled
* or retained mode. If the CPU is enabled, the vector table base address is
* updated and software reset of the Cortex-M4 core is performed.
*
* \param vectorTableOffset The offset of the vector table base address from
* memory address 0x00000000. The offset should be multiple to 1024 bytes.
*
*******************************************************************************/
void Cy_SysEnableCM4(uint32_t vectorTableOffset)
{
uint32_t cm4Status;
uint32_t interruptState;
interruptState = Cy_SaveIRQ();
cm4Status = Cy_SysGetCM4Status();
switch(cm4Status)
{
case CY_SYS_CM4_STATUS_DISABLED:
CPUSS->CM4_VECTOR_TABLE_BASE = vectorTableOffset;
CPUSS->CM4_PWR_CTL |= _VAL2FLD(CPUSS_CM4_PWR_CTL_POWER, 1UL);
CPUSS->CM4_PWR_CTL &= ~_VAL2FLD(CPUSS_CM4_PWR_CTL_ISOLATE, 1UL);
CPUSS->CM4_PWR_CTL &= ~_VAL2FLD(CPUSS_CM4_PWR_CTL_RESET, 1UL);
CPUSS->CM4_PWR_CTL |= _VAL2FLD(CPUSS_CM4_PWR_CTL_CLOCK, 1UL);
break;
case CY_SYS_CM4_STATUS_RETAINED:
CPUSS->CM4_VECTOR_TABLE_BASE = vectorTableOffset;
CPUSS->CM4_PWR_CTL |= _VAL2FLD(CPUSS_CM4_PWR_CTL_POWER, 1UL);
CPUSS->CM4_PWR_CTL &= ~_VAL2FLD(CPUSS_CM4_PWR_CTL_RETAIN, 1UL);
CPUSS->CM4_PWR_CTL &= ~_VAL2FLD(CPUSS_CM4_PWR_CTL_ISOLATE, 1UL);
CPUSS->CM4_PWR_CTL |= _VAL2FLD(CPUSS_CM4_PWR_CTL_CLOCK, 1UL);
break;
case CY_SYS_CM4_STATUS_RESET:
CPUSS->CM4_VECTOR_TABLE_BASE = vectorTableOffset;
CPUSS->CM4_PWR_CTL &= ~_VAL2FLD(CPUSS_CM4_PWR_CTL_RESET, 1UL);
CPUSS->CM4_PWR_CTL |= _VAL2FLD(CPUSS_CM4_PWR_CTL_CLOCK, 1UL);
break;
case CY_SYS_CM4_STATUS_ENABLED:
CPUSS->CM4_VECTOR_TABLE_BASE = vectorTableOffset;
/* Move to Reset from Enabled state */
CPUSS->CM4_PWR_CTL &= ~_VAL2FLD(CPUSS_CM4_PWR_CTL_CLOCK, 1UL);
CPUSS->CM4_PWR_CTL |= _VAL2FLD(CPUSS_CM4_PWR_CTL_RESET, 1UL);
/* Move to Enabled from Reset state */
CPUSS->CM4_PWR_CTL &= ~_VAL2FLD(CPUSS_CM4_PWR_CTL_RESET, 1UL);
CPUSS->CM4_PWR_CTL |= _VAL2FLD(CPUSS_CM4_PWR_CTL_CLOCK, 1UL);
break;
default:
/* Do nothing if Cortex-M4 is already enabled. */
break;
}
Cy_RestoreIRQ(interruptState);
}
/*******************************************************************************
* Function Name: Cy_SysDisableCM4
****************************************************************************//**
*
* Disables the Cortex-M4 core.
*
* \warning Do not call the function while the Cortex-M4 is executing because
* such a call may corrupt/abort a pending bus-transaction by the CPU and cause
* unexpected behavior in the system including a deadlock. Call the function
* while the Cortex-M4 core is in the Sleep or Deep Sleep low-power mode. Use
* the \ref group_syspm Power Management (syspm) API to put the CPU into the
* low-power modes. Use the \ref SysPm_ReadStatus() to get a status of the CPU.
*
*******************************************************************************/
void Cy_SysDisableCM4(void)
{
uint32_t cm4Status;
uint32_t interruptState;
interruptState = Cy_SaveIRQ();
cm4Status = Cy_SysGetCM4Status();
switch(cm4Status)
{
case CY_SYS_CM4_STATUS_ENABLED:
CPUSS->CM4_PWR_CTL &= ~_VAL2FLD(CPUSS_CM4_PWR_CTL_CLOCK, 1UL);
CPUSS->CM4_PWR_CTL |= _VAL2FLD(CPUSS_CM4_PWR_CTL_RESET, 1UL);
CPUSS->CM4_PWR_CTL |= _VAL2FLD(CPUSS_CM4_PWR_CTL_ISOLATE, 1UL);
CPUSS->CM4_PWR_CTL &= ~_VAL2FLD(CPUSS_CM4_PWR_CTL_POWER, 1UL);
break;
case CY_SYS_CM4_STATUS_RETAINED:
CPUSS->CM4_PWR_CTL |= _VAL2FLD(CPUSS_CM4_PWR_CTL_RESET, 1UL);
CPUSS->CM4_PWR_CTL &= ~_VAL2FLD(CPUSS_CM4_PWR_CTL_RETAIN, 1UL);
break;
default:
/* Do nothing if Cortex-M4 is already disabled. */
break;
}
Cy_RestoreIRQ(interruptState);
}
/*******************************************************************************
* Function Name: Cy_SysRetainCM4
****************************************************************************//**
*
* Retains the Cortex-M4 core.
*
* \warning Do not call the function while the Cortex-M4 is executing because
* such a call may corrupt/abort a pending bus-transaction by the CPU and cause
* unexpected behavior in the system including a deadlock. Call the function
* while the Cortex-M4 core is in the Sleep or Deep Sleep low-power mode. Use
* the \ref group_syspm Power Management (syspm) API to put the CPU into the
* low-power modes. Use the \ref Cy_SysPm_ReadStatus() to get a status of the CPU.
*
*******************************************************************************/
void Cy_SysRetainCM4(void)
{
uint32_t cm4Status;
uint32_t interruptState;
interruptState = Cy_SaveIRQ();
cm4Status = Cy_SysGetCM4Status();
switch(cm4Status)
{
case CY_SYS_CM4_STATUS_ENABLED:
CPUSS->CM4_PWR_CTL &= ~_VAL2FLD(CPUSS_CM4_PWR_CTL_CLOCK, 1UL);
CPUSS->CM4_PWR_CTL |= _VAL2FLD(CPUSS_CM4_PWR_CTL_ISOLATE, 1UL);
CPUSS->CM4_PWR_CTL |= _VAL2FLD(CPUSS_CM4_PWR_CTL_RETAIN, 1UL);
CPUSS->CM4_PWR_CTL &= ~_VAL2FLD(CPUSS_CM4_PWR_CTL_POWER, 1UL);
break;
case CY_SYS_CM4_STATUS_DISABLED:
/* Switch from the DISABLED to the RETAINED state is not valid.
* Do nothing in this case. */
break;
default:
/* Do nothing if Cortex-M4 is already in the RETAINED state. */
break;
}
Cy_RestoreIRQ(interruptState);
}
/*******************************************************************************
* Function Name: Cy_SysResetCM4
****************************************************************************//**
*
* Resets the Cortex-M4 core.
*
* \warning Do not call the function while the Cortex-M4 is executing because
* such a call may corrupt/abort a pending bus-transaction by the CPU and cause
* unexpected behavior in the system including a deadlock. Call the function
* while the Cortex-M4 core is in the Sleep or Deep Sleep low-power mode. Use
* the \ref group_syspm Power Management (syspm) API to put the CPU into the
* low-power modes. Use the \ref Cy_SysPm_ReadStatus() to get a status of the CPU.
*
*******************************************************************************/
void Cy_SysResetCM4(void)
{
uint32_t cm4Status;
uint32_t interruptState;
interruptState = Cy_SaveIRQ();
cm4Status = Cy_SysGetCM4Status();
switch(cm4Status)
{
case CY_SYS_CM4_STATUS_ENABLED:
CPUSS->CM4_PWR_CTL &= ~_VAL2FLD(CPUSS_CM4_PWR_CTL_CLOCK, 1UL);
CPUSS->CM4_PWR_CTL |= _VAL2FLD(CPUSS_CM4_PWR_CTL_RESET, 1UL);
break;
case CY_SYS_CM4_STATUS_DISABLED:
CPUSS->CM4_PWR_CTL |= _VAL2FLD(CPUSS_CM4_PWR_CTL_ISOLATE, 1UL);
CPUSS->CM4_PWR_CTL &= ~_VAL2FLD(CPUSS_CM4_PWR_CTL_POWER, 1UL);
break;
default:
/* Do nothing if Cortex-M4 is already in the RETAINED state. */
break;
}
Cy_RestoreIRQ(interruptState);
}
/* [] END OF FILE */

View File

@ -0,0 +1,185 @@
/***************************************************************************//**
* \file system_psoc6ble_cm0plus.h
* \version 1.0
*
* \brief Device system header file.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#ifndef _SYSTEM_PSOC6BLE_CM0PLUS_H_
#define _SYSTEM_PSOC6BLE_CM0PLUS_H_
#define CY_CM0 ((defined(__GNUC__) && (__ARM_ARCH == 6) && (__ARM_ARCH_6M__ == 1)) || \
(defined (__ICCARM__) && (__CORE__ == __ARM6M__)) || \
(defined(__ARMCC_VERSION) && (__TARGET_ARCH_THUMB == 3)))
#if (CY_CM0)
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** startup_m0p driver identifier */
#define CY_STARTUP_M0P_ID ((uint32_t)((uint32_t)((0x0Eu) & 0x3FFFu) << 18u))
/*******************************************************************************
* Inter Process Communication (IPC)
*******************************************************************************/
#define CY_IPC_CYPIPE_CLIENT_CNT (8u) /* Number of the defined clients */
#define CY_IPC_EP_MAX (CPUSS_IPC_IPC_NR) /* Number of IPC structures */
#define CY_IPC_EP_CYPIPE_CM0_ADDR (0u)
#define CY_IPC_EP_CYPIPE_CM4_ADDR (1u)
#if (CY_CM0)
#define CY_IPC_EP_CYPIPE_ADDR CY_IPC_EP_CYPIPE_CM0_ADDR
#else
#define CY_IPC_EP_CYPIPE_ADDR CY_IPC_EP_CYPIPE_CM4_ADDR
#endif /* (CY_CM0) */
#define CY_IPC_LOCK_COUNT (128u) /* Locks number. Must be a multiple of 32 */
/* IPC channels */
#define CY_IPC_CHAN_SYSCALL_CM0 (0u) /* System calls for the CM0 processor */
#define CY_IPC_CHAN_SYSCALL_CM4 (1u) /* System calls for the 1st non-CM0 processor */
#if (CY_CM0)
#define CY_IPC_CHAN_SYSCALL CY_IPC_CHAN_SYSCALL_CM0
#else
#define CY_IPC_CHAN_SYSCALL CY_IPC_CHAN_SYSCALL_CM4
#endif /* (CY_CM0) */
#define CY_IPC_CHAN_SYSCALL_DAP (2u) /* System call */
#define CY_IPC_CHAN_CRYPTO (3u) /* Crypto functions */
#define CY_IPC_CHAN_LOCK (4u) /* IPC Locks (System wide) */
#define CY_IPC_CHAN_CYPIPE_CM0 (5u) /* Cypress Pipe, CM0 side */
#define CY_IPC_CHAN_CYPIPE_CM4 (6u) /* Cypress Pipe, CM4 side */
/* IPC interrupts */
#define CY_IPC_INTR_SYSCALL_CM0 (0u)
#define CY_IPC_INTR_SYSCALL_CM4 (1u)
#define CY_IPC_INTR_SYSCALL_DAP (2u)
#define CY_IPC_INTR_CRYPTO_M0 (3u)
#define CY_IPC_INTR_CRYPTO_M4 (4u)
#define CY_IPC_INTR_CYPIPE_CM0 (5u)
#define CY_IPC_INTR_CYPIPE_CM4 (6u)
/* IPC CM0 Interrupts */
#if (CY_CM0)
#define CY_IPC_INTR_CYPIPE_SRC cpuss_interrupts_ipc5_IRQn
#define CY_IPC_INTR_CYPIPE_CM0SRC NvicMux28
#define CY_IPC_INTR_CYPIPE_PRIO (1u)
#else
#define CY_IPC_INTR_CYPIPE_SRC cpuss_interrupts_ipc6_IRQn
#define CY_IPC_INTR_CYPIPE_CM0SRC (240u) /* Default value of CM0_INT_CTLx register */
#define CY_IPC_INTR_CYPIPE_PRIO (1u)
#endif
/* The System pipe configuration defines the IPC channel number, interrupt number and the pipe interrupt mask */
#define CY_IPC_CYPIPE_INTR_MASK (uint32_t)((0x0001ul << CY_IPC_CHAN_CYPIPE_CM0) | (0x0001ul << CY_IPC_CHAN_CYPIPE_CM4) )
#if (CY_CM0)
#define CY_IPC_CYPIPE_CONFIG (uint32_t)( (CY_IPC_CYPIPE_INTR_MASK << 16) | (CY_IPC_INTR_CYPIPE_CM0 << 8u) | CY_IPC_CHAN_CYPIPE_CM0)
#else
#define CY_IPC_CYPIPE_CONFIG (uint32_t)( (CY_IPC_CYPIPE_INTR_MASK << 16) | (CY_IPC_INTR_CYPIPE_CM4 << 8u) | CY_IPC_CHAN_CYPIPE_CM4)
#endif
/**
* \addtogroup group_startup_functions
* \{
*/
extern void SystemInit(void);
extern void SystemCoreClockUpdate(void);
/** \} group_startup_functions */
/**
* \addtogroup group_startup_functions
* \{
*/
extern uint32_t Cy_SysGetCM4Status(void);
extern void Cy_SysEnableCM4(uint32_t vectorTableOffset);
extern void Cy_SysDisableCM4(void);
extern void Cy_SysRetainCM4(void);
extern void Cy_SysResetCM4(void);
/** \} group_startup_functions */
/** \cond */
extern void Default_Handler (void);
extern uint32_t Cy_SaveIRQ(void);
extern void Cy_RestoreIRQ(uint32_t saved);
extern void Cy_SMIF_StartupCallBack(void);
extern void Cy_SystemInit(void);
extern void Cy_SystemInitIpc(void);
extern void Cy_SystemInitFpuEnable(void);
extern uint32_t cy_delayFreqHz;
extern uint32_t cy_delayFreqKhz;
extern uint8_t cy_delayFreqMhz;
extern uint32_t cy_delay32kMs;
extern uint32_t cy_BleEcoClockFreqHz;
extern uint32_t cy_Hfclk0FreqHz;
extern uint32_t cy_PeriClkFreqHz;
/** \endcond */
/**
* \addtogroup group_startup_macro
* \{
*/
#ifndef CY_CORTEX_M4_APPL_ADDR
/** Start address of the Cortex-M4 application */
#define CY_CORTEX_M4_APPL_ADDR (0x10080000u)
#endif
#define CY_SYS_CM4_STATUS_ENABLED (0u) /**< The Cortex-M4 core is enabled. */
#define CY_SYS_CM4_STATUS_DISABLED (1u) /**< The Cortex-M4 core is disabled. */
#define CY_SYS_CM4_STATUS_RETAINED (2u) /**< The Cortex-M4 core is retained. */
#define CY_SYS_CM4_STATUS_UNKNOWN (3u) /**< The Cortex-M4 core is in the unknown state. Invalid state. */
#define CY_SYS_CM4_STATUS_RESET (4u) /**< The Cortex-M4 core is in the Reset mode. */
/** \} group_startup_macro */
/** \cond */
#define CPUSS_CM4_PWR_CTL_Msk (CPUSS_CM4_PWR_CTL_ISOLATE_Msk | \
CPUSS_CM4_PWR_CTL_RETAIN_Msk | CPUSS_CM4_PWR_CTL_POWER_Msk | \
CPUSS_CM4_PWR_CTL_RESET_Msk | CPUSS_CM4_PWR_CTL_CLOCK_Msk)
#define CPUSS_CM4_PWR_CTL_DISABLED (CPUSS_CM4_PWR_CTL_RESET_Msk | CPUSS_CM4_PWR_CTL_ISOLATE_Msk)
#define CPUSS_CM4_PWR_CTL_RETAINED (CPUSS_CM4_PWR_CTL_RETAIN_Msk | CPUSS_CM4_PWR_CTL_ISOLATE_Msk)
#define CPUSS_CM4_PWR_CTL_ENABLED (CPUSS_CM4_PWR_CTL_CLOCK_Msk | CPUSS_CM4_PWR_CTL_POWER_Msk)
#define CPUSS_CM4_PWR_CTL_RESET_MODE (CPUSS_CM4_PWR_CTL_RESET_Msk | CPUSS_CM4_PWR_CTL_POWER_Msk)
/** \endcond */
/** \addtogroup group_startup_globals
* \{
*/
extern uint32_t SystemCoreClock;
/** \} group_startup_globals */
#ifdef __cplusplus
}
#endif
#endif /* CY_CM0 */
#endif /* _SYSTEM_PSOC6BLE_CM0PLUS_H_ */
/* [] END OF FILE */

View File

@ -0,0 +1,92 @@
/***************************************************************************//**
* \file cy_crypto_config.h
* \version 1.0
*
* \brief
* This file provides user parameters for the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CONFIG_H)
#define CY_CRYPTO_CONFIG_H
/* Defines to configure interrupts used in Crypto driver */
/* Number of Crypto Notify interrupt inputs to CM0+ */
#define CY_CRYPTO_CM0_NOTIFY_INTR_NR (26u)
/* Priority of Crypto Notify interrupt inputs to CM0+ */
#define CY_CRYPTO_NOTIFY_INTR_PR (2u)
/* Number of Crypto release interrupt inputs to CM0+ */
#define CY_CRYPTO_CM0_RELEASE_INTR_NR (27u)
/* Priority of Crypto release interrupt inputs to CM0+ */
#define CY_CRYPTO_RELEASE_INTR_PR (2u)
/* Number of Crypto Error interrupt inputs to CM0+ */
#define CY_CRYPTO_CM0_ERROR_INTR_NR (28u)
/* Priority of Crypto Error interrupt inputs to CM0+ */
#define CY_CRYPTO_CM0_ERROR_INTR_PR (2u)
/* Default Crypto driver configuration */
#define CY_CRYPTO_DEFAULT_CONFIG \
{ \
CY_CRYPTO_CM0_NOTIFY_INTR_NR, \
CY_CRYPTO_NOTIFY_INTR_PR, \
CY_CRYPTO_CM0_RELEASE_INTR_NR, \
CY_CRYPTO_RELEASE_INTR_PR, \
CY_CRYPTO_CM0_ERROR_INTR_NR, \
CY_CRYPTO_CM0_ERROR_INTR_PR, \
NULL, \
NULL, \
NULL \
}
/* Defines to Enable/Disable Crypto functionality */
/* AES CMAC support (0 = no support, 1 = support),
* to run CMAC, AES ECB mode should be enabled */
#define CY_CRYPTO_USER_CMAC (1u)
/* AES ECB cipher support (0 = no support, 1 = support) */
#define CY_CRYPTO_USER_AES_ECB (1u)
/* AES CBC cipher support (0 = no support, 1 = support) */
#define CY_CRYPTO_USER_AES_CBC (1u)
/* AES CFB cipher support (0 = no support, 1 = support) */
#define CY_CRYPTO_USER_AES_CFB (1u)
/* AES CTR cipher support (0 = no support, 1 = support) */
#define CY_CRYPTO_USER_AES_CTR (1u)
/* PKCS1-v1_5 verification support (0 = no support, 1 = support),
* to run PKCS1-v1_ at least one of SHA modes should be enabled */
#define CY_CRYPTO_USER_PKCS1_5 (1u)
/* HMAC support (0 = no support, 1 = support),
* to run HMAC at least one of SHA modes should be enabled */
#define CY_CRYPTO_USER_HMAC (1u)
/* SHA1 hash support (0 = no support, 1 = support) */
#define CY_CRYPTO_USER_SHA1 (1u)
/* SHA 224 and 256 hash support, (0 = no support, 1 = support) */
#define CY_CRYPTO_USER_SHA256 (1u)
/* SHA 384, 512, 512_224 and 512_256 hash support (0 = no support, 1 = support) */
#define CY_CRYPTO_USER_SHA512 (1u)
/* (Triple) DES cipher support (0 = no support, 1 = support) */
#define CY_CRYPTO_USER_DES (1u)
/* Pseudo random number generation support (0 = no support, 1 = support) */
#define CY_CRYPTO_USER_PR (1u)
/* Cyclic Redundancy Check support (0 = no support, 1 = support) */
#define CY_CRYPTO_USER_CRC (1u)
/* Vector unit support (0 = no support, 1 = support) */
#define CY_CRYPTO_USER_VU (1u)
/* True random number generation support (0 = no support, 1 = support) */
#define CY_CRYPTO_USER_TR (1u)
/* String support (0 = no support, 1 = support) */
#define CY_CRYPTO_USER_STR (1u)
#endif /* #if !defined(CY_CRYPTO_CONFIG_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,28 @@
/* ========================================
*
* Copyright YOUR COMPANY, THE YEAR
* All Rights Reserved
* UNPUBLISHED, LICENSED SOFTWARE.
*
* CONFIDENTIAL AND PROPRIETARY INFORMATION
* WHICH IS THE PROPERTY OF your company.
*
* ========================================
*/
#ifndef CYAPICALLBACKS_H
#define CYAPICALLBACKS_H
#ifdef CPU_CORTEX_M0p
/*Define your Cortex-M0p macro callbacks here */
#endif
#ifdef CPU_CORTEX_M4
/*Define your Cortex-M4 macro callbacks here */
#endif
/*For more information, refer to the Writing Code topic in the PSoC Creator Help.*/
#endif /* CYAPICALLBACKS_H */
/* [] */

View File

@ -0,0 +1,5 @@
#ifndef INCLUDED_CYDISABLEDSHEETS_H
#define INCLUDED_CYDISABLEDSHEETS_H
#endif /* INCLUDED_CYDISABLEDSHEETS_H */

View File

@ -0,0 +1,6 @@
#ifndef INCLUDED_CYFITTER_H
#define INCLUDED_CYFITTER_H
#include "cy_device_headers.h"
#endif /* INCLUDED_CYFITTER_H */

View File

@ -0,0 +1,271 @@
/*******************************************************************************
* File Name: cyfitter_cfg.c
*
* PSoC Creator 4.1
*
* Description:
* This file contains device initialization code.
* Except for the user defined sections in CyClockStartupError(), this file should not be modified.
* This file is automatically generated by PSoC Creator.
*
********************************************************************************
* Copyright (c) 2007-2017 Cypress Semiconductor. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
********************************************************************************/
#include <string.h>
#include "cyfitter.h"
#include "gpio/cy_gpio.h"
#include "syslib/cy_syslib.h"
#include "cyfitter_cfg.h"
#include "sysclk/cy_sysclk.h"
#include "systick/cy_systick.h"
#define CY_NEED_CYCLOCKSTARTUPERROR 1
#if defined(__GNUC__) || defined(__ARMCC_VERSION)
#define CYPACKED
#define CYPACKED_ATTR __attribute__ ((packed))
#define CYALIGNED __attribute__ ((aligned))
#define CY_CFG_UNUSED __attribute__ ((unused))
#ifndef CY_CFG_SECTION
#define CY_CFG_SECTION __attribute__ ((section(".psocinit")))
#endif
#if defined(__ARMCC_VERSION)
#define CY_CFG_MEMORY_BARRIER() __memory_changed()
#else
#define CY_CFG_MEMORY_BARRIER() __sync_synchronize()
#endif
#elif defined(__ICCARM__)
#include <intrinsics.h>
#define CYPACKED __packed
#define CYPACKED_ATTR
#define CYALIGNED _Pragma("data_alignment=4")
#define CY_CFG_UNUSED _Pragma("diag_suppress=Pe177")
#define CY_CFG_SECTION _Pragma("location=\".psocinit\"")
#define CY_CFG_MEMORY_BARRIER() __DMB()
#else
#error Unsupported toolchain
#endif
#ifndef CYCODE
#define CYCODE
#endif
#ifndef CYDATA
#define CYDATA
#endif
#ifndef CYFAR
#define CYFAR
#endif
#ifndef CYXDATA
#define CYXDATA
#endif
CY_CFG_UNUSED
static void CYMEMZERO(void *s, size_t n);
CY_CFG_UNUSED
static void CYMEMZERO(void *s, size_t n)
{
(void)memset(s, 0, n);
}
CY_CFG_UNUSED
static void CYCONFIGCPY(void *dest, const void *src, size_t n);
CY_CFG_UNUSED
static void CYCONFIGCPY(void *dest, const void *src, size_t n)
{
(void)memcpy(dest, src, n);
}
CY_CFG_UNUSED
static void CYCONFIGCPYCODE(void *dest, const void *src, size_t n);
CY_CFG_UNUSED
static void CYCONFIGCPYCODE(void *dest, const void *src, size_t n)
{
(void)memcpy(dest, src, n);
}
/* Clock startup error codes */
#define CYCLOCKSTART_NO_ERROR 0u
#define CYCLOCKSTART_XTAL_ERROR 1u
#define CYCLOCKSTART_32KHZ_ERROR 2u
#define CYCLOCKSTART_PLL_ERROR 3u
#define CYCLOCKSTART_FLL_ERROR 4u
#ifdef CY_NEED_CYCLOCKSTARTUPERROR
/*******************************************************************************
* Function Name: CyClockStartupError
********************************************************************************
* Summary:
* If an error is encountered during clock configuration (crystal startup error,
* PLL lock error, etc.), the system will end up here. Unless reimplemented by
* the customer, this function will stop in an infinite loop.
*
* Parameters:
* void
*
* Return:
* void
*
*******************************************************************************/
CY_CFG_UNUSED
static void CyClockStartupError(uint8 errorCode);
CY_CFG_UNUSED
static void CyClockStartupError(uint8 errorCode)
{
/* To remove the compiler warning if errorCode not used. */
errorCode = errorCode;
/* If we have a clock startup error (bad MHz crystal, PLL lock, etc.), */
/* we will end up here to allow the customer to implement something to */
/* deal with the clock condition. */
#ifdef CY_CFG_CLOCK_STARTUP_ERROR_CALLBACK
CY_CFG_Clock_Startup_ErrorCallback();
#else
while(1) {}
#endif /* CY_CFG_CLOCK_STARTUP_ERROR_CALLBACK */
}
#endif
void ClockInit(void);
void ClockInit(void)
{
uint32_t status;
/* Enable all source clocks */
Cy_SysClk_LfClkSetSource(CY_SYSCLK_LFCLK_IN_ILO);
/* Configure CPU clock dividers */
Cy_SysClk_FastClkSetDivider(0u);
Cy_SysClk_PeriClkSetDivider(1u);
Cy_SysClk_SlowClkSetDivider(0u);
/* Configure LF & HF clocks */
Cy_SysClk_HfClockSetSource(0u, CY_SYSCLK_HFCLK_IN_CLKPATH0);
Cy_SysClk_HfClockSetDivider(0u, CY_SYSCLK_HFCLK_NO_DIVIDE);
Cy_SysClk_ClkHfEnable(0u);
/* Configure Path Clocks */
Cy_SysClk_ClkPathSetSource(0, CY_SYSCLK_CLKPATH_IN_IMO);
Cy_SysClk_ClkPathSetSource(1, CY_SYSCLK_CLKPATH_IN_IMO);
Cy_SysClk_ClkPathSetSource(2, CY_SYSCLK_CLKPATH_IN_IMO);
{
const cy_stc_fll_manual_config_t fllConfig =
{
.fllMult = 1825u,
.refDiv = 73u,
.ccoRange = CY_SYSCLK_FLL_CCO_RANGE4,
.enableOutputDiv = true,
.lockTolerance = 20u,
.igain = 7u,
.pgain = 5u,
.settlingCount = 8u,
.outputMode = CY_SYSCLK_FLLPLL_OUTPUT_AUTO
};
status = Cy_SysClk_FllManualConfigure(&fllConfig);
if (CY_RET_SUCCESS != status)
{
CyClockStartupError(CYCLOCKSTART_FLL_ERROR);
}
}
status = Cy_SysClk_FllEnable(10000u);
if (CY_RET_SUCCESS != status)
{
CyClockStartupError(CYCLOCKSTART_FLL_ERROR);
}
/* Configure miscellaneous clocks */
Cy_SysClk_ClkTimerSetSource(CY_SYSCLK_CLKTIMER_IN_IMO);
Cy_SysClk_ClkTimerSetDivider(0);
Cy_SysClk_ClkTimerEnable();
Cy_SysClk_ClkPumpSetSource(CY_SYSCLK_PUMP_IN_CLKPATH0);
Cy_SysClk_ClkPumpSetDivider(CY_SYSCLK_PUMP_NO_DIV);
Cy_SysClk_ClkPumpEnable();
Cy_SysClk_ClkBakSetSource(CY_SYSCLK_BAK_IN_CLKLF);
Cy_SysTick_SetClockSource(CY_SYSTICK_CLOCK_SOURCE_CLK_LF);
Cy_SysClk_IloEnable();
/* Set memory wait states based on 100 MHz HFClk[0] */
Cy_SysLib_SetWaitStates(false, 100);
/* Configure peripheral clock dividers */
/*
no Cy_SysClk_Periph* calls
Each clock is configured in its respective API source file:
* 1M Hz clock (50M/50 Hz) for us_ticker
* oversample*bps Hz clock (50M/(oversample*bps) Hz clock) for serial_api
(depending on the bps)
*/
}
/* Analog API Functions */
/*******************************************************************************
* Function Name: AnalogSetDefault
********************************************************************************
*
* Summary:
* Sets up the analog portions of the chip to default values based on chip
* configuration options from the project.
*
* Parameters:
* void
*
* Return:
* void
*
*******************************************************************************/
static void AnalogSetDefault(void);
static void AnalogSetDefault(void)
{
}
#define CY_AMUX_UNUSED CYREG_CPUSS_CM0_STATUS
/*******************************************************************************
* Function Name: Cy_SystemInit
********************************************************************************
* Summary:
* This function is called by the start-up code for the selected device. It
* performs all of the necessary device configuration based on the design
* settings. This includes settings from the Design Wide Resources (DWR) such
* as Clocks and Pins as well as any component configuration that is necessary.
*
* Parameters:
* void
*
* Return:
* void
*
*******************************************************************************/
void Cy_SystemInit(void)
{
/* Set worst case memory wait states (150 MHz), ClockInit() will update */
Cy_SysLib_SetWaitStates(false, 150);
/* Clock */
ClockInit();
/* Perform basic analog initialization to defaults */
AnalogSetDefault();
__enable_irq();
}

View File

@ -0,0 +1,29 @@
/*******************************************************************************
* File Name: cyfitter_cfg.h
*
* PSoC Creator 4.1
*
* Description:
* This file provides basic startup and mux configuration settings
* This file is automatically generated by PSoC Creator.
*
********************************************************************************
* Copyright (c) 2007-2017 Cypress Semiconductor. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
********************************************************************************/
#ifndef CYFITTER_CFG_H
#define CYFITTER_CFG_H
extern void Cy_SystemInit(void);
/* Analog Set/Unset methods */
#endif /* CYFITTER_CFG_H */
/*[]*/

View File

@ -0,0 +1,6 @@
#ifndef INCLUDED_CYFITTER_GPIO_H
#define INCLUDED_CYFITTER_GPIO_H
#include "cy_device_headers.h"
#endif /* INCLUDED_CYFITTER_GPIO_H */

View File

@ -0,0 +1,48 @@
/*******************************************************************************
* File Name: cymetadata.c
*
* PSoC Creator 4.1
*
* Description:
* This file defines all extra memory spaces that need to be included.
* This file is automatically generated by PSoC Creator.
*
********************************************************************************
* Copyright (c) 2007-2017 Cypress Semiconductor. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
********************************************************************************/
#include "stdint.h"
#if defined(__GNUC__) || defined(__ARMCC_VERSION)
#ifndef CY_META_SECTION
#define CY_META_SECTION __attribute__ ((__section__(".cymeta"), used))
#endif
CY_META_SECTION
#elif defined(__ICCARM__)
#pragma location=".cymeta"
#else
#error "Unsupported toolchain"
#endif
const uint8_t cy_metadata[] = {
0x00u, 0x05u, 0xE2u, 0x01u, 0x11u, 0x00u, 0x00u, 0x01u,
0x00u, 0x00u, 0x00u, 0x00u
};
#if defined(__GNUC__) || defined(__ARMCC_VERSION)
#ifndef CY_CHIP_PROT_SECTION
#define CY_CHIP_PROT_SECTION __attribute__ ((__section__(".cychipprotect"), used))
#endif
CY_CHIP_PROT_SECTION
#elif defined(__ICCARM__)
#pragma location=".cychipprotect"
#else
#error "Unsupported toolchain"
#endif
const uint8_t cy_meta_chipprotect[] = {
0x01u
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,450 @@
/***************************************************************************//**
* \file cy_crypto.h
* \version 1.0
*
* \brief
* This file provides the public interface for the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
********************************************************************************/
/**
* \defgroup group_crypto Cryptography (Crypto)
* \{
* The Crypto driver provides an API to perform
* cryptographic operations on user-designated data.
*
* Crypto supports: DES, TDES, AES (128, 192, 256 bits), SHA, CMAC-AES,
* HMAC, PRNG, TRNG, CRC, the utility functions for string management, and
* the accelerator for arithmetic on very large numbers (up to 4096 bits).
*
* Definitions
*
* <table class="doxtable">
* <tr>
* <th>Term</th>
* <th>Definition</th>
* </tr>
*
* <tr>
* <td>Plaintext</td>
* <td>An unencrypted message</td>
* </tr>
*
* <tr>
* <td>Ciphertext</td>
* <td>An encrypted message</td>
* </tr>
*
* <tr>
* <td>Block cipher</td>
* <td>An encryption function for fixed-size blocks of data.
* This function takes a fixed-size key and a block of plaintext data from
* the message and encrypts it to generate ciphertext. Block ciphers are
* reversible. The function performed on a block of encrypted data will decrypt it.</td>
* </tr>
*
* <tr>
* <td>Block cipher mode</td>
* <td>A mode of encrypting a message using Block ciphers for messages of arbitrary length.
* The message is padded so that its length is an integer multiple of the block size.
* ECB (Electronic Code Book), CBC (Cipher Block Chaining), and CFB (Cipher Feedback) are all
* modes of using Block ciphers to create an encrypted message of arbitrary length.</td>
* </tr>
*
* <tr>
* <td>Data Encryption Standard (DES)</td>
* <td>An obsolete Block cipher supported for legacy
* reasons. It uses a 56-bit key and a 64-bit message block size.</td>
* </tr>
*
* <tr>
* <td>Triple DES (3DES or TDES)</td>
* <td>Uses the DES operation and three DES encryptions in sequence: encrypt
* with DES with one 56-bit key, decrypt with a second 56-bit key, and then encrypt again with either
* the first key or a third 56-bit key. The block size is 64-bits.</td>
* </tr>
*
* <tr>
* <td>Advanced Encryption Standard (AES)</td>
* <td>This Block cipher replaces DES and 3DES.
* It is the current Block cipher standard. Keys can be 128, 192, or 256 bits
* in length and the message block size is 128 bits. This is the US government standard.
* AES is also used for message authentication.</td>
* </tr>
*
* <tr>
* <td>Cipher-based Message Authentication Code (CMAC)</td>
* <td>This method uses a key along with the message
* to compute the MAC value using the AES Block Cipher algorithm.</td>
* </tr>
*
* <tr>
* <td>Secure Hash Algorithm (SHA)</td>
* <td>This function takes a message of the arbitrary length
* and reduces it to a fixed-length residue or message digest after performing a series
* of mathematically defined operations that practically guarantee that any change in
* the message will change the hash value. It is used for message authentication by transmitting
* a message with a hash value appended to it and recalculating the message hash value using
* the same algorithm at the recipient's end. If the hashes differ, then the message is corrupted.</td>
* </tr>
*
* <tr>
* <td>Message Authentication Code (MAC)</td>
* <td>MACs are used to verify that a received message has not been altered.
* This is done by first computing a MAC value at the sender's end and appending it to the transmitted message.
* When the message is received, the MAC is computed again and checked against the MAC value transmitted with
* the message. If they do not match, the message has been altered. Either a Hash algorithm (such as SHA)
* or a Block Cipher (such as AES) can be used to produce the MAC value. Keyed MAC schemes use a Secret Key
* along with the message, thus the Key value must be known to be able to compute the MAC value.</td>
* </tr>
*
* <tr>
* <td>Hash Message Authentication Code (HMAC)</td>
* <td>This method uses a Key along with the message to compute
* the MAC value using a Hash algorithm.</td>
* </tr>
*
* <tr>
* <td>Pseudo Random Number Generator (PRNG)</td>
* <td>Based on Linear Feedback Shift Registers that generate a sequence
* starting from a non-zero seed.</td>
* </tr>
*
* <tr>
* <td>True Random Number Generator (TRNG)</td>
* <td>A block that generates a number that is statistically random and based
* on some physical random variation. The number cannot be duplicated by running the process again.</td>
* </tr>
*
* <tr>
* <td>Symmetric Key Cryptography</td>
* <td>Uses a common, known key to encrypt and decrypt messages (a shared secret between sender
* and receiver). An efficient method used for encrypting and decrypting messages once the authenticity
* of the other party has been established. DES (now obsolete), 3DES, and AES (currently used)
* are well known symmetric cryptography methods.</td>
* </tr>
*
* <tr>
* <td>Asymmetric Key Cryptography</td>
* <td>Also referred to as Public Key encryption. Someone who wishes to receive a message, publishes
* a very large public key (up to 4096 bits currently), which is one of two prime factors of a very large
* number. The other prime factor is the private key of the recipient and a secret. Someone wishing
* to send a message to the publisher of the public key encrypts the message with the public key. This message
* can now be decrypted only with the private key (the other prime factor held secret by the recipient).
* The message is now sent over any channel to the recipient who can decrypt it with the private, secret, key.
* The same process is used to send messages to the sender of the original message. The asymmetric cryptography
* relies on the mathematical impracticality (usually related to the processing power available at any given time)
* of factoring the keys. Common, computationally intensive, asymmetric algorithms are RSA and ECC.
* The public key is described by the pair (n, e) where n is a product of two randomly chosen primes p and q.
* The exponent e is a random integer 1 < e < Q where Q = (p-1) (q-1). The private key d is uniquely
* defined by the integer 1 < d < Q such that ed congruent to 1 (mod Q ).</td>
* </tr>
* </table>
*
* \section group_crypto_configuration Configuration Considerations
*
* Crypto has one configuration structure:
* \ref cy_stc_crypto_config_t
*
* \section group_crypto_MISRA MISRA-C Compliance
* <table class="doxtable">
* <tr>
* <th>MISRA rule</th>
* <th>Rule Class (Required/ Advisory)</th>
* <th>Rule Description</th>
* <th>Description of Deviation(s)</th>
* </tr>
* <tr>
* <td>11.4</td>
* <td>A</td>
* <td>A cast should not be performed between a pointer to the void to a pointer to the object type.</td>
* <td>The cast from the void to pointer and vice versa is used to transmit data via the IPC channel
* by exchanging the pointer. We exchange only one pointer, so there is no way to avoid this cast.</td>
* </tr>
* <tr>
* <td>14.4</td>
* <td>R</td>
* <td>Cast from a pointer to the void to a pointer to the object type.</td>
* <td>The cast from the void to pointer and vice versa is used to transmit data via the IPC channel
* by exchanging the pointer. We exchange only one pointer, so there is no way to avoid this cast.</td>
* </tr>
* <tr>
* <td>16.7</td>
* <td>R</td>
* <td>The object addressed by the pointer parameter '%s' is not modified
* and so the pointer can be of type 'pointer to const'.</td>
* <td>Data addressed by the pointer is modified by Crypto hardware, out of the compiler scope, so
* it can't be the pointer to const.</td>
* </tr>
*
* \section group_crypto_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \section group_crypto_memory_usage Memory Usage
*
* Flash and RAM memory usage for the Crypto driver is shown in the table below.
* The usage is measured for GCC 5.4.1 in a release build with "-Os" optimization
* for Cortex-M0+ and Cortex-M4 cores.
*
* <table class="doxtable">
* <tr><th>Core</th><th>Flash Size</th><th>RAM Size</th></tr>
*
* <tr> <td>CM0p</td> <td>4294</td> <td>5</td> </tr>
* <tr> <td>CM4</td> <td> 692</td> <td>4</td> </tr>
* </table>
*
* \defgroup group_crypto_macro Macro
* \defgroup group_crypto_functions Functions
* \defgroup group_crypto_data_structures Data Structures
* \defgroup group_crypto_enums Enumerated Types
*
*/
#if !defined(CY_CRYPTO_H)
#define CY_CRYPTO_H
#include <stddef.h>
#include <stdbool.h>
#include "cy_device_headers.h"
#include "crypto/cy_crypto_common.h"
#if (CPUSS_CRYPTO_PRESENT == 1)
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_crypto_functions
* \{
*/
cy_en_crypto_status_t Cy_Crypto_Init(cy_stc_crypto_context_t *cryptoContext, cy_stc_crypto_config_t const *configStruct);
cy_en_crypto_status_t Cy_Crypto_DeInit(cy_stc_crypto_context_t *cryptoContext, cy_stc_crypto_config_t const *configStruct);
cy_en_crypto_status_t Cy_Crypto_Enable(cy_stc_crypto_context_t *cryptoContext);
cy_en_crypto_status_t Cy_Crypto_Disable(cy_stc_crypto_context_t *cryptoContext);
cy_en_crypto_status_t Cy_Crypto_Sync(cy_stc_crypto_context_t const *cryptoContext, bool isBlocking);
cy_en_crypto_status_t Cy_Crypto_GetErrorStatus(const cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_hw_error_t *hwErrorCause);
#if ((CPUSS_CRYPTO_PR == 1) && (CY_CRYPTO_USER_PR == 1))
cy_en_crypto_status_t Cy_Crypto_Prng_Init(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_prng_t *cryptoPrngContext,
const uint32_t lfsr32InitState,
const uint32_t lfsr31InitState,
const uint32_t lfsr29InitState);
cy_en_crypto_status_t Cy_Crypto_Prng_Generate(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_prng_t *cryptoPrngContext,
uint32_t const max,
uint32_t *rndNumPtr);
#endif /* #if ((CPUSS_CRYPTO_PR == 1) && (CY_CRYPTO_USER_PR == 1)) */
#if ((CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1))
cy_en_crypto_status_t Cy_Crypto_Aes_Init(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_aes_t *cryptoAesContext,
uint32_t *keyPtr,
cy_en_crypto_aes_key_length_t keyLength);
#if (CY_CRYPTO_USER_AES_ECB == 1)
cy_en_crypto_status_t Cy_Crypto_Aes_Ecb_Run(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_aes_t *cryptoAesContext,
cy_en_crypto_dir_mode_t dirMode,
uint32_t *dstBlockPtr,
uint32_t *srcBlockPtr);
#endif /* #if (CY_CRYPTO_USER_AES_ECB == 1) */
#if (CY_CRYPTO_USER_AES_CBC == 1)
cy_en_crypto_status_t Cy_Crypto_Aes_Cbc_Run(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_aes_t *cryptoAesContext,
cy_en_crypto_dir_mode_t dirMode,
uint32_t srcSize,
uint32_t *ivPtr,
uint32_t *dstPtr,
uint32_t *srcPtr);
#endif /* #if (CY_CRYPTO_USER_AES_CBC == 1) */
#if (CY_CRYPTO_USER_AES_CFB == 1)
cy_en_crypto_status_t Cy_Crypto_Aes_Cfb_Run(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_aes_t *cryptoAesContext,
cy_en_crypto_dir_mode_t dirMode,
uint32_t srcSize,
uint32_t *ivPtr,
uint32_t *dstPtr,
uint32_t *srcPtr);
#endif /* #if (CY_CRYPTO_USER_AES_CFB == 1) */
#if (CY_CRYPTO_USER_AES_CTR == 1)
cy_en_crypto_status_t Cy_Crypto_Aes_Ctr_Run(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_aes_t *cryptoAesContext,
cy_en_crypto_dir_mode_t dirMode,
uint32_t srcSize,
uint32_t *srcOffset,
uint32_t nonceCounter[CY_CRYPTO_AES_BLOCK_SIZE / 8u],
uint32_t streamBlock[CY_CRYPTO_AES_BLOCK_SIZE / 8u],
uint32_t *dstPtr,
uint32_t *srcPtr);
#endif /* #if (CY_CRYPTO_USER_AES_CTR == 1) */
#if (CY_CRYPTO_USER_CMAC == 1)
cy_en_crypto_status_t Cy_Crypto_Aes_Cmac_Run(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_aes_t *cryptoAesContext,
uint32_t *srcPtr,
uint32_t srcSize,
uint32_t *keyPtr,
cy_en_crypto_aes_key_length_t keyLength,
uint32_t *cmacPtr);
#endif /* #if (CY_CRYPTO_USER_CMAC == 1) */
#endif /* #if ((CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1)) */
#if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1))
cy_en_crypto_status_t Cy_Crypto_Sha_Run(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_sha_t *cryptoShaContext,
uint32_t *messagePtr,
uint32_t messageSize,
uint32_t *digestPtr,
cy_en_crypto_sha_mode_t mode);
#endif /* #if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1)) */
#if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_HMAC == 1))
cy_en_crypto_status_t Cy_Crypto_Hmac_Run(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_sha_t *cryptoShaContext,
uint32_t *hmacPtr,
uint32_t *messagePtr,
uint32_t messageSize,
uint32_t *keyPtr,
uint32_t keyLength,
cy_en_crypto_sha_mode_t mode);
#endif /* #if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_HMAC == 1)) */
#if ((CPUSS_CRYPTO_STR == 1) && (CY_CRYPTO_USER_STR == 1))
cy_en_crypto_status_t Cy_Crypto_Str_MemCpy(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_str_t *cryptoMemContext,
void *dstPtr,
void const *srcPtr,
uint16_t size);
cy_en_crypto_status_t Cy_Crypto_Str_MemSet(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_str_t *cryptoMemContext,
void *dstPtr,
uint8_t data,
uint16_t size);
cy_en_crypto_status_t Cy_Crypto_Str_MemCmp(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_str_t *cryptoMemContext,
void const *src0Ptr,
void const *src1Ptr,
uint16_t size,
uint32_t *resultPtr);
cy_en_crypto_status_t Cy_Crypto_Str_MemXor(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_str_t *cryptoMemContext,
void const *src0Ptr,
void const *src1Ptr,
void *dstPtr,
uint16_t size);
#endif /* #if ((CPUSS_CRYPTO_STR == 1) && (CY_CRYPTO_USER_STR == 1)) */
#if ((CPUSS_CRYPTO_CRC == 1) && (CY_CRYPTO_USER_CRC == 1))
cy_en_crypto_status_t Cy_Crypto_Crc_Init(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_crc_t *cryptoCrcContext,
uint32_t polynomial,
uint8_t dataReverse,
uint8_t dataXor,
uint8_t remReverse,
uint32_t remXor);
cy_en_crypto_status_t Cy_Crypto_Crc_Run(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_crc_t *cryptoCrcContext,
void *dataPtr,
uint16_t dataSize,
uint32_t *crcPtr,
uint32_t lfsrInitState);
#endif /* #if ((CPUSS_CRYPTO_CRC == 1) && (CY_CRYPTO_USER_CRC == 1)) */
#if ((CPUSS_CRYPTO_TR == 1) && (CY_CRYPTO_USER_TR == 1))
cy_en_crypto_status_t Cy_Crypto_Trng_Generate(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_trng_t *cryptoTrngContext,
uint32_t GAROPol,
uint32_t FIROPol,
uint32_t max,
uint32_t *rndNumPtr);
#endif /* #if ((CPUSS_CRYPTO_TR == 1) && (CY_CRYPTO_USER_TR == 1)) */
#if ((CPUSS_CRYPTO_DES == 1) && (CY_CRYPTO_USER_DES == 1))
cy_en_crypto_status_t Cy_Crypto_Des_Run(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_des_t *cryptoDesContext,
cy_en_crypto_dir_mode_t dirMode,
uint32_t *keyPtr,
uint32_t *dstBlockPtr,
uint32_t *srcBlockPtr);
cy_en_crypto_status_t Cy_Crypto_Tdes_Run(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_des_t *cryptoDesContext,
cy_en_crypto_dir_mode_t dirMode,
uint32_t *keyPtr,
uint32_t *dstBlockPtr,
uint32_t *srcBlockPtr);
#endif /* #if ((CPUSS_CRYPTO_DES == 1) && (CY_CRYPTO_USER_DES == 1)) */
#if ((CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1))
cy_en_crypto_status_t Cy_Crypto_Rsa_Proc(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_rsa_t *cryptoRsaContext,
cy_stc_crypto_rsa_pub_key_t const *pubKeyPtr,
uint32_t const *messageePtr,
uint32_t messageLength,
uint32_t const *processedMessagePtr);
cy_en_crypto_status_t Cy_Crypto_Rsa_CalcCoefs(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_rsa_t *cryptoRsaContext,
cy_stc_crypto_rsa_pub_key_t const *pubKeyPtr);
#endif /* #if ((CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1)) */
#if (CY_CRYPTO_USER_PKCS1_5 == 1)
cy_en_crypto_status_t Cy_Crypto_Rsa_Verify(cy_stc_crypto_context_t *cryptoContext,
cy_stc_crypto_context_rsa_ver_t *cryptoRsaVerContext,
cy_en_crypto_rsa_ver_result_t *verResult,
cy_en_crypto_sha_mode_t digestType,
uint32_t const *digestPtr,
uint32_t const *decryptedSignaturePtr,
uint32_t decryptedSignatureLength);
void Cy_Crypto_Rsa_InvertEndianness(void *inArrPtr, uint32_t byteSize);
#endif /* #if (CY_CRYPTO_USER_PKCS1_5 == 1) */
/** \} group_crypto_functions */
#if defined(__cplusplus)
}
#endif
#endif /* #if (CPUSS_CRYPTO_PRESENT == 1) */
#endif /* (CY_CRYPTO_H) */
/** \} group_crypto */
/* [] END OF FILE */

View File

@ -0,0 +1,504 @@
/***************************************************************************//**
* \file cy_crypto_common.h
* \version 1.0
*
* \brief
* This file provides common constants and parameters
* for the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_COMMON_H)
#define CY_CRYPTO_COMMON_H
#include <stddef.h>
#include "cy_device_headers.h"
#include "syslib/cy_syslib.h"
#include "cy_crypto_config.h"
#if (CPUSS_CRYPTO_PRESENT == 1)
/**
* \addtogroup group_crypto_macro
* \{
*/
/** Driver major version */
#define CY_CRYPTO_DRV_VERSION_MAJOR (1)
/** Driver minor version */
#define CY_CRYPTO_DRV_VERSION_MINOR (0)
/** Defines Crypto_Sync blocking execution type parameter */
#define CY_CRYPTO_SYNC_BLOCKING (true)
/** Defines Crypto_Sync non-blocking execution type parameter */
#define CY_CRYPTO_SYNC_NON_BLOCKING (false)
/** Defines the Crypto DES key size (in bytes) */
#define CY_CRYPTO_DES_KEY_SIZE (8u)
/** Defines the Crypto TDES key size (in bytes) */
#define CY_CRYPTO_TDES_KEY_SIZE (24u)
/** Defines the Crypto AES block size (in bytes) */
#define CY_CRYPTO_AES_BLOCK_SIZE (16u)
/** Defines the Crypto AES key maximum size (in bytes) */
#define CY_CRYPTO_AES_128_KEY_SIZE (16u)
/** Defines the Crypto AES key maximum size (in bytes) */
#define CY_CRYPTO_AES_192_KEY_SIZE (24u)
/** Defines the Crypto AES key maximum size (in bytes) */
#define CY_CRYPTO_AES_256_KEY_SIZE (32u)
/** Defines size of the AES block, in four byte words */
#define CY_CRYPTO_AES_BLOCK_SIZE_U32 (4UL)
/** Defines the Crypto notify interrupt number */
#define CY_CRYPTO_NOTIFY_INTR CY_IPC_INTR_CRYPTO_M0
/* Overall AES enable */
#define CY_CRYPTO_USER_AES_ENABLE (CY_CRYPTO_USER_AES_ECB | \
CY_CRYPTO_USER_AES_CBC | \
CY_CRYPTO_USER_AES_CFB | \
CY_CRYPTO_USER_AES_CTR | \
CY_CRYPTO_USER_CMAC)
/* Overall SHA enable */
#define CY_CRYPTO_USER_SHA_ENABLE (CY_CRYPTO_USER_SHA1 | \
CY_CRYPTO_USER_SHA256 | \
CY_CRYPTO_USER_SHA512 | \
CY_CRYPTO_USER_HMAC)
#if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1))
/** Hash size for the SHA1 mode, in Bytes */
#define CY_CRYPTO_SHA1_DIGEST_SIZE (20u)
/** Hash size for the SHA224 mode, in Bytes */
#define CY_CRYPTO_SHA224_DIGEST_SIZE (28u)
/** Hash size for the SHA256 mode, in Bytes */
#define CY_CRYPTO_SHA256_DIGEST_SIZE (32u)
/** Hash size for the SHA384 mode, in Bytes */
#define CY_CRYPTO_SHA384_DIGEST_SIZE (48u)
/** Hash size for the SHA512 mode, in Bytes */
#define CY_CRYPTO_SHA512_DIGEST_SIZE (64u)
/** Hash size for the SHA512_224 mode, in Bytes */
#define CY_CRYPTO_SHA512_224_DIGEST_SIZE (28u)
/** Hash size for the SHA512_256 mode, in Bytes */
#define CY_CRYPTO_SHA512_256_DIGEST_SIZE (32u)
#endif /* #if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1)) */
#if ((CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1))
/** Processed message size for the RSA 1024Bit mode, in Bytes */
#define CY_CRYPTO_RSA1024_MESSAGE_SIZE (128)
/** Processed message size for the RSA 1536Bit mode, in Bytes */
#define CY_CRYPTO_RSA1536_MESSAGE_SIZE (192)
/** Processed message size for the RSA 2048Bit mode, in Bytes */
#define CY_CRYPTO_RSA2048_MESSAGE_SIZE (256)
#endif /* #if ((CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1)) */
/** Defines the Crypto release interrupt number */
#define CY_CRYPTO_RELEASE_INTR CY_IPC_INTR_CRYPTO_M4
/** Crypto Driver PDL ID */
#define CY_CRYPTO_ID CY_PDL_DRV_ID(0x0Cu)
/** \} group_crypto_macro */
/**
* \addtogroup group_crypto_data_structures
* \{
*/
/** The Crypto user callback function type called at the end of Crypto calculation. */
typedef void (*cy_crypto_callback_ptr_t)(void);
/** The Crypto configuration structure. */
typedef struct
{
uint8_t cm0NotifyIntrNum; /**< Specifies the notify interrupt number for the CM0 core */
uint8_t notifyIntrPrior; /**< Specifies the notify interrupt priority */
uint8_t cm0ReleaseIntrNum; /**< Specifies the release interrupt number for the CM0 core */
uint8_t releaseIntrPrior; /**< Specifies the release interrupt priority */
uint8_t cm0CryptoErrorIntrNum; /**< Specifies the interrupt number for the Crypto error handler */
uint8_t cryptoErrorIntrPrior; /**< Specifies the interrupt priority for the Crypto error handler */
cy_crypto_callback_ptr_t userCompleteCallback; /**< User callback, called after Crypto HW completes calculation */
cy_israddress userGetDataHandler; /**< User IPC process data IRQ handler */
cy_israddress userErrorHandler; /**< User error IRQ handler */
} cy_stc_crypto_config_t;
#if ((CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1))
/** The structure for storing the RSA public key. */
typedef struct
{
uint8_t *moduloPtr; /**< The pointer to the modulus for both public and private keys. */
uint32_t moduloLength; /**< The modulus length, in bits, maximum supported size is 2048Bit */
uint8_t *pubExpPtr; /**< The pointer to the RSA key public exponent */
uint32_t pubExpLength; /**< The RSA key public exponent length, in bits, maximum supported size is 256Bit */
uint8_t *barretCoefPtr; /**< The pointer to the Barrett coefficient of size (moduloLength + 1) */
uint8_t *inverseModuloPtr; /**< The pointer to the binary inverse of the modulo of size moduloLength */
uint8_t *rBarPtr; /**< The pointer to the (2^moduloLength mod modulo) of size moduloLength */
} cy_stc_crypto_rsa_pub_key_t;
typedef enum
{
CY_CRYPTO_RSA_VERIFY_SUCCESS = 0x00u, /**< RSA verify SUCCESS */
CY_CRYPTO_RSA_VERIFY_FAIL = 0x01u /**< RSA verify FAILED */
} cy_en_crypto_rsa_ver_result_t;
#endif /* #if ((CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1)) */
/** Structure for storing a description of a Crypto hardware error */
typedef struct
{
uint32_t errorStatus0; /**< Captures error description information:
for INSTR_OPC_ERROR: - violating the instruction.
for INSTR_CC_ERROR : - violating the instruction condition code.
for BUS_ERROR : - violating the transfer address. */
uint32_t errorStatus1; /**< [31] - Specifies if ERROR_STATUS0 and ERROR_STATUS1 capture is valid error-information.
[26..24] - The error source:
"0": INSTR_OPC_ERROR - an instruction decoder error.
"1": INSTR_CC_ERROR - an instruction condition code-error.
"2": BUS_ERROR - a bus master interface AHB-Lite bus-error.
"3": TR_AP_DETECT_ERROR.
[23..0] - Captures error description information.
For BUS_ERROR: - violating the transfer, read the attribute (DATA23[0]).
- violating the transfer, the size attribute (DATA23[5:4]).
"0": an 8-bit transfer; "1": 16 bits transfer; "2": 32-bit transfer. */
} cy_stc_crypto_hw_error_t;
/** \} group_crypto_data_structures */
/**
* \addtogroup group_crypto_enums
* \{
*/
/** The key length options for the AES method. */
#if ((CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1))
typedef enum
{
CY_CRYPTO_KEY_AES_128 = 0x00u, /**< The AES key size is 128 bits */
CY_CRYPTO_KEY_AES_192 = 0x01u, /**< The AES key size is 192 bits */
CY_CRYPTO_KEY_AES_256 = 0x02u /**< The AES key size is 256 bits */
} cy_en_crypto_aes_key_length_t;
#endif /* #if ((CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1)) */
/** Defines the direction of the Crypto methods*/
typedef enum
{
CY_CRYPTO_ENCRYPT = 0x00u, /**< The forward mode, plain text will be encrypted into cipher text */
CY_CRYPTO_DECRYPT = 0x01u /**< The reverse mode, cipher text will be decrypted into plain text */
} cy_en_crypto_dir_mode_t;
/** Define modes of SHA method */
#if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1))
typedef enum
{
#if ((CPUSS_CRYPTO_SHA1 == 1) && (CY_CRYPTO_USER_SHA1 == 1))
CY_CRYPTO_MODE_SHA1 = 0x00u, /**< Sets the SHA1 mode */
#endif /* #if ((CPUSS_CRYPTO_SHA1 == 1) && (CY_CRYPTO_USER_SHA1 == 1)) */
#if ((CPUSS_CRYPTO_SHA256 == 1) && (CY_CRYPTO_USER_SHA256 == 1))
CY_CRYPTO_MODE_SHA224 = 0x11u, /**< Sets the SHA224 mode */
CY_CRYPTO_MODE_SHA256 = 0x01u, /**< Sets the SHA256 mode */
#endif /* #if ((CPUSS_CRYPTO_SHA256 == 1) && (CY_CRYPTO_USER_SHA256 == 1)) */
#if ((CPUSS_CRYPTO_SHA512 == 1) && (CY_CRYPTO_USER_SHA512 == 1))
CY_CRYPTO_MODE_SHA384 = 0x12u, /**< Sets the SHA384 mode */
CY_CRYPTO_MODE_SHA512 = 0x02u, /**< Sets the SHA512 mode */
CY_CRYPTO_MODE_SHA512_256 = 0x22u, /**< Sets the SHA512/256 mode */
CY_CRYPTO_MODE_SHA512_224 = 0x32u /**< Sets the SHA512/224 mode */
#endif /* #if ((CPUSS_CRYPTO_SHA512 == 1) && (CY_CRYPTO_USER_SHA512 == 1)) */
} cy_en_crypto_sha_mode_t;
#endif /* #if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1)) */
/** Errors of the Crypto block */
typedef enum
{
/** Operation completed successfully. */
CY_CRYPTO_SUCCESS = 0x00u,
/** A hardware error occurred, detailed information is in stc_crypto_hw_error_t. */
CY_CRYPTO_HW_ERROR = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x01u,
/** The size of input data is not multiple of 16. */
CY_CRYPTO_SIZE_NOT_X16 = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x02u,
/** The key for the DES method is weak. */
CY_CRYPTO_DES_WEAK_KEY = CY_CRYPTO_ID | CY_PDL_STATUS_WARNING | 0x03u,
/** Communication between the client-server via IPC is broken. */
CY_CRYPTO_COMM_FAIL = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x04u,
/** The Crypto server is not started. */
CY_CRYPTO_SERVER_NOT_STARTED = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x06u,
/** Communication between the client-server via IPC is broken. */
CY_CRYPTO_SERVER_BUSY = CY_CRYPTO_ID | CY_PDL_STATUS_INFO | 0x07u,
/** The Crypto driver is not initialized. */
CY_CRYPTO_NOT_INITIALIZED = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x08u,
/** The Crypto hardware is not enabled. */
CY_CRYPTO_HW_NOT_ENABLED = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x09u,
/** The Crypto hardware is not enabled. */
CY_CRYPTO_NOT_SUPPORTED = CY_CRYPTO_ID | CY_PDL_STATUS_ERROR | 0x0Au
} cy_en_crypto_status_t;
/** \} group_crypto_enums */
/** Instruction to communicate between Client and Server */
typedef enum
{
CY_CRYPTO_INSTR_UNKNOWN = 0x00u,
CY_CRYPTO_INSTR_ENABLE = 0x01u,
CY_CRYPTO_INSTR_DISABLE = 0x02u,
#if ((CPUSS_CRYPTO_PR == 1) && (CY_CRYPTO_USER_PR == 1))
CY_CRYPTO_INSTR_PRNG_INIT = 0x03u,
CY_CRYPTO_INSTR_PRNG = 0x04u,
#endif /* #if ((CPUSS_CRYPTO_PR == 1) && (CY_CRYPTO_USER_PR == 1)) */
#if ((CPUSS_CRYPTO_TR == 1) && (CY_CRYPTO_USER_TR == 1))
CY_CRYPTO_INSTR_TRNG_INIT = 0x05u,
CY_CRYPTO_INSTR_TRNG = 0x06u,
#endif /* #if ((CPUSS_CRYPTO_PR == 1) && (CY_CRYPTO_USER_TR == 1)) */
#if ((CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1))
CY_CRYPTO_INSTR_AES_INIT = 0x07u,
#if (CY_CRYPTO_USER_AES_ECB == 1)
CY_CRYPTO_INSTR_AES_ECB = 0x08u,
#endif /* #if (CRYPTO_USER_AES_ECB == 1) */
#if (CY_CRYPTO_USER_AES_CBC == 1)
CY_CRYPTO_INSTR_AES_CBC = 0x09u,
#endif /* #if (CRYPTO_USER_AES_CBC == 1) */
#if (CY_CRYPTO_USER_AES_CFB == 1)
CY_CRYPTO_INSTR_AES_CFB = 0x0Au,
#endif /* #if (CRYPTO_USER_AES_CFB == 1) */
#if (CY_CRYPTO_USER_AES_CTR == 1)
CY_CRYPTO_INSTR_AES_CTR = 0x0Bu,
#endif /* #if (CRYPTO_USER_AES_CTR == 1) */
#if (CY_CRYPTO_USER_CMAC == 1)
CY_CRYPTO_INSTR_CMAC = 0x0Cu,
#endif /* #if (CY_CRYPTO_USER_CMAC == 1) */
#endif /* #if ((CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1)) */
#if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1))
CY_CRYPTO_INSTR_SHA = 0x0Du,
#endif /* #if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1)) */
#if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_HMAC == 1))
CY_CRYPTO_INSTR_HMAC = 0x0Eu,
#endif /* #if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_HMAC == 1)) */
#if ((CPUSS_CRYPTO_STR == 1) && (CY_CRYPTO_USER_STR == 1))
CY_CRYPTO_INSTR_MEM_CPY = 0x0Fu,
CY_CRYPTO_INSTR_MEM_SET = 0x10u,
CY_CRYPTO_INSTR_MEM_CMP = 0x11u,
CY_CRYPTO_INSTR_MEM_XOR = 0x12u,
#endif /* #if ((CPUSS_CRYPTO_STR == 1) && (CY_CRYPTO_USER_STR == 1)) */
#if ((CPUSS_CRYPTO_CRC == 1) && (CY_CRYPTO_USER_CRC == 1))
CY_CRYPTO_INSTR_CRC_INIT = 0x13u,
CY_CRYPTO_INSTR_CRC = 0x14u,
#endif /* #if ((CPUSS_CRYPTO_CRC == 1) && (CY_CRYPTO_USER_CRC == 1)) */
#if ((CPUSS_CRYPTO_DES == 1) && (CY_CRYPTO_USER_DES == 1))
CY_CRYPTO_INSTR_DES = 0x15u,
CY_CRYPTO_INSTR_3DES = 0x16u,
#endif /* #if ((CPUSS_CRYPTO_DES == 1) && (CY_CRYPTO_USER_DES == 1)) */
#if ((CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1))
CY_CRYPTO_INSTR_RSA_PROC = 0x17u,
CY_CRYPTO_INSTR_RSA_COEF = 0x18u,
#endif /* #if ((CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1)) */
#if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1))
CY_CRYPTO_INSTR_RSA_VER = 0x19u
#endif /* #if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_HMAC == 1)) */
} cy_en_crypto_comm_instr_t;
/**
* \addtogroup group_crypto_data_structures
* \{
*/
/** Structure for storing the AES state */
#if ((CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1))
typedef struct
{
uint32_t *keyPtr; /**< Pointer to AES key */
uint32_t invKey[CY_CRYPTO_AES_256_KEY_SIZE / 4u]; /**< Storage for inversed key */
cy_en_crypto_aes_key_length_t keyLength; /**< AES key length */
uint32_t blockIdx; /**< AES processed block index (for CMAC, SHA operations) */
} cy_stc_crypto_aes_state_t;
#endif /* #if ((CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1)) */
/*************************************************************
* Structures used for communication between Client and Server
***************************************************************/
/** Structure for storing the global context */
typedef struct
{
cy_en_crypto_comm_instr_t instr; /**< Server instruction code */
cy_en_crypto_status_t resp; /**< Response from executed crypto function */
cy_stc_crypto_hw_error_t hwErrorStatus; /**< Hardware processing errors */
void *xdata; /**< Pointer to the crypto function specific context data */
} cy_stc_crypto_context_t;
#if ((CPUSS_CRYPTO_DES == 1) && (CY_CRYPTO_USER_DES == 1))
/** Structure for storing the DES context */
typedef struct
{
cy_en_crypto_dir_mode_t dirMode; /**< Operation direction (Encrypt / Decrypt) */
uint32_t *keyPtr; /**< Pointer to key data */
uint32_t *dstPtr; /**< Pointer to data destination block */
uint32_t *srcPtr; /**< Pointer to data source block */
} cy_stc_crypto_context_des_t;
#endif /* #if ((CPUSS_CRYPTO_DES == 1) && (CY_CRYPTO_USER_DES == 1)) */
#if ((CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1))
/** Structure for storing the AES context */
typedef struct
{
cy_stc_crypto_aes_state_t aesState; /**< AES state data */
cy_en_crypto_dir_mode_t dirMode; /**< Operation direction (Encrypt / Decrypt) */
uint32_t srcSize; /**< Operation data size */
uint32_t *srcOffset; /**< Size of the last non-complete block (for CTR mode only) */
uint32_t *ivPtr; /**< Initialization vector, in the CTR mode is used as nonceCounter */
uint32_t *streamBlock; /**< AES processed block pointer (for CTR mode only) */
uint32_t *dstPtr; /**< Pointer to data destination block */
uint32_t *srcPtr; /**< Pointer to data source block */
} cy_stc_crypto_context_aes_t;
#endif /* #if ((CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1)) */
#if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1))
/** Structure for storing the SHA context */
typedef struct
{
uint32_t *messagePtr; /**< Pointer to data source block */
uint32_t messageSize; /**< Operation data size */
uint32_t *dstPtr; /**< Pointer to data destination block */
cy_en_crypto_sha_mode_t mode; /**< SHA mode */
uint32_t *keyPtr; /**< Pointer to key data (for HMAC only) */
uint32_t keyLength; /**< Key data length (for HMAC only) */
} cy_stc_crypto_context_sha_t;
#endif /* #if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1)) */
#if ((CPUSS_CRYPTO_PR == 1) && (CY_CRYPTO_USER_PR == 1))
/** Structure for storing the PRNG context */
typedef struct
{
uint32_t lfsr32InitState; /**< lfsr32 initialization data */
uint32_t lfsr31InitState; /**< lfsr31 initialization data */
uint32_t lfsr29InitState; /**< lfsr29 initialization data */
uint32_t max; /**< Maximum of the generated value */
uint32_t *prngNumPtr; /**< Pointer to generated value */
} cy_stc_crypto_context_prng_t;
#endif /* #if ((CPUSS_CRYPTO_PR == 1) && (CY_CRYPTO_USER_PR == 1)) */
#if ((CPUSS_CRYPTO_TR == 1) && (CY_CRYPTO_USER_TR == 1))
/** Structure for storing the TRNG context */
typedef struct
{
uint32_t GAROPol; /**< The polynomial for the programmable Galois ring oscillator (TR_GARO_CTL).
The polynomial is represented WITHOUT the high order bit (this bit is always assumed '1').
The polynomial should be aligned so that more significant bits (bit 30 and down)
contain the polynomial and less significant bits (bit 0 and up) contain padding '0's. */
uint32_t FIROPol; /**< The polynomial for the programmable Fibonacci ring oscillator(TR_FIRO_CTL).
The polynomial is represented WITHOUT the high order bit (this bit is always assumed '1').
The polynomial should be aligned so that more significant bits (bit 30 and down)
contain the polynomial and less significant bits (bit 0 and up) contain padding '0's. */
uint32_t max; /**< Maximum of the generated value */
uint32_t *trngNumPtr; /**< Pointer to generated value */
} cy_stc_crypto_context_trng_t;
#endif /* #if ((CPUSS_CRYPTO_TR == 1) && (CY_CRYPTO_USER_TR == 1)) */
#if ((CPUSS_CRYPTO_STR == 1) && (CY_CRYPTO_USER_STR == 1))
/** Structure for storing the STR context */
typedef struct
{
void const *srcPtr0; /**< Pointer to 1-st string source */
void const *srcPtr1; /**< Pointer to 2-nd string source */
void *dstPtr; /**< Pointer to string destination */
uint32_t dataSize; /**< Operation data size */
uint32_t data; /**< Operation data value (for memory setting) */
} cy_stc_crypto_context_str_t;
#endif /* #if ((CPUSS_CRYPTO_STR == 1) && (CY_CRYPTO_USER_STR == 1)) */
#if ((CPUSS_CRYPTO_CRC == 1) && (CY_CRYPTO_USER_CRC == 1))
/** Structure for storing the CRC context */
typedef struct
{
void* srcDataPtr; /**< Pointer to data source block */
uint32_t dataSize; /**< operation data size */
uint32_t *crcPtr; /**< Pointer to CRC destination variable */
uint32_t polynomial; /**< Polynomial for CRC calculate */
uint32_t lfsrInitState; /**< CRC calculation initial value */
uint32_t dataReverse; /**< Input data reverse flag */
uint32_t dataXor; /**< Input data XOR flag */
uint32_t remReverse; /**< Output data reverse flag */
uint32_t remXor; /**< Output data XOR flag */
} cy_stc_crypto_context_crc_t;
#endif /* #if ((CPUSS_CRYPTO_CRC == 1) && (CY_CRYPTO_USER_CRC == 1)) */
#if (CY_CRYPTO_USER_PKCS1_5 == 1)
/** Structure for storing the RSA verify context */
typedef struct
{
cy_en_crypto_rsa_ver_result_t *verResult; /**< Pointer to verification result /ref cy_en_crypto_rsa_ver_result_t */
cy_en_crypto_sha_mode_t digestType; /**< SHA digess type, used with SHA calculation of the message */
uint32_t const *hashPtr; /**< SHA digest of the message, calculated with digestType */
uint32_t const *decryptedSignaturePtr; /**< Previously decrypted RSA signature */
uint32_t decryptedSignatureLength; /**< Length of the decrypted RSA signature */
} cy_stc_crypto_context_rsa_ver_t;
#endif /* #if (CY_CRYPTO_USER_PKCS1_5 == 1) */
#if ((CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1))
/** Structure for storing the RSA process context */
typedef struct
{
cy_stc_crypto_rsa_pub_key_t *keyPtr; /**< Pointer to key data */
uint32_t const *messagePtr; /**< Pointer to data source block */
uint32_t messageLength; /**< Operation data size */
uint32_t const *resultPtr; /**< Pointer to data destination block */
} cy_stc_crypto_context_rsa_t;
#endif /* #if ((CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1)) */
/** \} group_crypto_data_structures */
#endif /* (CPUSS_CRYPTO_PRESENT == 1) */
#endif /* #if !defined(CY_CRYPTO_COMMON_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,405 @@
/***************************************************************************//**
* \file cy_crypto_core_aes.c
* \version 1.0
*
* \brief
* This file provides the source code fro the API for the AES method
* in the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "crypto/cy_crypto_common.h"
#include "crypto/cy_crypto_core_aes.h"
#include "crypto/cy_crypto_core_instructions.h"
#include "crypto/cy_crypto_core_util.h"
#include "crypto/cy_crypto_core_str.h"
#include "syslib/cy_syslib.h"
#include <string.h>
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1))
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Aes_InvKey
****************************************************************************//**
*
* Calculates an inverse block cipher key from the block cipher key.
*
* This function available for CM0+ core only.
*
* \param cryptoAesContext
* The pointer to the stc_crypto_context_t structure which stores all internal variables
* the Crypto driver requires.
*
*******************************************************************************/
void Cy_Crypto_Core_Aes_InvKey(cy_stc_crypto_aes_state_t const *aesStatePtr)
{
/* Issue the AES_KEY instruction to prepare the key for decrypt operation */
Cy_Crypto_SetReg2Instr((uint32_t)aesStatePtr->keyPtr, (uint32_t)aesStatePtr->invKey);
Cy_Crypto_Run2ParamInstr(CY_CRYPTO_AES_KEY_OPC,
CY_CRYPTO_RSRC0_SHIFT,
CY_CRYPTO_RSRC8_SHIFT);
/* Wait until the AES instruction is complete */
while(0uL != _FLD2VAL(CRYPTO_STATUS_AES_BUSY, CRYPTO->STATUS))
{
}
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Aes_Init
****************************************************************************//**
*
* Sets Aes mode and prepare inversed key.
*
* This function available for CM0+ core only.
*
* \param cryptoAesContext
* The pointer to the stc_crypto_context_t structure which stores
* the Crypto driver context.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Aes_Init(cy_stc_crypto_context_aes_t const *cryptoAesContext)
{
/* Set the key mode: 128, 192 or 256 Bit */
CRYPTO->AES_CTL = (uint32_t)(_VAL2FLD(CRYPTO_AES_CTL_KEY_SIZE,
(uint32_t)(cryptoAesContext->aesState.keyLength)));
Cy_Crypto_Core_Aes_InvKey(&(cryptoAesContext->aesState));
return (CY_CRYPTO_SUCCESS);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Aes_ProcessBlock
****************************************************************************//**
*
* Performs the AES block cipher.
*
* This function available for CM0+ core only.
*
* \param aesStatePtr
* The pointer to the aesStatePtr structure which stores the AES context.
*
* \param dirMode
* One of CRYPTO_ENCRYPT or CRYPTO_DECRYPT.
*
* \param dstBlockPtr
* The pointer to the cipher text.
*
* \param srcBlockPtr
* The pointer to the plain text. Must be 4-Byte aligned!
*
*******************************************************************************/
void Cy_Crypto_Core_Aes_ProcessBlock(cy_stc_crypto_aes_state_t const *aesStatePtr,
cy_en_crypto_dir_mode_t dirMode,
uint32_t *dstBlockPtr,
uint32_t const *srcBlockPtr)
{
Cy_Crypto_SetReg3Instr((CY_CRYPTO_DECRYPT == dirMode) ? (uint32_t)aesStatePtr->invKey : (uint32_t)aesStatePtr->keyPtr,
(uint32_t)srcBlockPtr,
(uint32_t)dstBlockPtr);
Cy_Crypto_Run3ParamInstr((CY_CRYPTO_DECRYPT == dirMode) ? CY_CRYPTO_AES_BLOCK_INV_OPC : CY_CRYPTO_AES_BLOCK_OPC,
CY_CRYPTO_RSRC0_SHIFT,
CY_CRYPTO_RSRC4_SHIFT,
CY_CRYPTO_RSRC12_SHIFT);
/* Wait until the AES instruction is complete */
while(0uL != _FLD2VAL(CRYPTO_STATUS_AES_BUSY, CRYPTO->STATUS))
{
}
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Aes_Xor
****************************************************************************//**
*
* Perform the XOR of two 16-Byte memory structures.
* All addresses must be 4-Byte aligned!
*
* This function available for CM0+ core only.
*
* \param src0BlockPtr
* The pointer to the first memory structure. Must be 4-Byte aligned!
*
* \param src1BlockPtr
* The pointer to the second memory structure. Must be 4-Byte aligned!
*
* \param dstBlockPtr
* The pointer to the memory structure with the XOR results.
*
*******************************************************************************/
void Cy_Crypto_Core_Aes_Xor(uint32_t const *src0BlockPtr,
uint32_t const *src1BlockPtr,
uint32_t *dstBlockPtr)
{
Cy_Crypto_SetReg3Instr((uint32_t)src0BlockPtr,
(uint32_t)src1BlockPtr,
(uint32_t)dstBlockPtr);
/* Issue the AES_XOR instruction */
Cy_Crypto_Run3ParamInstr(CY_CRYPTO_AES_XOR_OPC,
CY_CRYPTO_RSRC0_SHIFT,
CY_CRYPTO_RSRC4_SHIFT,
CY_CRYPTO_RSRC8_SHIFT);
/* Wait until the AES instruction is complete */
while(0uL != _FLD2VAL(CRYPTO_STATUS_AES_BUSY, CRYPTO->STATUS))
{
}
}
#if (CY_CRYPTO_USER_AES_ECB == 1)
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Aes_Ecb
****************************************************************************//**
*
* Performs AES operation on one Block.
*
* This function available for CM0+ core only.
*
* \param cryptoAesContext
* The pointer to the stc_crypto_context_t structure which stores
* Crypto driver context.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Aes_Ecb(cy_stc_crypto_context_aes_t *cryptoAesContext)
{
cy_stc_crypto_aes_state_t aesStateTmp = cryptoAesContext->aesState;
cy_en_crypto_dir_mode_t dirModeTmp = (cy_en_crypto_dir_mode_t)(cryptoAesContext->dirMode);
Cy_Crypto_Core_Aes_ProcessBlock(&aesStateTmp,
dirModeTmp,
cryptoAesContext->dstPtr,
cryptoAesContext->srcPtr);
return (CY_CRYPTO_SUCCESS);
}
#endif /* #if (CY_CRYPTO_USER_AES_ECB == 1) */
#if (CY_CRYPTO_USER_AES_CBC == 1)
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Aes_Cbc
****************************************************************************//**
*
* Performs AES operation on a plain text with Cipher Block Chaining (CBC).
*
* This function available for CM0+ core only.
*
* \param cryptoAesContext
* The pointer to stc_crypto_context_t structure which stores
* the Crypto driver context.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Aes_Cbc(cy_stc_crypto_context_aes_t *cryptoAesContext)
{
uint32_t size = (uint32_t)cryptoAesContext->srcSize;
uint32_t *dstPtrTmp = (uint32_t*)cryptoAesContext->dstPtr;
uint32_t *srcPtrTmp = (uint32_t*)cryptoAesContext->srcPtr;
cy_en_crypto_dir_mode_t dirModeTmp = cryptoAesContext->dirMode;
uint32_t *tempBuffPtr = (uint32_t*)CRYPTO->MEM_BUFF;
cy_en_crypto_status_t result;
/* Check whether the data size is multiple of 16 */
if (0uL != (uint32_t)(size & (CY_CRYPTO_AES_BLOCK_SIZE - 1u)))
{
result = CY_CRYPTO_SIZE_NOT_X16;
}
else
{
/* Copy the Initialization Vector to the local buffer because it changes during calculation */
memcpy(tempBuffPtr, cryptoAesContext->ivPtr, CY_CRYPTO_AES_BLOCK_SIZE);
if (CY_CRYPTO_DECRYPT == dirModeTmp)
{
while (size > 0uL)
{
Cy_Crypto_Core_Aes_ProcessBlock(&(cryptoAesContext->aesState),
dirModeTmp,
dstPtrTmp,
srcPtrTmp);
Cy_Crypto_Core_Aes_Xor(tempBuffPtr, dstPtrTmp, dstPtrTmp);
memcpy(tempBuffPtr, srcPtrTmp, CY_CRYPTO_AES_BLOCK_SIZE);
srcPtrTmp += CY_CRYPTO_AES_BLOCK_SIZE_U32;
dstPtrTmp += CY_CRYPTO_AES_BLOCK_SIZE_U32;
size -= CY_CRYPTO_AES_BLOCK_SIZE;
}
}
else
{
while (size > 0uL)
{
Cy_Crypto_Core_Aes_Xor(srcPtrTmp, tempBuffPtr, tempBuffPtr);
Cy_Crypto_Core_Aes_ProcessBlock(&(cryptoAesContext->aesState),
dirModeTmp,
dstPtrTmp,
tempBuffPtr);
memcpy(tempBuffPtr, dstPtrTmp, CY_CRYPTO_AES_BLOCK_SIZE);
srcPtrTmp += CY_CRYPTO_AES_BLOCK_SIZE_U32;
dstPtrTmp += CY_CRYPTO_AES_BLOCK_SIZE_U32;
size -= CY_CRYPTO_AES_BLOCK_SIZE;
}
}
result = CY_CRYPTO_SUCCESS;
}
return (result);
}
#endif /* #if (CY_CRYPTO_USER_AES_CBC == 1) */
#if (CY_CRYPTO_USER_AES_CFB == 1)
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Aes_Cfb
********************************************************************************
*
* Performs AES operation on a plain text with the Cipher Feedback Block method (CFB).
*
* This function available for CM0+ core only.
*
* \param cryptoAesContext
* The pointer to the stc_crypto_context_t structure which stores
* the Crypto driver context.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Aes_Cfb(cy_stc_crypto_context_aes_t *cryptoAesContext)
{
uint32_t size = (uint32_t)cryptoAesContext->srcSize;
uint32_t *tempIvPtr = (uint32_t*)CRYPTO->MEM_BUFF;
uint32_t *dstPtrTmp = (uint32_t*)cryptoAesContext->dstPtr;
uint32_t *srcPtrTmp = (uint32_t*)cryptoAesContext->srcPtr;
uint32_t *tempBuffPtr = (uint32_t*)dstPtrTmp;
cy_en_crypto_status_t result;
/* Check whether the data size is multiple of 16 */
if (0uL != (size & (CY_CRYPTO_AES_BLOCK_SIZE - 1u)))
{
result = CY_CRYPTO_SIZE_NOT_X16;
}
else
{
/* Copy the Initialization Vector to local buffer because it is changing during calculation */
memcpy(tempIvPtr, cryptoAesContext->ivPtr, CY_CRYPTO_AES_BLOCK_SIZE);
if (CY_CRYPTO_DECRYPT == cryptoAesContext->dirMode)
{
tempBuffPtr = srcPtrTmp;
}
while (size > 0uL)
{
/* In this mode, (CFB) is always an encryption! */
Cy_Crypto_Core_Aes_ProcessBlock(&(cryptoAesContext->aesState),
CY_CRYPTO_ENCRYPT,
dstPtrTmp,
tempIvPtr);
Cy_Crypto_Core_Aes_Xor(srcPtrTmp, dstPtrTmp, dstPtrTmp);
memcpy(tempIvPtr, tempBuffPtr, CY_CRYPTO_AES_BLOCK_SIZE);
srcPtrTmp += CY_CRYPTO_AES_BLOCK_SIZE_U32;
dstPtrTmp += CY_CRYPTO_AES_BLOCK_SIZE_U32;
tempBuffPtr += CY_CRYPTO_AES_BLOCK_SIZE_U32;
size -= CY_CRYPTO_AES_BLOCK_SIZE;
}
result = CY_CRYPTO_SUCCESS;
}
return (result);
}
#endif /* #if (CY_CRYPTO_USER_AES_CFB == 1) */
#if (CY_CRYPTO_USER_AES_CTR == 1)
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Aes_Ctr
********************************************************************************
*
* Performs AES operation on a plain text using the counter method (CTR).
*
* This function available for CM0+ core only.
*
* \param cryptoAesContext
* The pointer to the stc_crypto_context_t structure which stores
* the Crypto driver context.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Aes_Ctr(cy_stc_crypto_context_aes_t *cryptoAesContext)
{
uint32_t *dstPtrTmp = (uint32_t*)cryptoAesContext->dstPtr;
uint32_t *srcPtrTmp = (uint32_t*)cryptoAesContext->srcPtr;
uint32_t size = (uint32_t)cryptoAesContext->srcSize;
uint32_t *streamBlockTmp = (uint32_t*)cryptoAesContext->streamBlock;
uint32_t *nonceCounter = (uint32_t*)cryptoAesContext->ivPtr;
uint32_t cnt;
uint32_t i;
uint64_t counter;
cnt = (uint32_t)(size / CY_CRYPTO_AES_BLOCK_SIZE);
for (i = 0uL; i < cnt; i++)
{
/* In this mode, (CTR) is always an encryption! */
Cy_Crypto_Core_Aes_ProcessBlock(&(cryptoAesContext->aesState),
CY_CRYPTO_ENCRYPT,
streamBlockTmp,
nonceCounter);
/* Increment the nonce counter, at least 64Bits (from 128) is the counter part */
counter = *(uint64_t*)(nonceCounter + CY_CRYPTO_AES_CTR_CNT_POS);
counter = Cy_Crypto_InvertEndian8(counter);
counter++;
counter = Cy_Crypto_InvertEndian8(counter);
*(uint64_t*)(nonceCounter + CY_CRYPTO_AES_CTR_CNT_POS) = counter;
Cy_Crypto_Core_Aes_Xor(srcPtrTmp,
streamBlockTmp,
dstPtrTmp);
srcPtrTmp += CY_CRYPTO_AES_BLOCK_SIZE_U32;
dstPtrTmp += CY_CRYPTO_AES_BLOCK_SIZE_U32;
}
/* Save the reminder of the last non-complete block */
*cryptoAesContext->srcOffset = (uint32_t)(size % CY_CRYPTO_AES_BLOCK_SIZE);
return (CY_CRYPTO_SUCCESS);
}
#endif /* #if (CY_CRYPTO_USER_AES_CTR == 1) */
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
/* [] END OF FILE */

View File

@ -0,0 +1,77 @@
/***************************************************************************//**
* \file cy_crypto_core_aes.h
* \version 1.0
*
* \brief
* This file provides constant and parameters for the API for the AES method
* in the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_AES_H)
#define CY_CRYPTO_CORE_AES_H
#include "crypto/cy_crypto_common.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1))
#define CY_CRYPTO_AES_CTR_CNT_POS (0x02u)
void Cy_Crypto_Core_Aes_InvKey(cy_stc_crypto_aes_state_t const *aesStatePtr);
void Cy_Crypto_Core_Aes_ProcessBlock(cy_stc_crypto_aes_state_t const *aesStatePtr,
cy_en_crypto_dir_mode_t dirMode,
uint32_t *dstBlockPtr,
uint32_t const *srcBlockPtr);
void Cy_Crypto_Core_Aes_Xor(uint32_t const *src0BlockPtr,
uint32_t const *src1BlockPtr,
uint32_t *dstBlockPtr);
cy_en_crypto_status_t Cy_Crypto_Core_Aes_Init(cy_stc_crypto_context_aes_t const *cryptoContextPtr);
#if (CY_CRYPTO_USER_AES_ECB == 1)
cy_en_crypto_status_t Cy_Crypto_Core_Aes_Ecb(cy_stc_crypto_context_aes_t *cryptoContextPtr);
#endif /* #if (CY_CRYPTO_USER_AES_ECB == 1) */
#if (CY_CRYPTO_USER_AES_CBC == 1)
cy_en_crypto_status_t Cy_Crypto_Core_Aes_Cbc(cy_stc_crypto_context_aes_t *cryptoContextPtr);
#endif /* #if (CY_CRYPTO_USER_AES_CBC == 1) */
#if (CY_CRYPTO_USER_AES_CFB == 1)
cy_en_crypto_status_t Cy_Crypto_Core_Aes_Cfb(cy_stc_crypto_context_aes_t *cryptoContextPtr);
#endif /* #if (CY_CRYPTO_USER_AES_CFB == 1) */
#if (CY_CRYPTO_USER_AES_CTR == 1)
cy_en_crypto_status_t Cy_Crypto_Core_Aes_Ctr(cy_stc_crypto_context_aes_t *cryptoContextPtr);
#endif /* #if (CY_CRYPTO_USER_AES_CTE == 1) */
__STATIC_INLINE void Cy_Crypto_Core_Aes_WaitReady(void)
{
/* Wait until the TRNG instruction is complete */
while(0uL != _FLD2VAL(CRYPTO_STATUS_AES_BUSY, CRYPTO->STATUS))
{
}
}
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_CORE_AES_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,272 @@
/***************************************************************************//**
* \file cy_crypto_core_cmac.c
* \version 1.0
*
* \brief
* This file provides the source code to the API for the CMAC method
* in the Crypto block driver.
*
* Implementation is done in accordance with:
* http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38b.pdf
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "crypto/cy_crypto_core_cmac.h"
#include "crypto/cy_crypto_common.h"
#include "crypto/cy_crypto_core_aes.h"
#include "crypto/cy_crypto_core_instructions.h"
#include "crypto/cy_crypto_core_util.h"
#include "crypto/cy_crypto_core_str.h"
#include "syslib/cy_syslib.h"
#include <string.h>
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_CMAC == 1))
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Cmac_CalcSubKey
****************************************************************************//**
*
* Calculates the sub-key for the CMAC algorithm
* according to the NIST publication 800-38B, page 7.
*
* This function available for CM0+ core only.
*
* \param srcDstPtr
* The pointer to the source data for sub-key calculation, see 800-38B.
*
*******************************************************************************/
static void Cy_Crypto_Core_Cmac_CalcSubKey(uint8_t *srcDstPtr)
{
int32_t i;
uint32_t c;
uint32_t msb = 0uL;
for (i = 15; i >= 0; i--)
{
c = (uint32_t)srcDstPtr[i];
c = (c << 1) | msb;
srcDstPtr[i] = (uint8_t) c;
msb = (c >> 8u) & 1uL;
}
if (0uL != msb)
{
/* Just one byte is valuable, the rest are zeros */
srcDstPtr[(uint8_t)(CY_CRYPTO_AES_BLOCK_SIZE - 1u)] ^= CY_CRYPTO_CMAC_RB;
}
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Cmac_Init
****************************************************************************//**
*
* The function for initialization of CMAC operation.
*
* This function available for CM0+ core only.
*
* \param cmacStatePtr
* The pointer to the structure which stores the CMAC context.
*
* \param tempPtr
* The pointer to the temporary memory needed for CMAC calculation,
* the max needed - 128 Bytes.
*
* \param blockPtr
* The pointer to the temporary storage for block, the max needed - 128 Bytes.
*
* \param kPtr
* The pointer to the sub-key.
*******************************************************************************/
void Cy_Crypto_Core_Cmac_Init(cy_stc_crypto_cmac_state_t* cmacStatePtr,
uint32_t* tempPtr,
uint32_t* blockPtr,
uint32_t* kPtr)
{
cmacStatePtr->blockPtr = blockPtr;
cmacStatePtr->tempPtr = tempPtr;
cmacStatePtr->kPtr = kPtr;
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Cmac_Start
****************************************************************************//**
*
* Starts CMAC calculation.
*
* This function available for CM0+ core only.
*
* \param aesStatePtr
* The pointer to the structure which stores the AES context.
*
* \param cmacStatePtr
* the pointer to the structure which stores the CMAC context.
*
*******************************************************************************/
void Cy_Crypto_Core_Cmac_Start(cy_stc_crypto_aes_state_t *aesStatePtr,
cy_stc_crypto_cmac_state_t *cmacStatePtr)
{
uint32_t *kPtrTmp = cmacStatePtr->kPtr;
uint32_t *tempPtrTmp = cmacStatePtr->tempPtr;
/* Calculate the K1 sub-key */
memset((void*)tempPtrTmp, 0u, CY_CRYPTO_AES_BLOCK_SIZE);
Cy_Crypto_Core_Aes_ProcessBlock(aesStatePtr, CY_CRYPTO_ENCRYPT, kPtrTmp, tempPtrTmp);
Cy_Crypto_Core_Cmac_CalcSubKey((uint8_t*)kPtrTmp);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Cmac_Update
****************************************************************************//**
*
* Calculates CMAC on a message.
*
* This function available for CM0+ core only.
*
* \param aesStatePtr
* The pointer to the structure which stores the AES context.
*
* \param cmacStatePtr
* The pointer to the structure which stores the CMAC context.
*
* \param messagePtr
* The pointer to the message whose CMAC is being computed.
*
* \param messageSize
* The size of the message whose CMAC is being computed.
*
*******************************************************************************/
void Cy_Crypto_Core_Cmac_Update(cy_stc_crypto_aes_state_t *aesStatePtr,
cy_stc_crypto_cmac_state_t *cmacStatePtr,
uint32_t *messagePtr,
uint32_t messageSize)
{
uint32_t *blockPtrTmp = cmacStatePtr->blockPtr;
uint32_t *tempPtrTmp = cmacStatePtr->tempPtr;
/* Clear the argument for XOR for the first block */
memset((void* )tempPtrTmp, 0x00u, CY_CRYPTO_AES_BLOCK_SIZE);
/* Process all blocks except last */
while (messageSize > CY_CRYPTO_AES_BLOCK_SIZE)
{
Cy_Crypto_Core_Aes_Xor(messagePtr, tempPtrTmp, blockPtrTmp);
Cy_Crypto_Core_Aes_ProcessBlock(aesStatePtr, CY_CRYPTO_ENCRYPT, tempPtrTmp, blockPtrTmp);
/* Attention! 4 because the pointer is uint32_t */
messagePtr += 4u;
messageSize -= 16u;
}
/* The calculation size of the last block */
aesStatePtr->blockIdx = messageSize;
/* Copy the last block to the blockPtr */
memcpy((void*)blockPtrTmp, (void*)messagePtr, (uint16_t)aesStatePtr->blockIdx);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Cmac_Finish
****************************************************************************//**
*
* Completes CMAC calculation.
*
* This function available for CM0+ core only.
*
* \param aesStatePtr
* the pointer to the structure which stores the AES context.
*
* \param cmacStatePtr
* The pointer to the structure which stores the CMAC context.
*
* \param cmacPtr
* The pointer to the computed CMAC value.
*
*******************************************************************************/
void Cy_Crypto_Core_Cmac_Finish(cy_stc_crypto_aes_state_t *aesStatePtr,
cy_stc_crypto_cmac_state_t *cmacStatePtr,
uint32_t* cmacPtr)
{
uint32_t *blockPtrTmp = cmacStatePtr->blockPtr;
uint32_t *tempPtrTmp = cmacStatePtr->tempPtr;
uint32_t *kPtrTmp = cmacStatePtr->kPtr;
uint32_t blockIdxTmp = aesStatePtr->blockIdx;
uint32_t copySize;
if (blockIdxTmp < CY_CRYPTO_AES_BLOCK_SIZE)
{
/* Calculate the K2 sub-key */
Cy_Crypto_Core_Cmac_CalcSubKey((uint8_t* )kPtrTmp);
/* Appended '1' bit to the end of message, followed by '0' */
*((uint8_t* )blockPtrTmp + blockIdxTmp) = 0x80u;
/* Write zeros into the rest of the message */
copySize = CY_CRYPTO_AES_BLOCK_SIZE - 1u - blockIdxTmp;
memset(((uint8_t* )blockPtrTmp + blockIdxTmp + 1), 0x00u, (uint16_t)copySize);
}
Cy_Crypto_Core_Aes_Xor(blockPtrTmp, tempPtrTmp, blockPtrTmp);
Cy_Crypto_Core_Aes_Xor(blockPtrTmp, kPtrTmp, blockPtrTmp);
Cy_Crypto_Core_Aes_ProcessBlock(aesStatePtr, CY_CRYPTO_ENCRYPT, cmacPtr, blockPtrTmp);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Cmac
****************************************************************************//**
*
* Performs CMAC(Cipher-based Message Authentication Code) operation
* on a message to produce message authentication code using AES.
*
* This function available for CM0+ core only.
*
* \param cryptoAesContext
* The pointer to the stc_crypto_context_t structure which stores
* the Crypto driver context.
*
* \return
* A Crypto status \ref en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Cmac(cy_stc_crypto_context_aes_t *cryptoAesContext)
{
uint32_t *resultPtr = (uint32_t*)cryptoAesContext->dstPtr;
uint32_t *messagePtr = (uint32_t*)cryptoAesContext->srcPtr;
uint32_t messageSize = (uint32_t)cryptoAesContext->srcSize;
cy_stc_crypto_aes_state_t *aesStatePtr = &cryptoAesContext->aesState;
uint32_t *blockPtr = (uint32_t*)CRYPTO->MEM_BUFF;
uint32_t *tempPtr = (uint32_t*)((uint8_t*)blockPtr + CY_CRYPTO_AES_BLOCK_SIZE);
uint32_t *kPtr = (uint32_t*)((uint8_t*)tempPtr + CY_CRYPTO_AES_BLOCK_SIZE);
cy_stc_crypto_cmac_state_t *cmacStatePtr = (cy_stc_crypto_cmac_state_t* )((uint8_t*)kPtr + CY_CRYPTO_AES_BLOCK_SIZE);
(void)Cy_Crypto_Core_Aes_Init(cryptoAesContext);
Cy_Crypto_Core_Cmac_Init (cmacStatePtr, tempPtr, blockPtr, kPtr);
Cy_Crypto_Core_Cmac_Start (aesStatePtr, cmacStatePtr);
Cy_Crypto_Core_Cmac_Update(aesStatePtr, cmacStatePtr, messagePtr, messageSize);
Cy_Crypto_Core_Cmac_Finish(aesStatePtr, cmacStatePtr, resultPtr);
return (CY_CRYPTO_SUCCESS);
}
#endif /* ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_CMAC == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
/* [] END OF FILE */

View File

@ -0,0 +1,72 @@
/***************************************************************************//**
* \file cy_crypto_core_cmac.h
* \version 1.0
*
* \brief
* This file provides constants and function prototypes
* for the API for the CMAC method in the Crypto block driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_CMAC_H)
#define CY_CRYPTO_CORE_CMAC_H
#include "crypto/cy_crypto_common.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_CMAC == 1))
/** \cond INTERNAL */
/* The bit string used to generate sub-keys */
#define CY_CRYPTO_CMAC_RB (0x87u)
/* The structure to store the AES-CMAC context */
typedef struct
{
uint32_t *blockPtr;
uint32_t *kPtr;
uint32_t *tempPtr;
} cy_stc_crypto_cmac_state_t;
/* The function prototypes */
uint32_t Cy_Crypto_Core_Cmac_LeftShift(uint8_t *srcDstPtr);
void Cy_Crypto_Core_Cmac_Init(cy_stc_crypto_cmac_state_t *cmacStatePtr,
uint32_t *tempPtr,
uint32_t *blockPtr,
uint32_t *kPtr);
void Cy_Crypto_Core_Cmac_Start(cy_stc_crypto_aes_state_t *aesStatePtr,
cy_stc_crypto_cmac_state_t *cmacStatePtr);
void Cy_Crypto_Core_Cmac_Update(cy_stc_crypto_aes_state_t *aesStatePtr,
cy_stc_crypto_cmac_state_t *cmacStatePtr,
uint32_t *messagePtr,
uint32_t messageSize);
void Cy_Crypto_Core_Cmac_Finish(cy_stc_crypto_aes_state_t *aesStatePtr,
cy_stc_crypto_cmac_state_t *cmacStatePtr,
uint32_t* cmacPtr);
cy_en_crypto_status_t Cy_Crypto_Core_Cmac(cy_stc_crypto_context_aes_t *cryptoAesContext);
/** \endcond */
#endif /* ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_CMAC == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_CORE_CMAC_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,117 @@
/***************************************************************************//**
* \file cy_crypto_core_crc.c
* \version 1.0
*
* \brief
* This file provides the source code for CRC API
* in the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "crypto/cy_crypto_common.h"
#include "crypto/cy_crypto_core_crc.h"
#include "crypto/cy_crypto_core_util.h"
#include "crypto/cy_crypto_core_instructions.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_CRC == 1) && (CY_CRYPTO_USER_CRC == 1))
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Crc_Init
****************************************************************************//**
*
* Initializes CRC calculation.
*
* This function available for CM0+ core only.
*
* \param cryptoCrcContext
* The pointer to the stc_crypto_context_t structure which stores
* the Crypto driver context.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Crc_Init(cy_stc_crypto_context_crc_t *cryptoCrcContext)
{
/* Specifies the bit order in which a data Byte is processed
* (reversal is performed after XORing):
* '0': Most significant bit (bit 1) first.
* '1': Least significant bit (bit 0) first. */
CRYPTO->CRC_CTL = (uint32_t)( (_VAL2FLD(CRYPTO_CRC_CTL_DATA_REVERSE, (uint32_t)(cryptoCrcContext->dataReverse))) |
(_VAL2FLD(CRYPTO_CRC_CTL_REM_REVERSE, (uint32_t)(cryptoCrcContext->remReverse))) );
/* Specifies a byte mask with which each data byte is XORed.
* The XOR is performed before data reversal. */
CRYPTO->CRC_DATA_CTL = (uint32_t)(_VAL2FLD(CRYPTO_CRC_DATA_CTL_DATA_XOR, (uint32_t)cryptoCrcContext->dataXor));
/* CRC polynomial. The polynomial is represented WITHOUT the high order bit
* (this bit is always assumed '1'). */
CRYPTO->CRC_POL_CTL = (uint32_t)(_VAL2FLD(CRYPTO_CRC_POL_CTL_POLYNOMIAL, (uint32_t)cryptoCrcContext->polynomial));
/*Specifies a mask with which the CRC_LFSR_CTL.LFSR32 register is XORed to produce a remainder.
* The XOR is performed before remainder reversal. */
CRYPTO->CRC_REM_CTL = (uint32_t)(_VAL2FLD(CRYPTO_CRC_REM_CTL_REM_XOR, (uint32_t)cryptoCrcContext->remXor));
return (CY_CRYPTO_SUCCESS);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Server_Crc
****************************************************************************//**
*
* Performs CRC calculation on a message.
*
* This function available for CM0+ core only.
*
* \param cryptoCrcContext
* The pointer to the stc_crypto_context_t structure which stores
* vCrypto driver context.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Crc(cy_stc_crypto_context_crc_t *cryptoCrcContext)
{
/* A state of 32-bit Linear Feedback Shift Registers (LFSR) used to implement CRC. */
CRYPTO->CRC_LFSR_CTL = (uint32_t)(_VAL2FLD(CRYPTO_CRC_LFSR_CTL_LFSR32, (uint32_t)cryptoCrcContext->lfsrInitState));
/* Fill the FIFO with the instruction parameters */
Cy_Crypto_SetReg2Instr( (uint32_t)cryptoCrcContext->srcDataPtr,
(uint32_t)cryptoCrcContext->dataSize );
/* Issue the CRC instruction */
Cy_Crypto_Run2ParamInstr(CY_CRYPTO_CRC_OPC,
CY_CRYPTO_RSRC0_SHIFT,
CY_CRYPTO_RSRC4_SHIFT);
/* Wait until STR instruction is complete */
while(0uL != _FLD2VAL(CRYPTO_STATUS_CRC_BUSY, CRYPTO->STATUS))
{
}
/* Copy the result from the CRC_REM_RESULT register */
*cryptoCrcContext->crcPtr = (uint32_t)_FLD2VAL(CRYPTO_CRC_REM_RESULT_REM, CRYPTO->CRC_REM_RESULT);
return (CY_CRYPTO_SUCCESS);
}
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_CRC == 1) && (CY_CRYPTO_USER_CRC == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
/* [] END OF FILE */

View File

@ -0,0 +1,41 @@
/***************************************************************************//**
* \file cy_crypto_core_crc.h
* \version 1.0
*
* \brief
* This file provides the headers for CRC API
* in the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_CRC_H)
#define CY_CRYPTO_CORE_CRC_H
#include "crypto/cy_crypto_common.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_CRC == 1) && (CY_CRYPTO_USER_CRC == 1))
cy_en_crypto_status_t Cy_Crypto_Core_Crc_Init (cy_stc_crypto_context_crc_t *cryptoCrcContext);
cy_en_crypto_status_t Cy_Crypto_Core_Crc (cy_stc_crypto_context_crc_t *cryptoCrcContext);
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_CRC == 1) && (CY_CRYPTO_USER_CRC == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_CORE_CRC_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,208 @@
/***************************************************************************//**
* \file cy_crypto_core_des.c
* \version 1.0
*
* \brief
* This file provides the source code fro the API for the DES method
* in the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "crypto/cy_crypto_common.h"
#include "crypto/cy_crypto_core_des.h"
#include "crypto/cy_crypto_core_instructions.h"
#include "crypto/cy_crypto_core_util.h"
#include "crypto/cy_crypto_core_str.h"
#include "syslib/cy_syslib.h"
#include <string.h>
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_DES == 1) && (CY_CRYPTO_USER_DES == 1))
uint8_t const cy_desCommands[2][2] = {
{ CY_CRYPTO_DES_BLOCK_OPC, CY_CRYPTO_DES_BLOCK_INV_OPC }, /* DES mode */
{ CY_CRYPTO_TDES_BLOCK_OPC, CY_CRYPTO_TDES_BLOCK_INV_OPC } /* TDES mode */
};
/* Table with DES weak keys */
CY_ALIGN(4) uint8_t const cy_desWeakKeys[CY_CRYPTO_DES_WEAK_KEY_COUNT][CY_CRYPTO_DES_KEY_BYTE_LENGTH] =
{
{ 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 }
};
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Des_ProcessBlock
****************************************************************************//**
*
* Performs the DES or TDES block cipher.
* All addresses must be 4Byte aligned,
* srcBlock could overlap dstBlock.
*
* This function available for CM0+ core only.
*
* \param dirMode
* One of CRYPTO_ENCRYPT or CRYPTO_DECRYPT.
*
* \param keyPtr
* The pointer to the encryption/decryption key.
*
* \param dstBlockPtr
* The pointer to the cipher text.
*
* \param srcBlockPtr
* The pointer to the plain text. Must be 4-Byte aligned!
*
*******************************************************************************/
void Cy_Crypto_Core_Des_ProcessBlock(cy_en_crypto_des_mode_t desMode,
cy_en_crypto_dir_mode_t dirMode,
uint32_t const *keyPtr,
uint32_t *dstBlockPtr,
uint32_t const *srcBlockPtr)
{
Cy_Crypto_SetReg3Instr((uint32_t)keyPtr,
(uint32_t)srcBlockPtr,
(uint32_t)dstBlockPtr);
/* Issue the DES_BLOCK instruction */
Cy_Crypto_Run3ParamInstr(cy_desCommands[(uint8_t)desMode][(uint8_t)dirMode],
CY_CRYPTO_RSRC0_SHIFT,
CY_CRYPTO_RSRC4_SHIFT,
CY_CRYPTO_RSRC8_SHIFT);
/* Wait until the AES instruction is complete */
while (0uL != _FLD2VAL(CRYPTO_STATUS_DES_BUSY, CRYPTO->STATUS))
{
}
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Des
****************************************************************************//**
*
* Performs DES operation on a Single Block. All addresses must be 4-Byte aligned.
* Ciphertext (dstBlockPtr) may overlap with plaintext (srcBlockPtr)
* This function is independent from the previous Crypto state.
*
* This function available for CM0+ core only.
*
* \param cryptoDesContext
* The pointer to the cy_stc_crypto_context_des_t structure which stores
* the Crypto driver context.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Des(cy_stc_crypto_context_des_t *cryptoDesContext)
{
uint32_t i;
cy_en_crypto_status_t status = CY_CRYPTO_SUCCESS;
/* Check weak keys */
for (i = 0; i < CY_CRYPTO_DES_WEAK_KEY_COUNT; i++)
{
if (memcmp(cryptoDesContext->keyPtr, (uint8_t*)cy_desWeakKeys[i], CY_CRYPTO_DES_KEY_BYTE_LENGTH) == 0)
{
status = CY_CRYPTO_DES_WEAK_KEY;
break;
}
}
Cy_Crypto_Core_Des_ProcessBlock(CY_CRYPTO_DES_MODE_SINGLE,
cryptoDesContext->dirMode,
cryptoDesContext->keyPtr,
cryptoDesContext->dstPtr,
cryptoDesContext->srcPtr);
return (status);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Tdes
****************************************************************************//**
*
* Performs TDES operation on a Single Block. All addresses must be 4-Byte aligned.
* Ciphertext (dstBlockPtr) may overlap with plaintext (srcBlockPtr)
* This function is independent from the previous Crypto state.
*
* This function available for CM0+ core only.
*
* \param cryptoDesContext
* The pointer to the cy_stc_crypto_context_des_t structure which stores
* the Crypto driver context.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Tdes(cy_stc_crypto_context_des_t *cryptoDesContext)
{
uint32_t i;
cy_en_crypto_status_t status = CY_CRYPTO_SUCCESS;
uint32_t *_keyPtr = cryptoDesContext->keyPtr;
/* Check weak keys */
for (i = 0; i < CY_CRYPTO_DES_WEAK_KEY_COUNT; i++)
{
if (memcmp(_keyPtr, (uint8_t*)cy_desWeakKeys[i], CY_CRYPTO_DES_KEY_BYTE_LENGTH) == 0)
{
status = CY_CRYPTO_DES_WEAK_KEY;
break;
}
if (memcmp(&(_keyPtr[CY_CRYPTO_DES_KEY_BYTE_LENGTH]),
(uint8_t*)cy_desWeakKeys[i], CY_CRYPTO_DES_KEY_BYTE_LENGTH) == 0)
{
status = CY_CRYPTO_DES_WEAK_KEY;
break;
}
if (memcmp(&(_keyPtr[2 * CY_CRYPTO_DES_KEY_BYTE_LENGTH]),
(uint8_t*)cy_desWeakKeys[i], CY_CRYPTO_DES_KEY_BYTE_LENGTH) == 0)
{
status = CY_CRYPTO_DES_WEAK_KEY;
break;
}
}
Cy_Crypto_Core_Des_ProcessBlock(CY_CRYPTO_DES_MODE_TRIPLE,
cryptoDesContext->dirMode,
_keyPtr,
cryptoDesContext->dstPtr,
cryptoDesContext->srcPtr);
return (status);
}
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_DES == 1) && (CY_CRYPTO_USER_DES == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
/* [] END OF FILE */

View File

@ -0,0 +1,48 @@
/***************************************************************************//**
* \file cy_crypto_core_des.h
* \version 1.0
*
* \brief
* This file provides constant and parameters for the API for the DES method
* in the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_DES_H)
#define CY_CRYPTO_CORE_DES_H
#include "crypto/cy_crypto_common.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_DES == 1) && (CY_CRYPTO_USER_DES == 1))
#define CY_CRYPTO_DES_WEAK_KEY_COUNT (16)
#define CY_CRYPTO_DES_KEY_BYTE_LENGTH (8)
typedef enum {
CY_CRYPTO_DES_MODE_SINGLE = 0,
CY_CRYPTO_DES_MODE_TRIPLE = 1
} cy_en_crypto_des_mode_t;
cy_en_crypto_status_t Cy_Crypto_Core_Des(cy_stc_crypto_context_des_t *cryptoDesContext);
cy_en_crypto_status_t Cy_Crypto_Core_Tdes(cy_stc_crypto_context_des_t *cryptoDesContext);
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_DES == 1) && (CY_CRYPTO_USER_DES == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_CORE_DES_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,244 @@
/***************************************************************************//**
* \file cy_crypto_core_hmac.c
* \version 1.0
*
* \brief
* This file provides the source code to the API for the HMAC method
* in the Crypto block driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "crypto/cy_crypto_common.h"
#include "crypto/cy_crypto_core_hmac.h"
#include "crypto/cy_crypto_core_sha.h"
#include "crypto/cy_crypto_core_util.h"
#include "crypto/cy_crypto_core_str.h"
#include "syslib/cy_syslib.h"
#include <string.h>
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_HMAC == 1))
#define CY_CRYPTO_HMAC_IPAD (0x36u)
#define CY_CRYPTO_HMAC_0PAD (0x5Cu)
#define CY_CRYPTO_HMAC_MAX_PAD_SIZE (128u)
#define CY_CRYPTO_HMAC_MAX_M0_KEY_SIZE (128u)
typedef struct
{
uint32_t *ipadPtr;
uint32_t *opadPtr;
uint32_t *m0KeyPtr;
} cy_stc_crypto_hmac_state_t;
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Hmac_Init
****************************************************************************//**
*
* Initializes HMAC (Hash-based Message Authentication Code) calculation.
* Allocate two buffers (ipadPtr and opadPtr) for HMAC calculation.
*
* This function available for CM0+ core only.
*
* \param hmacStatePtr
* the pointer to the hmacStatePtr structure which stores internal variables
* for HMAC calculation.
*
* \param ipadPtr
* The memory buffer for HMAC calculation, the max used size = CRYPTO_HMAC_MAX_PAD_SIZE.
*
* \param opadPtr
* The memory buffer for HMAC calculation, the max used size = CRYPTO_HMAC_MAX_PAD_SIZE.
*
* * \param m0KeyPtr
* The memory buffer for HMAC calculation, the max used size = CRYPTO_HMAC_MAX_M0_KEY_SIZE.
*
*******************************************************************************/
void Cy_Crypto_Core_Hmac_Init(cy_stc_crypto_hmac_state_t *hmacStatePtr,
uint32_t *ipadPtr,
uint32_t *opadPtr,
uint32_t *m0KeyPtr)
{
hmacStatePtr->ipadPtr = ipadPtr;
hmacStatePtr->opadPtr = opadPtr;
hmacStatePtr->m0KeyPtr = m0KeyPtr;
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Hmac_Calculate
****************************************************************************//**
*
* Starts HMAC (Hash-based Message Authentication Code) calculation.
*
* This function available for CM0+ core only.
*
* \param hmacStatePtr
* The pointer to the hmacStatePtr structure which stores internal variables
* for HMAC calculation.
*
* \param hashStatePtr
* The pointer to the hashStatePtr structure which stores internal variables
* of the SHA algorithm because it is used for HMAC calculation.
*
* \param keyPtr
* The pointer to the encryption key used in computing AES-CMAC.
*
* \param keyLength
* The size of the encryption key.
*
* \param messagePtr
* The pointer to the input message.
*
* \param messageSize
* The size of the input message.
*
* \param hmacPtr
* The pointer to the calculated HMAC.
*
*******************************************************************************/
void Cy_Crypto_Core_Hmac_Calculate(cy_stc_crypto_hmac_state_t *hmacStatePtr,
cy_stc_crypto_sha_state_t *hashStatePtr,
uint32_t *keyPtr,
uint32_t keyLength,
uint32_t *messagePtr,
uint32_t messageSize,
uint32_t *hmacPtr)
{
uint32_t i = 0uL;
uint8_t *ipadPtrTmp = (uint8_t*)hmacStatePtr->ipadPtr;
uint8_t *opadPtrTmp = (uint8_t*)hmacStatePtr->opadPtr;
uint8_t *m0KeyPtrTmp = (uint8_t*)hmacStatePtr->m0KeyPtr;
/* Steps 1-3 according to FIPS 198-1 */
if (keyLength > hashStatePtr->blockSize)
{
/* The key is larger than the block size. Do a hash on the key. */
Cy_Crypto_Core_Sha_Start (hashStatePtr);
Cy_Crypto_Core_Sha_Update (hashStatePtr, keyPtr, keyLength);
Cy_Crypto_Core_Sha_Finish (hashStatePtr, (uint32_t*)m0KeyPtrTmp, keyLength);
/* Append zeros */
memset((m0KeyPtrTmp + hashStatePtr->digestSize), 0x00u,
(hashStatePtr->blockSize - hashStatePtr->digestSize));
}
else if (keyLength < hashStatePtr->blockSize)
{
/* If the key is shorter than the block, append zeros */
memcpy(m0KeyPtrTmp, keyPtr, (uint16_t)keyLength);
memset((m0KeyPtrTmp + keyLength), 0x00u, (hashStatePtr->blockSize - keyLength));
}
else
{
memcpy(m0KeyPtrTmp, keyPtr, keyLength);
}
/* Steps 4 and 7 according to FIPS 198-1 */
while (i < hashStatePtr->blockSize)
{
ipadPtrTmp[i] = CY_CRYPTO_HMAC_IPAD ^ m0KeyPtrTmp[i];
opadPtrTmp[i] = CY_CRYPTO_HMAC_0PAD ^ m0KeyPtrTmp[i];
i++;
}
/* Step 6 according to FIPS 198-1 */
Cy_Crypto_Core_Sha_Start (hashStatePtr);
Cy_Crypto_Core_Sha_ProcessBlock (hashStatePtr, (uint32_t*)ipadPtrTmp);
/* Append a message */
Cy_Crypto_Core_Sha_Update (hashStatePtr, messagePtr, messageSize);
Cy_Crypto_Core_Sha_Finish (hashStatePtr, (uint32_t*)ipadPtrTmp, (messageSize + hashStatePtr->blockSize));
/* Here is the ready part of HASH: Hash((Key^ipad)||text) */
/* Steps 8, 9 according to FIPS 198-1 */
Cy_Crypto_Core_Sha_Start (hashStatePtr);
Cy_Crypto_Core_Sha_ProcessBlock (hashStatePtr, (uint32_t*)opadPtrTmp);
/* Append HASH from Step 6 */
Cy_Crypto_Core_Sha_Update (hashStatePtr, (uint32_t*)ipadPtrTmp, hashStatePtr->digestSize);
Cy_Crypto_Core_Sha_Finish (hashStatePtr, hmacPtr, (hashStatePtr->digestSize + hashStatePtr->blockSize));
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Hmac_Free
****************************************************************************//**
*
* Clears the used memory buffers.
*
* This function available for CM0+ core only.
*
* \param hmacStatePtr
* The pointer to the HMAC context.
*
*******************************************************************************/
void Cy_Crypto_Core_Hmac_Free(cy_stc_crypto_hmac_state_t *hmacStatePtr)
{
/* Clear the memory buffer. */
memset(hmacStatePtr->ipadPtr, 0x00u, CY_CRYPTO_HMAC_MAX_PAD_SIZE);
memset(hmacStatePtr->opadPtr, 0x00u, CY_CRYPTO_HMAC_MAX_PAD_SIZE);
memset(hmacStatePtr->m0KeyPtr, 0x00u, CY_CRYPTO_HMAC_MAX_M0_KEY_SIZE);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Hmac
****************************************************************************//**
*
* Performs HMAC calculation.
*
* This function available for CM0+ core only.
*
* \param cryptoShaContext
* The pointer to the stc_crypto_context_t structure which stores all internal variables
* for Crypto driver.
*
* \return
* A Crypto status \ref en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Hmac(cy_stc_crypto_context_sha_t *cryptoShaContext)
{
uint32_t *messageTmpPtr = cryptoShaContext->messagePtr;
uint32_t messageSizeTmp = cryptoShaContext->messageSize;
uint32_t *hmacPtr = cryptoShaContext->dstPtr;
cy_en_crypto_sha_mode_t modeTmp = cryptoShaContext->mode;
uint32_t *keyTmpPtr = cryptoShaContext->keyPtr;
uint32_t keyLengthTmp = cryptoShaContext->keyLength;
/* Allocating internal variables into the CRYPTO SRAM Buffer */
uint32_t *blockPtr = (uint32_t*)CRYPTO->MEM_BUFF;
uint32_t *hashPtr = (uint32_t*)((uint8_t*)blockPtr + CY_CRYPTO_MAX_BLOCK_SIZE);
uint32_t *roundMemPtr = (uint32_t*)((uint8_t*)hashPtr + CY_CRYPTO_MAX_HASH_SIZE);
uint32_t *ipadPtr = (uint32_t*)((uint8_t*)roundMemPtr + CY_CRYPTO_MAX_ROUND_MEM_SIZE);
uint32_t *opadPtr = (uint32_t*)((uint8_t*)ipadPtr + CY_CRYPTO_HMAC_MAX_PAD_SIZE);
uint32_t *m0KeyPtr = (uint32_t*)((uint8_t*)opadPtr + CY_CRYPTO_HMAC_MAX_PAD_SIZE);
cy_stc_crypto_hmac_state_t *hmacStatePtr = (cy_stc_crypto_hmac_state_t* )((uint8_t*)m0KeyPtr + CY_CRYPTO_MAX_BLOCK_SIZE);
cy_stc_crypto_sha_state_t *hashStatePtr = (cy_stc_crypto_sha_state_t* )((uint8_t*)hmacStatePtr + sizeof(cy_stc_crypto_hmac_state_t));
Cy_Crypto_Core_Sha_Init (hashStatePtr, (uint8_t*)blockPtr, hashPtr, roundMemPtr, modeTmp);
Cy_Crypto_Core_Hmac_Init (hmacStatePtr, ipadPtr, opadPtr, m0KeyPtr);
Cy_Crypto_Core_Hmac_Calculate (hmacStatePtr, hashStatePtr, keyTmpPtr, keyLengthTmp, messageTmpPtr, messageSizeTmp, hmacPtr);
Cy_Crypto_Core_Hmac_Free (hmacStatePtr);
Cy_Crypto_Core_Sha_Free (hashStatePtr);
return (CY_CRYPTO_SUCCESS);
}
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_HMAC == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
/* [] END OF FILE */

View File

@ -0,0 +1,37 @@
/***************************************************************************//**
* \file cy_crypto_cora_hmac.h
* \version 1.0
*
* \brief
* This file provides constants and function prototypes
* for the API for the SHA method in the Crypto block driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_HMAC_H)
#define CY_CRYPTO_CORE_HMAC_H
#include "crypto/cy_crypto_common.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_HMAC == 1))
cy_en_crypto_status_t Cy_Crypto_Core_Hmac(cy_stc_crypto_context_sha_t *cryptoContext);
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_HMAC == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_CORE_HMAC_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,180 @@
/***************************************************************************//**
* \file cy_crypto_core_instructions.h
* \version 1.0
*
* \brief
* This file provides internal (not public) constant and parameters
* for the Crypto server.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_INSTRUCTIONS_H)
#define CY_CRYPTO_CORE_INSTRUCTIONS_H
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if (CPUSS_CRYPTO_PRESENT == 1)
/***************************************
* Crypto IP opcodes
***************************************/
#define CY_CRYPTO_REGFILE_R0 (0x00uL)
#define CY_CRYPTO_REGFILE_R1 (0x01uL)
#define CY_CRYPTO_REGFILE_R2 (0x02uL)
#define CY_CRYPTO_REGFILE_R3 (0x03uL)
#define CY_CRYPTO_REGFILE_R4 (0x04uL)
#define CY_CRYPTO_REGFILE_R5 (0x05uL)
#define CY_CRYPTO_REGFILE_R6 (0x06uL)
#define CY_CRYPTO_REGFILE_R7 (0x07uL)
#define CY_CRYPTO_REGFILE_R8 (0x08uL)
#define CY_CRYPTO_REGFILE_R9 (0x09uL)
#define CY_CRYPTO_REGFILE_R10 (0x0AuL)
#define CY_CRYPTO_REGFILE_R11 (0x0BuL)
#define CY_CRYPTO_REGFILE_R12 (0x0CuL)
#define CY_CRYPTO_REGFILE_R13 (0x0DuL)
#define CY_CRYPTO_REGFILE_R14 (0x0EuL)
#define CY_CRYPTO_REGFILE_R15 (0x0FuL)
#define CY_CRYPTO_SET_REG1_OPC (0x40u)
#define CY_CRYPTO_SET_REG2_OPC (0x41u)
#define CY_CRYPTO_SET_REG3_OPC (0x42u)
#define CY_CRYPTO_SET_REG4_OPC (0x43u)
#define CY_CRYPTO_RSRC0_SHIFT (0u)
#define CY_CRYPTO_RSRC4_SHIFT (4u)
#define CY_CRYPTO_RSRC8_SHIFT (8u)
#define CY_CRYPTO_RSRC12_SHIFT (12u)
#define CY_CRYPTO_RSRC20_SHIFT (20u)
#define CY_CRYPTO_OPCODE_POS (24u)
#define CY_CRYPTO_RSRC26_SHIFT (26u)
#define CY_CRYPTO_RSRC30_SHIFT (30u)
#define CY_CRYPTO_AES_BLOCK_OPC (0x44u)
#define CY_CRYPTO_AES_BLOCK_INV_OPC (0x45u)
#define CY_CRYPTO_AES_KEY_OPC (0x46u)
#define CY_CRYPTO_AES_KEY_INV_OPC (0x47u)
#define CY_CRYPTO_AES_XOR_OPC (0x48u)
#define CY_CRYPTO_SHA_OPC (0x4cu)
#define CY_CRYPTO_STR_MEMCPY_OPC (0x50u)
#define CY_CRYPTO_STR_MEMSET_OPC (0x51u)
#define CY_CRYPTO_STR_MEMCMP_OPC (0x52u)
#define CY_CRYPTO_STR_MEMXOR_OPC (0x53u)
#define CY_CRYPTO_CRC_OPC (0x58u)
#define CY_CRYPTO_PRNG_OPC (0x5cu)
#define CY_CRYPTO_TRNG_OPC (0x60u)
#define CY_CRYPTO_DES_BLOCK_OPC (0x70u)
#define CY_CRYPTO_DES_BLOCK_INV_OPC (0x71u)
#define CY_CRYPTO_TDES_BLOCK_OPC (0x72u)
#define CY_CRYPTO_TDES_BLOCK_INV_OPC (0x73u)
#define CY_CRYPTO_SYNC_OPC (0x7fu)
#define CY_CRYPTO_FIFODEPTH (0x08u)
/* Vector Unit instructions */
#define CY_CRYPTO_VU_ALLOC_MEM_OPC (0x12u)
#define CY_CRYPTO_VU_FREE_MEM_OPC (0x13u)
/* Instructions with register operand only, category I */
#define CY_CRYPTO_VU_SET_REG_OPC (0x80u)
#define CY_CRYPTO_VU_MOV_REG_OPC (0x02u)
#define CY_CRYPTO_VU_LD_REG_OPC (0x00u)
#define CY_CRYPTO_VU_ST_REG_OPC (0x01u)
/* Instructions with register operand only, category III */
#define CY_CRYPTO_VU_SWAP_REG_OPC (0x03u)
/* Instructions with register operand only, category IV */
#define CY_CRYPTO_VU_MOV_REG_TO_STATUS_OPC (0x04u)
/* Instructions with register operand only, category V */
#define CY_CRYPTO_VU_MOV_STATUS_TO_REG_OPC (0x05u)
/* Instructions with register operand only, category VI */
#define CY_CRYPTO_VU_PUSH_REG_OPC (0x10u)
#define CY_CRYPTO_VU_POP_REG_OPC (0x11u)
/* Instructions with register operand only, category VII */
#define CY_CRYPTO_VU_ADD_REG_OPC (0x06u)
#define CY_CRYPTO_VU_SUB_REG_OPC (0x07u)
#define CY_CRYPTO_VU_OR_REG_OPC (0x08u)
#define CY_CRYPTO_VU_AND_REG_OPC (0x09u)
#define CY_CRYPTO_VU_XOR_REG_OPC (0x0Au)
#define CY_CRYPTO_VU_NOR_REG_OPC (0x0Bu)
#define CY_CRYPTO_VU_NAND_REG_OPC (0x0Cu)
#define CY_CRYPTO_VU_MIN_REG_OPC (0x0Du)
#define CY_CRYPTO_VU_MAX_REG_OPC (0x0Eu)
/* Instructions with mixed operands, category I */
#define CY_CRYPTO_VU_LSL_OPC (0x20u)
#define CY_CRYPTO_VU_LSR_OPC (0x24u)
/* Instructions with mixed operands, category II */
#define CY_CRYPTO_VU_LSL1_OPC (0x21u)
#define CY_CRYPTO_VU_LSL1_WITH_CARRY_OPC (0x22u)
#define CY_CRYPTO_VU_LSR1_OPC (0x25u)
#define CY_CRYPTO_VU_LSR1_WITH_CARRY_OPC (0x26u)
/* Instructions with mixed operands, category III */
#define CY_CRYPTO_VU_SET_BIT_OPC (0x2Cu)
#define CY_CRYPTO_VU_CLR_BIT_OPC (0x2Du)
#define CY_CRYPTO_VU_INV_BIT_OPC (0x2Eu)
/* Instructions with mixed operands, category IV */
#define CY_CRYPTO_VU_GET_BIT_OPC (0x2Fu)
/* Instructions with mixed operands, category V */
#define CY_CRYPTO_VU_CLSAME_OPC (0x28u)
#define CY_CRYPTO_VU_CTSAME_OPC (0x29u)
/* Instructions with memory buffer operands, category I */
#define CY_CRYPTO_VU_SET_TO_ZERO_OPC (0x34u)
#define CY_CRYPTO_VU_SET_TO_ONE_OPC (0x35u)
/* Instructions with memory buffer operands, category II */
#define CY_CRYPTO_VU_MOV_OPC (0x30u)
#define CY_CRYPTO_VU_XSQUARE_OPC (0x31u)
/* Instructions with memory buffer operands, category III */
#define CY_CRYPTO_VU_CMP_SUB_OPC (0x3Du)
#define CY_CRYPTO_VU_CMP_DEFREE_OPC (0x3Eu)
/* Instructions with memory buffer operands, category IV */
#define CY_CRYPTO_VU_TST_OPC (0x3fu)
#define CY_CRYPTO_VU_XMUL_OPC (0x32u)
#define CY_CRYPTO_VU_UMUL_OPC (0x33u)
#define CY_CRYPTO_VU_ADD_OPC (0x36u)
#define CY_CRYPTO_VU_SUB_OPC (0x37u)
#define CY_CRYPTO_VU_OR_OPC (0x38u)
#define CY_CRYPTO_VU_AND_OPC (0x39u)
#define CY_CRYPTO_VU_XOR_OPC (0x3Au)
#define CY_CRYPTO_VU_NOR_OPC (0x3Bu)
#define CY_CRYPTO_VU_NAND_OPC (0x3Cu)
#endif /* #if (CPUSS_CRYPTO_PRESENT == 1) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_CORE_INSTRUCTIONS_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,99 @@
/***************************************************************************//**
* \file cy_crypto_core_prng.c
* \version 1.0
*
* \brief
* This file provides the source code to the API for the PRNG
* in the Crypto block driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "crypto/cy_crypto_common.h"
#include "crypto/cy_crypto_core_prng.h"
#include "crypto/cy_crypto_core_instructions.h"
#include "crypto/cy_crypto_core_util.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_PR == 1) && (CY_CRYPTO_USER_PR == 1))
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Prng_Init
****************************************************************************//**
*
* Initializes the PRND parameters.
* Invoking this function causes a restart of the pseudo-random sequence.
*
* This function available for CM0+ core only.
*
* \param cryptoPrngContext
* The pointer to thestc_crypto_context_t structure which stores
* the Crypto driver context.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Prng_Init(cy_stc_crypto_context_prng_t *cryptoPrngContext)
{
CRYPTO->PR_LFSR_CTL0 = (uint32_t)(_VAL2FLD(CRYPTO_PR_LFSR_CTL0_LFSR32,
(uint32_t)cryptoPrngContext->lfsr32InitState));
CRYPTO->PR_LFSR_CTL1 = (uint32_t)(_VAL2FLD(CRYPTO_PR_LFSR_CTL1_LFSR31,
(uint32_t)cryptoPrngContext->lfsr31InitState));
CRYPTO->PR_LFSR_CTL2 = (uint32_t)(_VAL2FLD(CRYPTO_PR_LFSR_CTL2_LFSR29,
(uint32_t)cryptoPrngContext->lfsr29InitState));
return (CY_CRYPTO_SUCCESS);
}
/*******************************************************************************
* Function Name: Crypto_Core_Prng
****************************************************************************//**
*
* Generates a Pseudo Random Number.
*
* This function available for CM0+ core only.
*
* \param cryptoPrngContext
* The pointer to the stc_crypto_context_t structure which stores
* the Crypto driver context.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Prng(cy_stc_crypto_context_prng_t *cryptoPrngContext)
{
CRYPTO->INSTR_FF_WR = (uint32_t)(CY_CRYPTO_SET_REG1_OPC << CY_CRYPTO_OPCODE_POS);
CRYPTO->INSTR_FF_WR = (uint32_t)cryptoPrngContext->max;
CRYPTO->INSTR_FF_WR = (uint32_t)((uint32_t)CY_CRYPTO_PRNG_OPC << CY_CRYPTO_OPCODE_POS);
/* Wait until the PRNG instruction is complete */
while(0uL != _FLD2VAL(CRYPTO_STATUS_PR_BUSY, CRYPTO->STATUS))
{
}
*cryptoPrngContext->prngNumPtr = (uint32_t)_FLD2VAL(CRYPTO_PR_RESULT_DATA32, CRYPTO->PR_RESULT);
return (CY_CRYPTO_SUCCESS);
}
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_PR == 1) && (CY_CRYPTO_USER_PR == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
/* [] END OF FILE */

View File

@ -0,0 +1,39 @@
/***************************************************************************//**
* \file cy_crypto_core_prng.h
* \version 1.0
*
* \brief
* This file provides provides constant and parameters for the API of the PRNG
* in the Crypto block driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_PRNG_H)
#define CY_CRYPTO_CORE_PRNG_H
#include "crypto/cy_crypto_common.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_PR == 1) && (CY_CRYPTO_USER_PR == 1))
cy_en_crypto_status_t Cy_Crypto_Core_Prng_Init (cy_stc_crypto_context_prng_t *cryptoPrngContext);
cy_en_crypto_status_t Cy_Crypto_Core_Prng (cy_stc_crypto_context_prng_t *cryptoPrngContext);
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_PR == 1) && (CY_CRYPTO_USER_PR == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_CORE_PRNG_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,993 @@
/***************************************************************************//**
* \file cy_crypto_core_rsa.c
* \version 1.0
*
* \brief
* This file provides the source code to the API to calculate
* a signature by the RSA method in the Crypto block driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "crypto/cy_crypto_common.h"
#include "crypto/cy_crypto_core_rsa.h"
#include "crypto/cy_crypto_core_instructions.h"
#include "crypto/cy_crypto_core_util.h"
#include "crypto/cy_crypto_core_vu_hw.h"
#include "crypto/cy_crypto_core_vu.h"
#include "crypto/cy_crypto_core_sha.h"
#include "syslib/cy_syslib.h"
#include <string.h>
#if (CY_CPU_CORTEX_M0P)
#define CY_CRYPTO_SHA1_PADDING_SIZE (15u)
#define CY_CRYPTO_SHA256_512_PADDING_SIZE (19u)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1))
/* Functions prototypes */
void Cy_Crypto_Core_Rsa_MontCoeff(uint32_t modDerReg, uint32_t modReg, uint32_t size);
void Cy_Crypto_Core_Rsa_BarrettGetU(uint32_t barrettUReg, uint32_t modReg, uint32_t size);
void Cy_Crypto_Core_Rsa_BarretRed(uint32_t resultReg, uint32_t aReg, uint32_t barrettUReg, uint32_t modReg, uint32_t size);
void Cy_Crypto_Core_Rsa_MontTransform(uint32_t z, uint32_t a, uint32_t barrett_u, uint32_t mod, uint32_t size);
void Cy_Crypto_Core_Rsa_MontMul(uint32_t z, uint32_t a, uint32_t b, uint32_t mont_mod_der, uint32_t mod, uint32_t size);
void Cy_Crypto_Core_Rsa_expModByMont(uint32_t y,
uint32_t x,
uint32_t e,
uint32_t n,
uint32_t barretCoef,
uint32_t inverseModulo,
uint32_t rBar,
uint32_t size);
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1)) */
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CY_CRYPTO_USER_PKCS1_5 == 1))
/* Encodings for hash functions */
#if ((CPUSS_CRYPTO_SHA1 == 1) && (CY_CRYPTO_USER_SHA1 == 1))
static const uint8_t Sha1EncStr[CY_CRYPTO_SHA1_PADDING_SIZE] =
{
0x14u, 0x04u, 0x00u, 0x05u,
0x1Au, 0x02u, 0x03u, 0x0Eu, 0x2Bu, 0x05u, 0x06u, 0x09u,
0x30u, 0x21u, 0x30u
};
#endif /* #if ((CPUSS_CRYPTO_SHA1 == 1) && (CY_CRYPTO_USER_SHA1 == 1)) */
#if ((CPUSS_CRYPTO_SHA256 == 1) && (CY_CRYPTO_USER_SHA256 == 1))
static const uint8_t Sha224EncStr[CY_CRYPTO_SHA256_512_PADDING_SIZE] =
{
0x1Cu, 0x04u, 0x00u, 0x05u, 0x04u, 0x02u, 0x04u, 0x03u,
0x65u, 0x01u, 0x48u, 0x86u, 0x60u, 0x09u, 0x06u, 0x0du,
0x30u, 0x2Du, 0x30u
};
static const uint8_t Sha256EncStr[CY_CRYPTO_SHA256_512_PADDING_SIZE] =
{
0x20u, 0x04u, 0x00u, 0x05u, 0x01u, 0x02u, 0x04u, 0x03u,
0x65u, 0x01u, 0x48u, 0x86u, 0x60u, 0x09u, 0x06u, 0x0du,
0x30u, 0x31u, 0x30u
};
#endif /* #if ((CPUSS_CRYPTO_SHA256 == 1) && (CY_CRYPTO_USER_SHA256 == 1)) */
#if ((CPUSS_CRYPTO_SHA512 == 1) && (CY_CRYPTO_USER_SHA512 == 1))
static const uint8_t Sha384EncStr[CY_CRYPTO_SHA256_512_PADDING_SIZE] =
{
0x30u, 0x04u, 0x00u, 0x05u, 0x02u, 0x02u, 0x04u, 0x03u,
0x65u, 0x01u, 0x48u, 0x86u, 0x60u, 0x09u, 0x06u, 0x0du,
0x30u, 0x41u, 0x30u
};
static const uint8_t Sha512EncStr[CY_CRYPTO_SHA256_512_PADDING_SIZE] =
{
0x40u, 0x04u, 0x00u, 0x05u, 0x03u, 0x02u, 0x04u, 0x03u,
0x65u, 0x01u, 0x48u, 0x86u, 0x60u, 0x09u, 0x06u, 0x0du,
0x30u, 0x51u, 0x30u
};
static const uint8_t Sha512_224EncStr[CY_CRYPTO_SHA256_512_PADDING_SIZE] =
{
0x1Cu, 0x04u, 0x00u, 0x05u, 0x05u, 0x02u, 0x04u, 0x03u,
0x65u, 0x01u, 0x48u, 0x86u, 0x60u, 0x09u, 0x06u, 0x0du,
0x30u, 0x2Du, 0x30u
};
static const uint8_t Sha512_256EncStr[CY_CRYPTO_SHA256_512_PADDING_SIZE] =
{
0x20u, 0x04u, 0x00u, 0x05u, 0x06u, 0x02u, 0x04u, 0x03u,
0x65u, 0x01u, 0x48u, 0x86u, 0x60u, 0x09u, 0x06u, 0x0du,
0x30u, 0x31u, 0x30u
};
#endif /* #if ((CPUSS_CRYPTO_SHA512 == 1) && (CY_CRYPTO_USER_SHA512 == 1)) */
/*******************************************************************************
* Function Name: Cy_Crypto_Core_RsaVerify
****************************************************************************//**
*
* RSA verification with checks for content, paddings and signature format.
* SHA digest of the message and decrypted message should be calculated before.
* Supports only PKCS1-v1_5 format, inside of this format supported padding
* using only SHA, cases with MD2 and MD5 are not supported.
* PKCS1-v1_5 described here, page 31:
* http://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf
*
* Returns the verification result \ref cy_en_crypto_rsa_ver_result_t.
*
* \param cryptoContextPtr
* Pointer to the RSA context
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_RsaVerify(cy_stc_crypto_context_rsa_ver_t *cryptoContextPtr)
{
cy_en_crypto_status_t result = CY_CRYPTO_SUCCESS;
cy_en_crypto_sha_mode_t _digestType = cryptoContextPtr->digestType;
uint8_t *_digestPtr = (uint8_t*)cryptoContextPtr->hashPtr;
uint8_t *_decryptedSignaturePtr = (uint8_t*)cryptoContextPtr->decryptedSignaturePtr;
uint32_t _decryptedSignatureLength = cryptoContextPtr->decryptedSignatureLength;
cy_en_crypto_rsa_ver_result_t *_verResult = cryptoContextPtr->verResult;
uint8_t *psBeginPtr;
uint8_t *encodingArrPtr = NULL;
uint32_t encodingArrSize = 0;
uint32_t digestSize = 0;
uint32_t i;
int32_t psLength;
int32_t cmpRes = 0;
switch (_digestType)
{
#if ((CPUSS_CRYPTO_SHA1 == 1) && (CY_CRYPTO_USER_SHA1 == 1))
case CY_CRYPTO_MODE_SHA1:
encodingArrPtr = (uint8_t*)Sha1EncStr;
encodingArrSize = sizeof(Sha1EncStr);
digestSize = CY_CRYPTO_SHA1_DIGEST_SIZE;
break;
#endif /* #if ((CPUSS_CRYPTO_SHA1 == 1) && (CY_CRYPTO_USER_SHA1 == 1)) */
#if ((CPUSS_CRYPTO_SHA256 == 1) && (CY_CRYPTO_USER_SHA256 == 1))
case CY_CRYPTO_MODE_SHA224:
encodingArrPtr = (uint8_t*)Sha224EncStr;
encodingArrSize = sizeof(Sha224EncStr);
digestSize = CY_CRYPTO_SHA224_DIGEST_SIZE;
break;
case CY_CRYPTO_MODE_SHA256:
encodingArrPtr = (uint8_t*)Sha256EncStr;
encodingArrSize = sizeof(Sha256EncStr);
digestSize = CY_CRYPTO_SHA256_DIGEST_SIZE;
break;
#endif /* #if ((CPUSS_CRYPTO_SHA256 == 1) && (CY_CRYPTO_USER_SHA256 == 1)) */
#if ((CPUSS_CRYPTO_SHA512 == 1) && (CY_CRYPTO_USER_SHA512 == 1))
case CY_CRYPTO_MODE_SHA384:
encodingArrPtr = (uint8_t*)Sha384EncStr;
encodingArrSize = sizeof(Sha384EncStr);
digestSize = CY_CRYPTO_SHA384_DIGEST_SIZE;
break;
case CY_CRYPTO_MODE_SHA512:
encodingArrPtr = (uint8_t*)Sha512EncStr;
encodingArrSize = sizeof(Sha512EncStr);
digestSize = CY_CRYPTO_SHA512_DIGEST_SIZE;
break;
case CY_CRYPTO_MODE_SHA512_224:
encodingArrPtr = (uint8_t*)Sha512_224EncStr;
encodingArrSize = sizeof(Sha512_224EncStr);
digestSize = CY_CRYPTO_SHA512_224_DIGEST_SIZE;
break;
case CY_CRYPTO_MODE_SHA512_256:
encodingArrPtr = (uint8_t*)Sha512_256EncStr;
encodingArrSize = sizeof(Sha512_256EncStr);
digestSize = CY_CRYPTO_SHA512_256_DIGEST_SIZE;
break;
#endif /* #if ((CPUSS_CRYPTO_SHA512 == 1) && (CY_CRYPTO_USER_SHA512 == 1)) */
default:
break;
}
/* Fail by default */
*_verResult = CY_CRYPTO_RSA_VERIFY_FAIL;
/* Check size of decrypted message */
if (_decryptedSignatureLength < (encodingArrSize + digestSize + 11))
{
cmpRes = 1; /* further checking is not needed */
}
psLength = _decryptedSignatureLength - digestSize - encodingArrSize - 3;
/* Address of start of T string (0xFFs) in padding */
psBeginPtr = _decryptedSignaturePtr + _decryptedSignatureLength - 3;
/* Check whether the begin of message is 0x00, 0x01 and after PS string (before T string) is 0x00 byte.*/
if ( (0 != cmpRes) ||
(0x00 != *(psBeginPtr + 2)) ||
(0x01 != *(psBeginPtr + 1)) ||
(0x00 != *(_decryptedSignaturePtr + _decryptedSignatureLength - psLength - 3)) )
{
cmpRes = 1; /* Further checking is not needed */
}
/* Check FFs */
if (0 == cmpRes )
{
for (i = psLength; i > 0; i--)
{
if (0xFF != *(psBeginPtr - i + 1))
{
cmpRes = 1; /* Further checking is not needed */
break;
}
}
}
/* Check the padding (T string) */
if (0 == cmpRes)
{
cmpRes = memcmp(encodingArrPtr,
(_decryptedSignaturePtr + digestSize),
encodingArrSize);
}
/* Check the digest */
if (0 == cmpRes)
{
_decryptedSignaturePtr = _decryptedSignaturePtr + digestSize - 1;
for (i = digestSize; i > 0; i--)
{
if( *_decryptedSignaturePtr != *_digestPtr )
{
cmpRes = 1; /* Further checking is not needed */
break;
}
_decryptedSignaturePtr--;
_digestPtr++;
}
}
if (0 == cmpRes )
{
*_verResult = CY_CRYPTO_RSA_VERIFY_SUCCESS;
}
return (result);
}
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CY_CRYPTO_USER_PKCS1_5 == 1)) */
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1))
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Rsa_MontCoeff
****************************************************************************//**
*
* Calculation of Montgomery coefficients for Montgomery multiplication in GF(p).
*
* Reference: "Montgomery Multiplication", H. S. Warren, Jr., July 2012
* Reference: http://www.hackersdelight.org/MontgomeryMultiplication.pdf
*
* GCD method is used, reference:
* https://en.wikipedia.org/wiki/Binary_GCD_algorithm
*
* Inputs: modulus n, k = number of bits in n;
* Outputs: R^-1 and n' which allows equation: R*R^-1 - n*n' = 1,
* where R = 1 << size.
*
* Leaf function.
*
* \param modDerReg
* Register index for Montgomery coefficient value.
*
* \param modReg
* Register index for modulo value.
*
* \param size
* Size of modulo, in Bits.
*
*******************************************************************************/
void Cy_Crypto_Core_Rsa_MontCoeff(uint32_t modDerReg, uint32_t modReg, uint32_t size)
{
uint32_t my_mod = 9;
uint32_t tmp = 10;
uint32_t a = 11;
uint32_t b = 12;
uint32_t u = 13;
uint32_t v = 14;
uint16_t status;
uint16_t a_zero;
uint16_t u_even;
CY_CRYPTO_VU_PUSH_REG ();
CY_CRYPTO_VU_LD_REG (v, modDerReg);
CY_CRYPTO_VU_LD_REG (my_mod, modReg);
CY_CRYPTO_VU_ALLOC_MEM (a, size);
CY_CRYPTO_VU_ALLOC_MEM (b, size);
CY_CRYPTO_VU_ALLOC_MEM (u, size);
CY_CRYPTO_VU_SET_TO_ONE (u);
CY_CRYPTO_VU_SET_TO_ZERO (v);
CY_CRYPTO_VU_SET_TO_ZERO (a);
CY_CRYPTO_VU_SET_REG (tmp, (size - 1), 1);
CY_CRYPTO_VU_SET_BIT (a, tmp);
CY_CRYPTO_VU_MOV (b, my_mod);
while(1)
{
Cy_Crypto_Core_WaitForReady();
CY_CRYPTO_VU_TST(a);
status = Cy_Crypto_Core_Vu_StatusRead();
a_zero = status & (1 << CY_CRYPTO_VU_STATUS_ZERO);
if(a_zero != 0)
{
break;
}
CY_CRYPTO_VU_LSR1(a, a);
CY_CRYPTO_VU_TST(u);
status = Cy_Crypto_Core_Vu_StatusRead();
u_even = status & (1 << CY_CRYPTO_VU_STATUS_EVEN);
if(u_even != 0)
{
CY_CRYPTO_VU_LSR1(u, u);
CY_CRYPTO_VU_LSR1(v, v);
}
else
{
CY_CRYPTO_VU_ADD(u, u, b);
CY_CRYPTO_VU_LSR1_WITH_CARRY(u, u);
CY_CRYPTO_VU_LSR1(v, v);
CY_CRYPTO_VU_SET_BIT(v, tmp);
}
}
CY_CRYPTO_VU_FREE_MEM((1 << a) | (1 << b) | (1 << u));
CY_CRYPTO_VU_POP_REG();
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Rsa_BarrettGetU
****************************************************************************//**
*
* Calculation of Barrett coefficient for Barrett reduction in GF(p).
*
* The function reduces the size of the Barrett coefficient by removing leading '0' bits.
* This improves the performance of the Barrett reduction (faster multiplication).
* (1 << bit_size) > mod > (1 << (bit_size-1))
*
* barrett_u = (1 << (2 * size)) / mod NO!!! leading '1' Barrett bit.
*
* Leaf function.
*
* \param barrettUReg
* Register index for Barrett reduction value.
*
* \param modReg
* Register index for modulo value.
*
* \param
* Size modulo size in Bits.
*
*******************************************************************************/
void Cy_Crypto_Core_Rsa_BarrettGetU(uint32_t barrettUReg, uint32_t modReg, uint32_t size)
{
uint32_t dividend = 0;
uint32_t t = 1;
uint32_t temp = 2;
uint32_t sh = 3;
int32_t i;
CY_CRYPTO_VU_ALLOC_MEM(dividend, size+1);
CY_CRYPTO_VU_ALLOC_MEM(t, size+1);
CY_CRYPTO_VU_ALLOC_MEM(temp, size+1);
/* (1 << size) there is probably a more efficient way to initialize this */
CY_CRYPTO_VU_SET_REG (sh, size, 1);
CY_CRYPTO_VU_SET_TO_ZERO (dividend);
CY_CRYPTO_VU_SET_BIT (dividend, sh);
CY_CRYPTO_VU_MOV (temp, dividend);
CY_CRYPTO_VU_SET_TO_ZERO (barrettUReg);
for (i = size; i >= 0; i--)
{
/* C = (a >= b) */
CY_CRYPTO_VU_SUB (t, dividend, modReg);
CY_CRYPTO_VU_COND_SWAP_REG (CY_CRYPTO_VU_COND_CS, dividend, t);
CY_CRYPTO_VU_COND_XOR (CY_CRYPTO_VU_COND_CS, barrettUReg, barrettUReg, temp);
CY_CRYPTO_VU_LSL1 (dividend, dividend);
CY_CRYPTO_VU_LSR1 (temp, temp);
}
CY_CRYPTO_VU_FREE_MEM((1 << dividend) | (1 << temp) | (1 << t));
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Rsa_BarretRed
****************************************************************************//**
*
* Barrett reduction in GF(p).
*
* z = a_double mod modulo
*
* t[b-1:0] = z_double >> size
* t = t * barrett_u
* t = t + ((z_double >> size) << size) "for leading '1' Barrett bit"
* t = t >> size
* t = t * mod
* u = z_double - t
* u = IF (u >= mod) u = u - mod
*
* Leaf function.
*
* \param resultReg
* Register index for Barrett reduced value.
*
* \param aReg
* Register index for non reduced value.
*
* \param barrettUReg
* Register index for Barrett reduction value.
*
* \param modReg
* Register index for modulo value.
*
* \param size
* Bit size.
*
*******************************************************************************/
void Cy_Crypto_Core_Rsa_BarretRed(uint32_t resultReg, uint32_t aReg, uint32_t barrettUReg, uint32_t modReg, uint32_t size)
{
uint32_t sh = 0;
uint32_t t_double = 1;
uint32_t z_double = 2;
CY_CRYPTO_VU_ALLOC_MEM (t_double, 2 * size);
CY_CRYPTO_VU_ALLOC_MEM (z_double, 2 * size);
CY_CRYPTO_VU_SET_REG (sh, size, 1);
CY_CRYPTO_VU_LSR (t_double, aReg, sh);
CY_CRYPTO_VU_UMUL (z_double, t_double, barrettUReg);
CY_CRYPTO_VU_LSL (t_double, t_double, sh);
CY_CRYPTO_VU_ADD (z_double, z_double, t_double);
CY_CRYPTO_VU_LSR (z_double, z_double, sh);
CY_CRYPTO_VU_UMUL (t_double, z_double, modReg);
CY_CRYPTO_VU_SUB (z_double, aReg, t_double);
/* C = (a >= b) */
CY_CRYPTO_VU_CMP_SUB (z_double, modReg);
CY_CRYPTO_VU_COND_SUB (CY_CRYPTO_VU_COND_CS, z_double, z_double, modReg);
CY_CRYPTO_VU_CMP_SUB (z_double, modReg);
CY_CRYPTO_VU_COND_SUB (CY_CRYPTO_VU_COND_CS, z_double, z_double, modReg);
CY_CRYPTO_VU_MOV (resultReg, z_double);
CY_CRYPTO_VU_FREE_MEM ((1 << z_double) | (1 << t_double));
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Rsa_MontTransform
****************************************************************************//**
*
* \brief Conversion to Montgomery representation.
*
* z = (a << size) % mod
*
* \param z
* Register index for Montgomery representation value.
*
* \param a
* Register index for regular representation value.
*
* \param barrett_u
* Register index for Barrett reduction value.
*
* \param mod
* Register index for modulo value.
*
* \param size
* Bit size.
*
*******************************************************************************/
void Cy_Crypto_Core_Rsa_MontTransform(uint32_t z, uint32_t a, uint32_t barrett_u, uint32_t mod, uint32_t size)
{
uint32_t sh = 0;
uint32_t t1_plus2 = 1;
uint32_t t2_plus2 = 0;
uint32_t t_double = 2;
uint32_t a_double = 3;
CY_CRYPTO_VU_ALLOC_MEM (t_double, 2 * size);
CY_CRYPTO_VU_ALLOC_MEM (a_double, 2 * size);
CY_CRYPTO_VU_SET_REG (sh, size, 1);
CY_CRYPTO_VU_UMUL (t_double, a, barrett_u);
CY_CRYPTO_VU_LSR (a_double, t_double, sh);
CY_CRYPTO_VU_UMUL (t_double, a_double, mod);
CY_CRYPTO_VU_LSL (a_double, a, sh);
CY_CRYPTO_VU_ALLOC_MEM (t2_plus2, size + 2);
CY_CRYPTO_VU_SUB (t2_plus2, a_double, t_double);
CY_CRYPTO_VU_FREE_MEM ((1 << a_double) | (1 << t_double));
CY_CRYPTO_VU_ALLOC_MEM (t1_plus2, size + 2);
/* Check CARRY = (a >= b) */
CY_CRYPTO_VU_SUB (t1_plus2, t2_plus2, mod);
CY_CRYPTO_VU_COND_SWAP_REG (CY_CRYPTO_VU_COND_CC, t1_plus2, t2_plus2);
/* Check CARRY = (a >= b) */
CY_CRYPTO_VU_SUB (t2_plus2, t1_plus2, mod);
CY_CRYPTO_VU_COND_MOV (CY_CRYPTO_VU_COND_CC, z, t1_plus2);
CY_CRYPTO_VU_COND_MOV (CY_CRYPTO_VU_COND_CS, z, t2_plus2);
CY_CRYPTO_VU_FREE_MEM ((1 << t2_plus2) | (1 << t1_plus2));
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Rsa_MontMul
****************************************************************************//**
*
* Montgomery multiplication in GF(p).
*
* z = a * b * r % mod
*
* t = mont_a * mont_b
* u = t * mont_mod_der "only lower 32 bits are needed"
* u = u * mod
* u = u + t
* u = u >> size
* u = IF (u >= mod) u = u - mod
*
* Leaf function.
*
* \param z
* Register index for product value.
*
* \param a
* Register index for multiplicand value.
*
* \param b
* Register index for multiplier value.
*
* \param mont_mod_der
* Register index for Montgomery coefficient value.
*
* \param mod
* Register index for modulo value.
*
* \param size
* Bit size.
*
*******************************************************************************/
void Cy_Crypto_Core_Rsa_MontMul(uint32_t z, uint32_t a, uint32_t b, uint32_t mont_mod_der, uint32_t mod, uint32_t size)
{
uint32_t sh = 0;
uint32_t t = 1;
uint32_t u_double = 2;
uint32_t t_double = 3;
uint32_t status = 4;
CY_CRYPTO_VU_ALLOC_MEM (t, size + 1);
CY_CRYPTO_VU_ALLOC_MEM (u_double, 2 * size);
CY_CRYPTO_VU_ALLOC_MEM (t_double, 2 * size);
CY_CRYPTO_VU_SET_REG (sh, size, 1);
CY_CRYPTO_VU_UMUL (t_double, a, b);
/* Only lower 32 bits are needed */
CY_CRYPTO_VU_UMUL (t, t_double, mont_mod_der);
/* Clear the MSB bit (cut to size length) */
CY_CRYPTO_VU_LSL1(t, t);
CY_CRYPTO_VU_LSR1(t, t);
CY_CRYPTO_VU_UMUL (u_double, t, mod);
CY_CRYPTO_VU_ADD (u_double, u_double, t_double);
CY_CRYPTO_VU_MOV_STATUS_TO_REG (status);
CY_CRYPTO_VU_LSR (u_double, u_double, sh);
CY_CRYPTO_VU_SET_TO_ZERO (t);
CY_CRYPTO_VU_SET_REG (sh, 0, 1);
CY_CRYPTO_VU_SET_BIT (t, sh);
CY_CRYPTO_VU_SET_REG (sh, size, 1);
CY_CRYPTO_VU_LSL (t, t, sh);
CY_CRYPTO_VU_MOV_REG_TO_STATUS (status);
Cy_Crypto_Core_WaitForReady();
CY_CRYPTO_VU_COND_XOR (CY_CRYPTO_VU_COND_CS, u_double, u_double, t);
/* C = (a >= b) */
CY_CRYPTO_VU_SUB (t_double, u_double, mod);
CY_CRYPTO_VU_COND_SWAP_REG (CY_CRYPTO_VU_COND_CS, u_double, t_double);
CY_CRYPTO_VU_MOV (z, u_double);
CY_CRYPTO_VU_FREE_MEM ((1 << t_double) | (1 << u_double) | (1 << t));
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Rsa_expModByMont
****************************************************************************//**
*
* Perform y = x^e mod n using Montgomery reduction technique to speed-up
* calculation. Suitable for cases with short e.
*
* \param y
* Register index for calculated value.
*
* \param x
* Register index for multiplicand value.
*
* \param e
* Register index for exponent value.
*
* \param n
* Register index for modulo value.
*
* \param size
* modulo size, in Bits
*
*******************************************************************************/
void Cy_Crypto_Core_Rsa_expModByMont(uint32_t y,
uint32_t x,
uint32_t e,
uint32_t n,
uint32_t barretCoef,
uint32_t inverseModulo,
uint32_t rBar,
uint32_t size)
{
int32_t i;
uint16_t j;
uint16_t status;
uint16_t carry;
uint16_t clsame;
uint32_t my_y = 5;
uint32_t my_x = 6;
uint32_t my_e = 7;
uint32_t my_n = 8;
uint32_t R0_1 = 9;
uint32_t n_prime = 10;
uint32_t temp = 11;
uint32_t barrett_u = 12;
uint32_t x_bar = 13;
uint32_t REG = 14;
CY_CRYPTO_VU_PUSH_REG();
CY_CRYPTO_VU_LD_REG(my_x, x);
CY_CRYPTO_VU_LD_REG(my_y, y);
CY_CRYPTO_VU_LD_REG(my_e, e);
CY_CRYPTO_VU_LD_REG(my_n, n);
CY_CRYPTO_VU_LD_REG(n_prime, inverseModulo);
CY_CRYPTO_VU_LD_REG(barrett_u, barretCoef);
CY_CRYPTO_VU_MOV(my_y, rBar);
CY_CRYPTO_VU_ALLOC_MEM(R0_1, size);
CY_CRYPTO_VU_ALLOC_MEM(x_bar, size);
CY_CRYPTO_VU_ALLOC_MEM(temp, size);
Cy_Crypto_Core_Rsa_MontTransform(x_bar, my_x, barrett_u, my_n, size);
Cy_Crypto_Core_WaitForReady();
CY_CRYPTO_VU_MOV(temp, my_e);
CY_CRYPTO_VU_SET_TO_ZERO(R0_1);
CY_CRYPTO_VU_CLSAME(REG, temp, R0_1);
/* This is needed, otherwise clsame is wrong */
Cy_Crypto_Core_WaitForReady();
clsame = Cy_Crypto_Core_Vu_RegDataPtrRead(REG);
j = Cy_Crypto_Core_Vu_RegSizeRead(temp) + 1 - clsame;
CY_CRYPTO_VU_SET_REG(REG, clsame, 1);
CY_CRYPTO_VU_LSL(temp, temp, REG);
for (i = j; i > 0; i--)
{
/* j is number of bits in exponent e */
Cy_Crypto_Core_Rsa_MontMul(my_y, my_y, my_y, n_prime, my_n, size);
Cy_Crypto_Core_WaitForReady();
CY_CRYPTO_VU_LSL1(temp, temp);
status = Cy_Crypto_Core_Vu_StatusRead();
carry = status & (1 << CY_CRYPTO_VU_STATUS_CARRY);
if (carry != 0)
{
Cy_Crypto_Core_Rsa_MontMul(my_y, my_y, x_bar, n_prime, my_n, size);
}
}
CY_CRYPTO_VU_SET_TO_ONE(R0_1);
Cy_Crypto_Core_Rsa_MontMul(my_y, my_y, R0_1, n_prime , my_n, size);
CY_CRYPTO_VU_FREE_MEM((1 << R0_1) | (1 << x_bar) | (1 << temp));
CY_CRYPTO_VU_POP_REG();
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Rsa_Proc
****************************************************************************//**
*
* RSA process algorithm based on the Montgomery algorithm
* using Barrett reduction
*
* https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29
*
* \param cryptoContextPtr
* Pointer to the RSA context
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Rsa_Proc(cy_stc_crypto_context_rsa_t *cryptoContextPtr)
{
cy_en_crypto_status_t result = CY_CRYPTO_SUCCESS;
uint8_t *_expPtr = cryptoContextPtr->keyPtr->pubExpPtr;
uint32_t _expBitLength = cryptoContextPtr->keyPtr->pubExpLength;
uint8_t *_nPtr = cryptoContextPtr->keyPtr->moduloPtr;
uint32_t _nBitLength = cryptoContextPtr->keyPtr->moduloLength;
uint32_t *_messagePtr = (uint32_t*)cryptoContextPtr->messagePtr;
uint32_t _messageByteLength = cryptoContextPtr->messageLength;
uint32_t *_resultPtr = (uint32_t*)cryptoContextPtr->resultPtr;
uint8_t *_barretCoefPtr = cryptoContextPtr->keyPtr->barretCoefPtr;
uint8_t *_inverseModuloPtr = cryptoContextPtr->keyPtr->inverseModuloPtr;
uint8_t *_rBarPtr = cryptoContextPtr->keyPtr->rBarPtr;
uint32_t _nByteLength = 0;
uint32_t _barretByteLength = 0;
uint32_t _expByteLength = 0;
uint32_t yReg = 5;
uint32_t xReg = 6;
uint32_t eReg = 7;
uint32_t modReg = 8;
uint32_t inverseModuloReg = 9;
uint32_t barrettReg = 10;
uint32_t rBarReg = 11;
/* Clear all Crypto SRAM before operations */
memset((void*)CRYPTO->MEM_BUFF, 0x00, CPUSS_CRYPTO_BUFF_SIZE * 4);
CY_CRYPTO_VU_ALLOC_MEM(yReg, _nBitLength);
CY_CRYPTO_VU_ALLOC_MEM(xReg, _nBitLength);
CY_CRYPTO_VU_ALLOC_MEM(eReg, _nBitLength);
CY_CRYPTO_VU_ALLOC_MEM(modReg, _nBitLength);
CY_CRYPTO_VU_ALLOC_MEM(barrettReg, _nBitLength + 1);
CY_CRYPTO_VU_ALLOC_MEM(inverseModuloReg, _nBitLength);
CY_CRYPTO_VU_ALLOC_MEM(rBarReg, _nBitLength);
_nByteLength = _nBitLength / 8;
if ((_nBitLength % 8) != 0)
{
_nByteLength += 1;
}
_barretByteLength = (_nBitLength + 1) / 8;
if (((_nBitLength + 1) % 8) != 0)
{
_barretByteLength += 1;
}
_expByteLength = _expBitLength / 8;
if ((_expBitLength % 8) != 0)
{
_expByteLength += 1;
}
memcpy((void*)((uint32_t)CRYPTO->MEM_BUFF + 4 * Cy_Crypto_Core_Vu_RegDataPtrRead(modReg)), _nPtr, _nByteLength);
memcpy((void*)((uint32_t)CRYPTO->MEM_BUFF + 4 * Cy_Crypto_Core_Vu_RegDataPtrRead(eReg)), _expPtr, _expByteLength);
memcpy((void*)((uint32_t)CRYPTO->MEM_BUFF + 4 * Cy_Crypto_Core_Vu_RegDataPtrRead(xReg)), _messagePtr, _messageByteLength);
/* Check coefficients */
if (_barretCoefPtr == NULL)
{
Cy_Crypto_Core_Rsa_BarrettGetU(barrettReg, modReg, _nBitLength);
Cy_Crypto_Core_WaitForReady();
}
else
{
memcpy((void*)((uint32_t)CRYPTO->MEM_BUFF + 4 * Cy_Crypto_Core_Vu_RegDataPtrRead(barrettReg)),
_barretCoefPtr,
_barretByteLength);
}
if (_rBarPtr == NULL)
{
/* inverseModuloReg used here as temp variable */
CY_CRYPTO_VU_SET_TO_ONE(inverseModuloReg);
Cy_Crypto_Core_Rsa_MontTransform(rBarReg, inverseModuloReg, barrettReg, modReg, _nBitLength);
Cy_Crypto_Core_WaitForReady();
}
else
{
memcpy((void*)((uint32_t)CRYPTO->MEM_BUFF + 4 * Cy_Crypto_Core_Vu_RegDataPtrRead(rBarReg)),
_rBarPtr,
_nByteLength);
}
if (_inverseModuloPtr == NULL)
{
Cy_Crypto_Core_Rsa_MontCoeff(inverseModuloReg, modReg, _nBitLength);
Cy_Crypto_Core_WaitForReady();
}
else
{
memcpy((void*)((uint32_t)CRYPTO->MEM_BUFF + 4 * Cy_Crypto_Core_Vu_RegDataPtrRead(inverseModuloReg)),
_inverseModuloPtr,
_nByteLength);
}
Cy_Crypto_Core_Rsa_expModByMont(yReg,
xReg,
eReg,
modReg,
barrettReg,
inverseModuloReg,
rBarReg,
_nBitLength);
Cy_Crypto_Core_Vu_WaitForComplete();
/* Copy the result to output buffer */
memcpy((void*)_resultPtr, (void*)((uint32_t)CRYPTO->MEM_BUFF + 4 * Cy_Crypto_Core_Vu_RegDataPtrRead(yReg)), _nByteLength);
CY_CRYPTO_VU_FREE_MEM((1 << yReg) | (1 << xReg) | (1 << eReg) | (1 << modReg) |
(1 << inverseModuloReg) | (1 << barrettReg) | (1 << rBarReg));
return (result);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Rsa_Coef
****************************************************************************//**
*
* Calculation constant coefficients to to speed-up Montgomery algorithm.
* These coefficients are:
* coefficient for Barrett reduction,
* binary inverse of the modulo,
* result of (2^moduloLength mod modulo)
*
* \param cryptoContextPtr
* Pointer to the RSA context
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Rsa_Coef(cy_stc_crypto_context_rsa_t *cryptoContextPtr)
{
cy_en_crypto_status_t result = CY_CRYPTO_SUCCESS;
uint8_t *_nPtr = cryptoContextPtr->keyPtr->moduloPtr;
uint32_t _nBitLength = cryptoContextPtr->keyPtr->moduloLength;
uint8_t *_barretCoefPtr = cryptoContextPtr->keyPtr->barretCoefPtr;
uint8_t *_inverseModuloPtr = cryptoContextPtr->keyPtr->inverseModuloPtr;
uint8_t *_rBarPtr = cryptoContextPtr->keyPtr->rBarPtr;
uint32_t _nByteLength;
uint32_t _barretByteLength;
uint32_t modReg = 11;
uint32_t inverseModuloReg = 12;
uint32_t barrettReg = 13;
uint32_t rBarReg = 14;
/* Clear all Crypto SRAM before operations */
memset((void*)CRYPTO->MEM_BUFF, 0x00, CPUSS_CRYPTO_BUFF_SIZE * 4);
CY_CRYPTO_VU_ALLOC_MEM(modReg, _nBitLength);
CY_CRYPTO_VU_ALLOC_MEM(barrettReg, _nBitLength + 1);
CY_CRYPTO_VU_ALLOC_MEM(inverseModuloReg, _nBitLength);
CY_CRYPTO_VU_ALLOC_MEM(rBarReg, _nBitLength);
_nByteLength = _nBitLength / 8;
if ((_nBitLength % 8) != 0)
{
_nByteLength += 1;
}
_barretByteLength = (_nBitLength + 1) / 8;
if (((_nBitLength + 1) % 8) != 0)
{
_barretByteLength += 1;
}
/* Copy modulo to Crypto SRAM */
memcpy((void*)((uint32_t)CRYPTO->MEM_BUFF + 4 * Cy_Crypto_Core_Vu_RegDataPtrRead(modReg)),
_nPtr,
_nByteLength);
Cy_Crypto_Core_Rsa_BarrettGetU(barrettReg, modReg, _nBitLength);
Cy_Crypto_Core_WaitForReady();
/* Copy calculated Barrett coefficient */
memcpy((void*)_barretCoefPtr,
(void*)((uint32_t)CRYPTO->MEM_BUFF + 4 * Cy_Crypto_Core_Vu_RegDataPtrRead(barrettReg)),
_barretByteLength);
/* inverseModuloReg used here as temp variable */
CY_CRYPTO_VU_SET_TO_ONE(inverseModuloReg);
Cy_Crypto_Core_Rsa_MontTransform(rBarReg, inverseModuloReg, barrettReg, modReg, _nBitLength);
Cy_Crypto_Core_WaitForReady();
/* Copy calculated r-bar = (1 << size) mod modulo */
memcpy((void*)_rBarPtr,
(void*)((uint32_t)CRYPTO->MEM_BUFF + 4 * Cy_Crypto_Core_Vu_RegDataPtrRead(rBarReg)),
_nByteLength);
Cy_Crypto_Core_Rsa_MontCoeff(inverseModuloReg, modReg, _nBitLength);
Cy_Crypto_Core_WaitForReady();
/* Copy calculated inverse modulo */
memcpy((void*)_inverseModuloPtr,
(void*)((uint32_t)CRYPTO->MEM_BUFF + 4 * Cy_Crypto_Core_Vu_RegDataPtrRead(inverseModuloReg)),
_nByteLength);
CY_CRYPTO_VU_FREE_MEM((1 << modReg) | (1 << inverseModuloReg) | (1 << barrettReg) | (1 << rBarReg));
return (result);
}
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */

View File

@ -0,0 +1,62 @@
/***************************************************************************//**
* \file cy_crypto_core_rsa.h
* \version 1.0
*
* \brief
* This file provides provides constant and parameters
* for the API of the RSA in the Crypto block driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_RSA_H)
#define CY_CRYPTO_CORE_RSA_H
#include "crypto/cy_crypto_common.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1))
/* Crypto IP condition codes (vector unit) */
#define CY_CRYPTO_VU_COND_ALWAYS (0x00u)
#define CY_CRYPTO_VU_COND_EQ (0x01u)
#define CY_CRYPTO_VU_COND_NE (0x02u)
#define CY_CRYPTO_VU_COND_CS (0x03u)
#define CY_CRYPTO_VU_COND_CC (0x04u)
#define CY_CRYPTO_VU_COND_HI (0x05u)
#define CY_CRYPTO_VU_COND_LS (0x06u)
#define CY_CRYPTO_VU_COND_EVEN (0x07u)
#define CY_CRYPTO_VU_COND_ODD (0x08u)
/* Crypto IP status (vector unit) */
#define CY_CRYPTO_VU_STATUS_ONE (3u)
#define CY_CRYPTO_VU_STATUS_ZERO (2u)
#define CY_CRYPTO_VU_STATUS_EVEN (1u)
#define CY_CRYPTO_VU_STATUS_CARRY (0u)
cy_en_crypto_status_t Cy_Crypto_Core_Rsa_Proc(cy_stc_crypto_context_rsa_t *cryptoContextPtr);
cy_en_crypto_status_t Cy_Crypto_Core_Rsa_Coef(cy_stc_crypto_context_rsa_t *cryptoContextPtr);
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1)) */
#if (CY_CRYPTO_USER_PKCS1_5 == 1)
cy_en_crypto_status_t Cy_Crypto_Core_RsaVerify(cy_stc_crypto_context_rsa_ver_t *cryptoContextPtr);
#endif /* #if (CY_CRYPTO_USER_PKCS1_5 == 1) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_CORE_RSA_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,442 @@
/***************************************************************************//**
* \file cy_crypto_core_sha.c
* \version 1.0
*
* \brief
* This file provides the source code to the API for the SHA method
* in the Crypto block driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "crypto/cy_crypto_common.h"
#include "crypto/cy_crypto_core_sha.h"
#include "crypto/cy_crypto_core_instructions.h"
#include "crypto/cy_crypto_core_util.h"
#include "crypto/cy_crypto_core_str.h"
#include "syslib/cy_syslib.h"
#include <string.h>
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1))
/* Initialization vectors for different modes of the SHA algorithm */
#if ((CPUSS_CRYPTO_SHA1 == 1) && (CY_CRYPTO_USER_SHA1 == 1))
static const uint32_t Sha1InitHash[] =
{
0x67452301uL, 0xEFCDAB89uL, 0x98BADCFEuL, 0x10325476uL,
0xC3D2E1F0uL
};
#endif /* #if ((CPUSS_CRYPTO_SHA1 == 1) && (CY_CRYPTO_USER_SHA1 == 1)) */
#if ((CPUSS_CRYPTO_SHA256 == 1) && (CY_CRYPTO_USER_SHA256 == 1))
static const uint32_t Sha224InitHash[] =
{
0xC1059ED8uL, 0x367CD507uL, 0x3070DD17uL, 0xF70E5939uL,
0xFFC00B31uL, 0x68581511uL, 0x64F98FA7uL, 0xBEFA4FA4uL
};
static const uint32_t Sha256InitHash[] =
{
0x6A09E667uL, 0xBB67AE85uL, 0x3C6EF372uL, 0xA54FF53AuL,
0x510E527FuL, 0x9B05688CuL, 0x1F83D9ABuL, 0x5BE0CD19uL
};
#endif /* #if ((CPUSS_CRYPTO_SHA256 == 1) && (CY_CRYPTO_USER_SHA256 == 1)) */
#if ((CPUSS_CRYPTO_SHA512 == 1) && (CY_CRYPTO_USER_SHA512 == 1))
static const uint32_t Sha512_224InitHash[] =
{
0x8C3D37C8uL, 0x19544DA2uL, 0x73E19966uL, 0x89DCD4D6uL,
0x1DFAB7AEuL, 0x32FF9C82uL, 0x679DD514uL, 0x582F9FCFuL,
0x0F6D2B69uL, 0x7BD44DA8uL, 0x77E36F73uL, 0x04C48942uL,
0x3F9D85A8uL, 0x6A1D36C8uL, 0x1112E6ADuL, 0x91D692A1uL
};
static const uint32_t Sha512_256InitHash[] =
{
0x22312194uL, 0xFC2BF72CuL, 0x9F555FA3uL, 0xC84C64C2uL,
0x2393B86BuL, 0x6F53B151uL, 0x96387719uL, 0x5940EABDuL,
0x96283EE2uL, 0xA88EFFE3uL, 0xBE5E1E25uL, 0x53863992uL,
0x2B0199FCuL, 0x2C85B8AAuL, 0x0EB72DDCuL, 0x81C52CA2uL
};
static const uint32_t Sha384InitHash[] =
{
0xCBBB9D5DuL, 0xC1059ED8uL, 0x629A292AuL, 0x367CD507uL,
0x9159015AuL, 0x3070DD17uL, 0x152FECD8uL, 0xF70E5939uL,
0x67332667uL, 0xFFC00B31uL, 0x8EB44A87uL, 0x68581511uL,
0xDB0C2E0DuL, 0x64F98FA7uL, 0x47B5481DuL, 0xBEFA4FA4uL
};
static const uint32_t Sha512InitHash[] =
{
0x6A09E667uL, 0xF3BCC908uL, 0xBB67AE85uL, 0x84CAA73BuL,
0x3C6EF372uL, 0xFE94F82BuL, 0xA54FF53AuL, 0x5F1D36F1uL,
0x510E527FuL, 0xADE682D1uL, 0x9B05688CuL, 0x2B3E6C1FuL,
0x1F83D9ABuL, 0xFB41BD6BuL, 0x5BE0CD19uL, 0x137E2179uL
};
#endif /* #if ((CPUSS_CRYPTO_SHA512 == 1) && (CY_CRYPTO_USER_SHA512 == 1)) */
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Sha_ProcessBlock
****************************************************************************//**
*
* Performs the SHA calculation on one block.
* All addresses must be 4-Byte aligned!
*
* This function available for CM0+ core only.
*
* \param hashStatePtr
* The pointer to a Hash State.
*
* \param blockPtr
* The pointer to the block whose Hash is being computed.
*
*******************************************************************************/
void Cy_Crypto_Core_Sha_ProcessBlock(cy_stc_crypto_sha_state_t *hashStatePtr, uint32_t *blockPtr)
{
Cy_Crypto_SetReg4Instr((uint32_t)blockPtr,
(uint32_t)hashStatePtr->hashPtr, /* Initial hash */
(uint32_t)hashStatePtr->roundMemPtr,
(uint32_t)hashStatePtr->hashPtr); /* Digest */
/* Issue the SHA instruction */
Cy_Crypto_Run4ParamInstr(CY_CRYPTO_SHA_OPC,
CY_CRYPTO_RSRC0_SHIFT,
CY_CRYPTO_RSRC4_SHIFT,
CY_CRYPTO_RSRC8_SHIFT,
CY_CRYPTO_RSRC12_SHIFT);
/* Wait until the SHA instruction is complete */
while(0uL != _FLD2VAL(CRYPTO_STATUS_SHA_BUSY, CRYPTO->STATUS))
{
}
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Sha_Init
****************************************************************************//**
*
* The function to initialize SHA operation.
*
* This function available for CM0+ core only.
*
* \param hashStatePtr
* The pointer to a Hash State.
*
* \param mode
* One of these: CY_CRYPTO_SHA256, CY_CRYPTO_SHA1, CY_CRYPTO_SHA256_224, CY_CRYPTO_SHA512,
* CY_CRYPTO_SHA384, CY_CRYPTO_SHA512_224, CY_CRYPTO_SHA512_256
*
*******************************************************************************/
void Cy_Crypto_Core_Sha_Init(cy_stc_crypto_sha_state_t *hashStatePtr,
uint8_t *blockPtr,
uint32_t *hashPtr,
uint32_t *roundMemPtr,
cy_en_crypto_sha_mode_t mode)
{
cy_en_crypto_sha_hw_mode_t shaHwMode;
#if ((CPUSS_CRYPTO_SHA512 == 1) && (CY_CRYPTO_USER_SHA512 == 1))
shaHwMode = CY_CRYPTO_SHA_CTL_MODE_SHA512;
#endif /* #if ((CPUSS_CRYPTO_SHA512 == 1) && (CY_CRYPTO_USER_SHA512 == 1)) */
switch (mode)
{
#if ((CPUSS_CRYPTO_SHA1 == 1) && (CY_CRYPTO_USER_SHA1 == 1))
case CY_CRYPTO_MODE_SHA1:
shaHwMode = CY_CRYPTO_SHA_CTL_MODE_SHA1;
hashStatePtr->initialHashPtr = Sha1InitHash;
hashStatePtr->blockSize = CY_CRYPTO_SHA1_BLOCK_SIZE;
hashStatePtr->hashSize = CY_CRYPTO_SHA1_HASH_SIZE;
hashStatePtr->digestSize = CY_CRYPTO_SHA1_DIGEST_SIZE;
hashStatePtr->roundMemSize = CY_CRYPTO_SHA1_ROUND_MEM_SIZE;
break;
#endif /* #if ((CPUSS_CRYPTO_SHA1 == 1) && (CY_CRYPTO_USER_SHA1 == 1)) */
#if ((CPUSS_CRYPTO_SHA256 == 1) && (CY_CRYPTO_USER_SHA256 == 1))
case CY_CRYPTO_MODE_SHA224:
shaHwMode = CY_CRYPTO_SHA_CTL_MODE_SHA256;
hashStatePtr->initialHashPtr = Sha224InitHash;
hashStatePtr->blockSize = CY_CRYPTO_SHA256_BLOCK_SIZE;
hashStatePtr->hashSize = CY_CRYPTO_SHA256_HASH_SIZE;
hashStatePtr->digestSize = CY_CRYPTO_SHA224_DIGEST_SIZE;
hashStatePtr->roundMemSize = CY_CRYPTO_SHA256_ROUND_MEM_SIZE;
break;
case CY_CRYPTO_MODE_SHA256:
shaHwMode = CY_CRYPTO_SHA_CTL_MODE_SHA256;
hashStatePtr->initialHashPtr = Sha256InitHash;
hashStatePtr->blockSize = CY_CRYPTO_SHA256_BLOCK_SIZE;
hashStatePtr->hashSize = CY_CRYPTO_SHA256_HASH_SIZE;
hashStatePtr->digestSize = CY_CRYPTO_SHA256_DIGEST_SIZE;
hashStatePtr->roundMemSize = CY_CRYPTO_SHA256_ROUND_MEM_SIZE;
break;
#endif /* #if ((CPUSS_CRYPTO_SHA256 == 1) && (CY_CRYPTO_USER_SHA256 == 1)) */
#if ((CPUSS_CRYPTO_SHA512 == 1) && (CY_CRYPTO_USER_SHA512 == 1))
case CY_CRYPTO_MODE_SHA384:
hashStatePtr->initialHashPtr = Sha384InitHash;
hashStatePtr->blockSize = CY_CRYPTO_SHA512_BLOCK_SIZE;
hashStatePtr->hashSize = CY_CRYPTO_SHA512_HASH_SIZE;
hashStatePtr->digestSize = CY_CRYPTO_SHA384_DIGEST_SIZE;
hashStatePtr->roundMemSize = CY_CRYPTO_SHA512_ROUND_MEM_SIZE;
break;
case CY_CRYPTO_MODE_SHA512:
hashStatePtr->initialHashPtr = Sha512InitHash;
hashStatePtr->blockSize = CY_CRYPTO_SHA512_BLOCK_SIZE;
hashStatePtr->hashSize = CY_CRYPTO_SHA512_HASH_SIZE;
hashStatePtr->digestSize = CY_CRYPTO_SHA512_DIGEST_SIZE;
hashStatePtr->roundMemSize = CY_CRYPTO_SHA512_ROUND_MEM_SIZE;
break;
case CY_CRYPTO_MODE_SHA512_224:
hashStatePtr->initialHashPtr = Sha512_224InitHash;
hashStatePtr->blockSize = CY_CRYPTO_SHA512_BLOCK_SIZE;
hashStatePtr->hashSize = CY_CRYPTO_SHA512_HASH_SIZE;
hashStatePtr->digestSize = CY_CRYPTO_SHA512_224_DIGEST_SIZE;
hashStatePtr->roundMemSize = CY_CRYPTO_SHA512_ROUND_MEM_SIZE;
break;
case CY_CRYPTO_MODE_SHA512_256:
hashStatePtr->initialHashPtr = Sha512_256InitHash;
hashStatePtr->blockSize = CY_CRYPTO_SHA512_BLOCK_SIZE;
hashStatePtr->hashSize = CY_CRYPTO_SHA512_HASH_SIZE;
hashStatePtr->digestSize = CY_CRYPTO_SHA512_256_DIGEST_SIZE;
hashStatePtr->roundMemSize = CY_CRYPTO_SHA512_ROUND_MEM_SIZE;
break;
#endif /* #if ((CPUSS_CRYPTO_SHA512 == 1) && (CY_CRYPTO_USER_SHA512 == 1)) */
default:
break;
}
hashStatePtr->mode = mode;
hashStatePtr->blockPtr = blockPtr;
hashStatePtr->hashPtr = hashPtr;
hashStatePtr->roundMemPtr = roundMemPtr;
/* Set the SHA mode */
CRYPTO->SHA_CTL = (uint32_t)(_VAL2FLD(CRYPTO_SHA_CTL_MODE, (uint32_t)shaHwMode));
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Sha_Start
****************************************************************************//**
*
* Initializes the initial hash vector.
*
* This function available for CM0+ core only.
*
* \param hashStatePtr
* The pointer to the SHA context.
*
*******************************************************************************/
void Cy_Crypto_Core_Sha_Start(cy_stc_crypto_sha_state_t *hashStatePtr)
{
memcpy(hashStatePtr->hashPtr, hashStatePtr->initialHashPtr, hashStatePtr->hashSize);
}
/*******************************************************************************
* Function Name: Crypto_Server_SHA_Update
****************************************************************************//**
*
* Performs the SHA calculation on one message.
*
* This function available for CM0+ core only.
*
* \param hashStatePtr
* The pointer to the SHA context.
*
* \param messagePtr
* The pointer to the message whose Hash is being computed.
*
* \param messageSize
* The size of the message whose Hash is being computed.
*
*******************************************************************************/
void Cy_Crypto_Core_Sha_Update(cy_stc_crypto_sha_state_t *hashStatePtr,
uint32_t *messagePtr,
uint32_t messageSize)
{
uint8_t *blockPtrTmp = hashStatePtr->blockPtr;
uint32_t blockSizeTmp = hashStatePtr->blockSize;
uint32_t blockIdx = messageSize & (blockSizeTmp - 1u);
hashStatePtr->messageSize = messageSize;
if (messageSize >= blockSizeTmp)
{
while (messageSize >= blockSizeTmp)
{
Cy_Crypto_Core_Sha_ProcessBlock(hashStatePtr, messagePtr);
/* Use /4 because the pointer is to uint32_t and blockSize is in Bytes */
messagePtr += (blockSizeTmp / 4u);
messageSize -= blockSizeTmp;
}
}
/* Copy the end of the message to the block */
memcpy(blockPtrTmp, messagePtr, blockIdx);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Sha_Finish
****************************************************************************//**
*
* Completes SHA calculation.
*
* This function available for CM0+ core only.
*
* \param hashStatePtr
* The pointer to the SHA context.
*
* \param digestPtr
* The pointer to the calculated hash digest.
*
* \param finalMessageSize
* The final message size, can be different from the messageSize
* if you use command Cy_Crypto_Core_Sha_ProcessBlock() before.
*
*******************************************************************************/
void Cy_Crypto_Core_Sha_Finish(cy_stc_crypto_sha_state_t *hashStatePtr,
uint32_t *digestPtr,
uint32_t finalMessageSize)
{
uint32_t *hashTmpPtr = hashStatePtr->hashPtr;
uint8_t *blockTmpPtr = hashStatePtr->blockPtr;
uint32_t blockSizeTmp = hashStatePtr->blockSize;
uint32_t blockIdx = (uint32_t)(hashStatePtr->messageSize & (blockSizeTmp - 1u));
uint32_t size;
if (CY_CRYPTO_SHA512_BLOCK_SIZE == blockSizeTmp)
{
size = CY_CRYPTO_SHA512_PAD_SIZE; /* Pad size = 112 */
}
else
{
size = CY_CRYPTO_SHA256_PAD_SIZE; /* Pad size = 56 */
}
/* Append 1 bit to the end of the message */
blockTmpPtr[blockIdx] = 0x80u;
/* Clear the rest of the block */
memset((void* )&blockTmpPtr[blockIdx + 1u], 0x00u, (blockSizeTmp - blockIdx - 1u));
if (blockIdx >= size)
{
/* Here we need one additional last block to calculate SHA, prepare it: */
Cy_Crypto_Core_Sha_ProcessBlock(hashStatePtr, (uint32_t*)blockTmpPtr);
/* Clear the last block */
memset(blockTmpPtr, 0x00u, blockSizeTmp);
}
/* Write at the end length of the message, in Bits */
blockTmpPtr[blockSizeTmp - 4u] = (uint8_t)((finalMessageSize * 8uL) >> 24u);
blockTmpPtr[blockSizeTmp - 3u] = (uint8_t)((finalMessageSize * 8uL) >> 16u);
blockTmpPtr[blockSizeTmp - 2u] = (uint8_t)((finalMessageSize * 8uL) >> 8u);
blockTmpPtr[blockSizeTmp - 1u] = (uint8_t)(finalMessageSize * 8uL);
/* Process the last block */
Cy_Crypto_Core_Sha_ProcessBlock(hashStatePtr, (uint32_t*)blockTmpPtr);
/* Invert endians of the hash and copy it to digestPtr, re-use the size variable */
size = (uint32_t)(hashStatePtr->digestSize / 4u);
for(; size != 0u; size--)
{
*digestPtr = CY_SWAP_ENDIAN32(*hashTmpPtr);
digestPtr++;
hashTmpPtr++;
}
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Sha_Free
****************************************************************************//**
*
* Clears the used memory buffers.
*
* This function available for CM0+ core only.
*
* \param hashStatePtr
* The pointer to the SHA context.
*
*******************************************************************************/
void Cy_Crypto_Core_Sha_Free(cy_stc_crypto_sha_state_t *hashStatePtr)
{
/* Clears the memory buffer. */
memset(hashStatePtr->blockPtr, 0x00u, hashStatePtr->blockSize);
memset(hashStatePtr->hashPtr, 0x00u, hashStatePtr->hashSize);
memset(hashStatePtr->roundMemPtr, 0x00u, hashStatePtr->roundMemSize);
}
/*******************************************************************************
* Function Name: Crypto_Core_Sha
****************************************************************************//**
*
* Performs the SHA Hash function.
*
* This function available for CM0+ core only.
*
* \param cryptoShaContext
* the pointer to the stc_crypto_context_t structure which stores all internal variables
* for Crypto driver.
*
* \return
* A Crypto status \ref en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Sha(cy_stc_crypto_context_sha_t *cryptoShaContext)
{
uint32_t *messageTmpPtr = cryptoShaContext->messagePtr;
uint32_t messageSizeTmp = cryptoShaContext->messageSize;
uint32_t *digestPtr = cryptoShaContext->dstPtr;
cy_en_crypto_sha_mode_t modeTmp = cryptoShaContext->mode;
/* Allocate CRYPTO_MAX_BLOCK_SIZE Bytes for blockPtr */
uint8_t *blockPtr = (uint8_t*)CRYPTO->MEM_BUFF;
/* Allocate CRYPTO_MAX_HASH_SIZE Bytes for hashPtr */
uint32_t *hashPtr = (uint32_t*)(blockPtr + CY_CRYPTO_MAX_BLOCK_SIZE);
/* Allocate CRYPTO_MAX_ROUND_MEM_SIZE Bytes for roundMemPtr */
uint32_t *roundMemPtr = (uint32_t*)((uint8_t*)hashPtr + CY_CRYPTO_MAX_HASH_SIZE);
/* Allocate space for the structure which stores the SHA context */
cy_stc_crypto_sha_state_t *hashStatePtr =
(cy_stc_crypto_sha_state_t*)((uint8_t*)roundMemPtr + CY_CRYPTO_MAX_ROUND_MEM_SIZE);
/* Initialize the hashStatePtr structure with zeros */
memset(hashStatePtr, 0x00u, sizeof(cy_stc_crypto_sha_state_t));
Cy_Crypto_Core_Sha_Init (hashStatePtr, blockPtr, hashPtr, roundMemPtr, modeTmp);
Cy_Crypto_Core_Sha_Start (hashStatePtr);
Cy_Crypto_Core_Sha_Update (hashStatePtr, messageTmpPtr, messageSizeTmp);
Cy_Crypto_Core_Sha_Finish (hashStatePtr, digestPtr, messageSizeTmp);
Cy_Crypto_Core_Sha_Free (hashStatePtr);
return (CY_CRYPTO_SUCCESS);
}
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
/* [] END OF FILE */

View File

@ -0,0 +1,115 @@
/***************************************************************************//**
* \file cy_crypto_core_sha.h
* \version 1.0
*
* \brief
* This file provides constants and function prototypes
* for the API for the SHA method in the Crypto block driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_SHA_H)
#define CY_CRYPTO_CORE_SHA_H
#include "crypto/cy_crypto_common.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1))
/** \cond INTERNAL */
/* Defines for the SHA algorithm */
#define CY_CRYPTO_SHA1_BLOCK_SIZE (64u)
#define CY_CRYPTO_SHA256_BLOCK_SIZE (64u)
#define CY_CRYPTO_SHA512_BLOCK_SIZE (128u)
#define CY_CRYPTO_MAX_BLOCK_SIZE (128u)
#define CY_CRYPTO_SHA256_PAD_SIZE (56uL)
#define CY_CRYPTO_SHA512_PAD_SIZE (112uL)
#define CY_CRYPTO_SHA1_HASH_SIZE (20u)
#define CY_CRYPTO_SHA256_HASH_SIZE (64u)
#define CY_CRYPTO_SHA512_HASH_SIZE (128u)
#define CY_CRYPTO_MAX_HASH_SIZE (128u)
#define CY_CRYPTO_SHA1_ROUND_MEM_SIZE (320uL)
#define CY_CRYPTO_SHA256_ROUND_MEM_SIZE (256uL)
#define CY_CRYPTO_SHA512_ROUND_MEM_SIZE (640uL)
#define CY_CRYPTO_MAX_ROUND_MEM_SIZE (640uL)
/* The structure for storing the SHA context */
typedef struct
{
cy_en_crypto_sha_mode_t mode;
uint8_t *blockPtr;
uint32_t blockSize;
uint32_t *hashPtr;
uint32_t hashSize;
uint32_t *roundMemPtr;
uint32_t roundMemSize;
uint32_t messageSize;
uint32_t digestSize;
const uint32_t *initialHashPtr;
} cy_stc_crypto_sha_state_t;
typedef enum
{
#if ((CPUSS_CRYPTO_SHA1 == 1) && (CY_CRYPTO_USER_SHA1 == 1))
CY_CRYPTO_SHA_CTL_MODE_SHA1 = 0u,
#endif /* #if ((CPUSS_CRYPTO_SHA1 == 1) && (CY_CRYPTO_USER_SHA1 == 1)) */
#if ((CPUSS_CRYPTO_SHA256 == 1) && (CY_CRYPTO_USER_SHA256 == 1))
CY_CRYPTO_SHA_CTL_MODE_SHA256 = 1u,
#endif /* #if ((CPUSS_CRYPTO_SHA256 == 1) && (CY_CRYPTO_USER_SHA256 == 1)) */
#if ((CPUSS_CRYPTO_SHA512 == 1) && (CY_CRYPTO_USER_SHA512 == 1))
CY_CRYPTO_SHA_CTL_MODE_SHA512 = 2u,
#endif /* #if ((CPUSS_CRYPTO_SHA512 == 1) && (CY_CRYPTO_USER_SHA512 == 1)) */
} cy_en_crypto_sha_hw_mode_t;
void Cy_Crypto_Core_Sha_Init(cy_stc_crypto_sha_state_t *hashStatePtr,
uint8_t *blockPtr,
uint32_t *hashPtr,
uint32_t *roundMemPtr,
cy_en_crypto_sha_mode_t mode);
void Cy_Crypto_Core_Sha_ProcessBlock(cy_stc_crypto_sha_state_t *hashStatePtr,
uint32_t *blockPtr);
void Cy_Crypto_Core_Sha_Start(cy_stc_crypto_sha_state_t *hashStatePtr);
void Cy_Crypto_Core_Sha_Update(cy_stc_crypto_sha_state_t *hashStatePtr,
uint32_t *messagePtr,
uint32_t messageSize);
void Cy_Crypto_Core_Sha_Finish(cy_stc_crypto_sha_state_t *hashStatePtr,
uint32_t *digestPtr,
uint32_t finalMessageSize);
void Cy_Crypto_Core_Sha_Free(cy_stc_crypto_sha_state_t *hashStatePtr);
cy_en_crypto_status_t Cy_Crypto_Core_Sha(cy_stc_crypto_context_sha_t *cryptoShaContext);
/** \endcond */
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_CORE_SHA_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,194 @@
/***************************************************************************//**
* \file cy_crypto_core_str.c
* \version 1.0
*
* \brief
* This file provides the source code for the string management API
* in the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_crypto_common.h"
#include "cy_crypto_core_str.h"
#include "cy_crypto_core_instructions.h"
#include "cy_crypto_core_util.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_STR == 1) && (CY_CRYPTO_USER_STR == 1))
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Str_MemCpy
****************************************************************************//**
*
* Function MemCpy uses Crypto HW.
* Memory structures should not overlap!
* There is no alignment restriction.
*
* This function available for CM0+ core only.
*
* \param src
* The pointer to the source of MemCpy.
*
* \param dst
* The pointer to the destination of MemCpy.
*
* \param size
* The size in bytes of the copy operation.
*
*******************************************************************************/
void Cy_Crypto_Core_Str_MemCpy(void* dstPtr, void const *srcPtr, uint16_t size)
{
/* Prepare data in the register file for next instruction */
Cy_Crypto_SetReg3Instr((uint32_t)srcPtr,
(uint32_t)dstPtr,
(uint32_t)size);
/* Issue the STR_MEMCPY instruction */
Cy_Crypto_Run3ParamInstr(CY_CRYPTO_STR_MEMCPY_OPC,
CY_CRYPTO_RSRC0_SHIFT,
CY_CRYPTO_RSRC4_SHIFT,
CY_CRYPTO_RSRC8_SHIFT);
/* Wait until the STR instruction is complete */
while(0uL != _FLD2VAL(CRYPTO_STATUS_STR_BUSY, CRYPTO->STATUS))
{
}
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Str_MemSet
****************************************************************************//**
*
* Function MemSet uses Crypto HW.
* There is no alignment restriction.
*
* This function available for CM0+ core only.
*
* \param dst
* The pointer to the destination of MemSet.
* \param data
* The value to be set.
* \param size
* The size in bytes of the set operation.
*
*******************************************************************************/
void Cy_Crypto_Core_Str_MemSet(void* dstPtr, uint8_t data, uint16_t size)
{
Cy_Crypto_SetReg3Instr((uint32_t)dstPtr,
(uint32_t)size,
(uint32_t)data);
/* Issue the STR_MEMSET instruction */
Cy_Crypto_Run3ParamInstr(CY_CRYPTO_STR_MEMSET_OPC,
CY_CRYPTO_RSRC0_SHIFT,
CY_CRYPTO_RSRC8_SHIFT,
CY_CRYPTO_RSRC12_SHIFT);
/* Wait until the STR instruction is complete */
while(0uL != _FLD2VAL(CRYPTO_STATUS_STR_BUSY, CRYPTO->STATUS))
{
}
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Str_MemCmp
****************************************************************************//**
*
* Function MemCmp uses Crypto HW.
* There is no alignment restriction.
*
* This function available for CM0+ core only.
*
* \param src0
* The pointer to the first source of MemCmp.
* \param src1
* The pointer to the second source of MemCmp.
* \param size
* the size in bytes of the compare operation.
*
* \return
* 0 - if Source 1 = Source 2, 1 - if not.
*
*******************************************************************************/
uint32_t Cy_Crypto_Core_Str_MemCmp(void const *src0Ptr, void const *src1Ptr, uint16_t size)
{
Cy_Crypto_SetReg3Instr((uint32_t)src0Ptr,
(uint32_t)src1Ptr,
(uint32_t)size);
/* Issue the STR_MEMCMP instruction */
Cy_Crypto_Run3ParamInstr(CY_CRYPTO_STR_MEMCMP_OPC,
CY_CRYPTO_RSRC0_SHIFT,
CY_CRYPTO_RSRC4_SHIFT,
CY_CRYPTO_RSRC8_SHIFT);
/* Wait until the STR instruction is complete */
while(0uL != _FLD2VAL(CRYPTO_STATUS_STR_BUSY, CRYPTO->STATUS))
{
}
return((uint32_t)(CRYPTO->STR_RESULT));
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Str_MemXor
****************************************************************************//**
*
* Function MemXor uses Crypto HW.
* Memory structures should not overlap!
* There is no alignment restriction.
*
* This function available for CM0+ core only.
*
* \param src0
* The pointer to the first source of MemXor.
* \param src1
* The pointer to the second source of MemXor.
* \param dest
* The pointer to the destination of MemXor.
*
* \param size
* The size in bytes of the compare operation.
*
*******************************************************************************/
void Cy_Crypto_Core_Str_MemXor(void const *src0Ptr, void const *src1Ptr, void* dstPtr, uint16_t size)
{
Cy_Crypto_SetReg4Instr((uint32_t)src0Ptr,
(uint32_t)src1Ptr,
(uint32_t)size,
(uint32_t)dstPtr);
/* Issue the STR_MEMXOR instruction */
Cy_Crypto_Run4ParamInstr(CY_CRYPTO_STR_MEMXOR_OPC,
CY_CRYPTO_RSRC0_SHIFT,
CY_CRYPTO_RSRC4_SHIFT,
CY_CRYPTO_RSRC8_SHIFT,
CY_CRYPTO_RSRC12_SHIFT);
/* Wait until the STR instruction is complete */
while(0uL != _FLD2VAL(CRYPTO_STATUS_STR_BUSY, CRYPTO->STATUS))
{
}
}
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_STR == 1) && (CY_CRYPTO_USER_STR == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
/* [] END OF FILE */

View File

@ -0,0 +1,43 @@
/***************************************************************************//**
* \file cy_crypto_core_str.h
* \version 1.0
*
* \brief
* This file provides the headers for the string management API
* in the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_STR_H)
#define CY_CRYPTO_CORE_STR_H
#include "cy_crypto_common.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_STR == 1) & (CY_CRYPTO_USER_STR == 1))
void Cy_Crypto_Core_Str_MemCpy(void* dstPtr, void const *srcPtr, uint16_t size);
void Cy_Crypto_Core_Str_MemSet(void* dstPtr, uint8_t data, uint16_t size);
uint32_t Cy_Crypto_Core_Str_MemCmp(void const *src0Ptr, void const *src1Ptr, uint16_t size);
void Cy_Crypto_Core_Str_MemXor(void const *src0Ptr, void const *src1Ptr, void* dstPtr, uint16_t size);
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_STR == 1) & (CY_CRYPTO_USER_STR == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_CORE_STR_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,93 @@
/***************************************************************************//**
* \file cy_crypto_core_trng.c
* \version 1.0
*
* \brief
* This file provides the source code to the API for the TRNG
* in the Crypto block driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "crypto/cy_crypto_common.h"
#include "crypto/cy_crypto_core_trng.h"
#include "crypto/cy_crypto_core_instructions.h"
#include "crypto/cy_crypto_core_util.h"
#include "crypto/cy_crypto_core_trng_config.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_TR == 1) && (CY_CRYPTO_USER_TR == 1))
/*******************************************************************************
* Function Name: Crypto_Server_Trng_Init
****************************************************************************//**
*
* Initializes the TRND parameters.
*
* This function available for CM0+ core only.
*
*******************************************************************************/
void Cy_Crypto_Server_Trng_Init(void)
{
CRYPTO->TR_CTL0 = CY_CRYPTO_TR_CTL0_VAL;
CRYPTO->TR_CTL1 = CY_CRYPTO_TR_CTL1_VAL;
CRYPTO->TR_MON_CTL = CY_CRYPTO_TR_BTSTR_SEL;
CRYPTO->TR_MON_CMD = CY_CRYPTO_TR_START_MON;
CRYPTO->TR_MON_RC_CTL = CY_CRYPTO_TR_RC_CUTOFF;
CRYPTO->TR_MON_AP_CTL = CY_CRYPTO_TR_AC_CUTOFF;
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Trng
****************************************************************************//**
*
* Generates a True Random Number and returns it in the
* cryptoTrngContext->trngNumPtr.
*
* This function available for CM0+ core only.
*
* \param cryptoTrngContext
* The pointer to the stc_crypto_context_t structure which stores
* the Crypto driver context.
*
* \return
* A Crypto status \ref en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Trng(cy_stc_crypto_context_trng_t *cryptoTrngContext)
{
Cy_Crypto_Server_Trng_Init();
CRYPTO->TR_GARO_CTL = (uint32_t)cryptoTrngContext->GAROPol;
CRYPTO->TR_FIRO_CTL = (uint32_t)cryptoTrngContext->FIROPol;
CRYPTO->INSTR_FF_WR = (uint32_t)(CY_CRYPTO_SET_REG1_OPC << CY_CRYPTO_OPCODE_POS);
CRYPTO->INSTR_FF_WR = (uint32_t)cryptoTrngContext->max;
CRYPTO->INSTR_FF_WR = (uint32_t)((uint32_t)CY_CRYPTO_TRNG_OPC << CY_CRYPTO_OPCODE_POS);
/* Wait until the TRNG instruction is complete */
while(0uL != _FLD2VAL(CRYPTO_STATUS_TR_BUSY, CRYPTO->STATUS))
{
}
*cryptoTrngContext->trngNumPtr = (uint32_t)_FLD2VAL(CRYPTO_TR_RESULT_DATA32, CRYPTO->TR_RESULT);
return (CY_CRYPTO_SUCCESS);
}
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_TR == 1) && (CY_CRYPTO_USER_TR == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
/* [] END OF FILE */

View File

@ -0,0 +1,37 @@
/***************************************************************************//**
* \file cy_crypto_core_trng.h
* \version 1.0
*
* \brief
* This file provides provides constant and parameters
* for the API of the TRNG in the Crypto block driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_TRNG_H)
#define CY_CRYPTO_CORE_TRNG_H
#include "crypto/cy_crypto_common.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_TR == 1) && (CY_CRYPTO_USER_TR == 1))
cy_en_crypto_status_t Cy_Crypto_Core_Trng(cy_stc_crypto_context_trng_t *cryptoTrngContext);
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_TR == 1) && (CY_CRYPTO_USER_TR == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_CORE_TRNG_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,239 @@
/***************************************************************************//**
* \file cy_crypto_core_trng_config.h
* \version 1.0
*
* \brief
* This file provides internal (not public) constant and parameters
* for the Crypto TRNG driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_TRNG_CONFIG_H)
#define CY_CRYPTO_CORE_TRNG_CONFIG_H
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_TR == 1))
/** TRNG Configuration default values */
/**
* Specifies the clock divider that is used to sample oscillator data.
* This clock divider is wrt. "clk_sys".
* "0": sample clock is "clk_sys".
* "1": sample clock is "clk_sys"/2.
* ...
* "255": sample clock is "clk_sys"/256.
*/
#define CY_CRYPTO_TR_SAMPLE_CLOCK_DIV (0UL)
/**
* Specifies the clock divider used to produce reduced bits.
* "0": 1 reduced bit is produced for each sample.
* "1": 1 reduced bit is produced for each 2 samples.
* ...
* "255": 1 reduced bit is produced for each 256 samples.
*
* The reduced bits are considered random bits and shifted into TR_RESULT0.DATA32.
*/
#define CY_CRYPTO_TR_RED_CLOCK_DIV (0UL)
/**
* Specifies an initialization delay: a number of removed/dropped samples before
* reduced bits are generated. This field should be programmed in the range [1, 255].
* After starting the oscillators, at least the first 2 samples should be
* removed/dropped to clear the state of internal synchronizers. In addition,
* it is advised to drop at least the second 2 samples from the oscillators
* (to circumvent the semi-predictable oscillator start-up behavior). This results
* in the default field value of "3". the field encoding is as follows:
* "0": 1 sample is dropped.
* "1": 2 samples are dropped.
* ...
* "255": 256 samples are dropped.
*
* The TR_INITIALIZED interrupt cause is set to '1', when the initialization delay is passed.
*/
#define CY_CRYPTO_TR_INIT_DELAY (3UL)
/**
* Specifies if the "von Neumann corrector" is disabled or enabled:
* '0': disabled.
* '1': enabled.
* The "von Neumann corrector" post-processes the reduced bits to remove a '0' or '1' bias.
* The corrector operates on reduced bit pairs ("oldest bit, newest bit"):
* "00": no bit is produced.
* "01": '0' bit is produced (oldest bit).
* "10": '1' bit is produced (oldest bit).
* "11": no bit is produced.
* NOTE: The corrector produces bits at a random pace and at a frequency that
* is 1/4 of the reduced bit frequency (reduced bits are processed in pairs,
* and half of the pairs do NOT produce a bit).
*/
#define CY_CRYPTO_TR_VON_NEUMANN_CORR (1UL)
/**
* Specifies if the TRNG functionality is stopped on an adaptive proportion test
* detection (when HW sets INTR.TR_AP_DETECT to '1'):
* '0': Functionality is stopped (TR_CTL1 fields are set to '0' by HW).
* '1': Functionality is NOT stopped.
*/
#define CY_CRYPTO_TR_STOP_ON_AP_DETECT (1UL)
/**
* Specifies if the TRNG functionality is stopped on a repetition count test detection
* (when HW sets INTR.TR_RC_DETECT to '1'):
* '0': Functionality is stopped (TR_CTL1 fields are set to '0' by HW).
* '1': Functionality is NOT stopped.
*/
#define CY_CRYPTO_TR_STOP_ON_RC_DETECT (1UL)
/** FW sets this field to '1' to enable the ring oscillator with 11 inverters. */
#define CY_CRYPTO_TR_RO11_EN (1UL)
/** FW sets this field to '1' to enable the ring oscillator with 15 inverters. */
#define CY_CRYPTO_TR_RO15_EN (1UL)
/**
* FW sets this field to '1' to enable the fixed Galois ring oscillator
* with 15 inverters.
*/
#define CY_CRYPTO_TR_GARO15_EN (1UL)
/**
* FW sets this field to '1' to enable the programmable Galois ring oscillator with up
* to 31 inverters. The TR_GARO_CTL register specifies the programmable polynomial.
*/
#define CY_CRYPTO_TR_GARO31_EN (1UL)
/** FW sets this field to '1' to enable the fixed Fibonacci ring oscillator with 15 inverters. */
#define CY_CRYPTO_TR_FIRO15_EN (1UL)
/**
* FW sets this field to '1' to enable the programmable Fibonacci ring oscillator
* with up to 31 inverters. The TR_FIRO_CTL register specifies the programmable polynomial.
*/
#define CY_CRYPTO_TR_FIRO31_EN (1UL)
/**
* The polynomial for programmable Galois ring oscillator. The polynomial is represented
* WITHOUT the high order bit (this bit is always assumed '1'). The polynomial should be aligned
* so that the more significant bits (bit 30 and down) contain the polynomial and the less
* significant bits (bit 0 and up) contain padding '0's.
*/
#define CY_CRYPTO_TR_GARO (1UL)
/**
* The polynomial for the programmable Fibonacci ring oscillator. The polynomial is represented
* WITHOUT the high order bit (this bit is always assumed '1'). The polynomial should
* be aligned so that the more significant bits (bit 30 and down) contain the polynomial
* and the less significant bits (bit 0 and up) contain padding '0's.
*/
#define CY_CRYPTO_TR_FIRO (1UL)
/**
* Selection of the bit stream:
* "0": DAS bit stream.
* "1": RED bit stream.
* "2": TR bit stream.
* "3": Undefined.
*/
#define CY_CRYPTO_TR_BITSTREAM_SEL (0UL)
/**
* Adaptive proportion (AP) test enable:
* '0': Stopped.
* '1': Started.
*
* On AP detection, HW sets this field to '0' and sets INTR.TR_AP_DETECT to '1.
*/
#define CY_CRYPTO_TR_START_AP (0UL)
/**
* Repetition count (RC) test enable:
* '0': Disabled.
* '1': Enabled.
*
* On RC detection, HW sets this field to '0' and sets INTR.TR_RC_DETECT to '1.
*/
#define CY_CRYPTO_TR_START_RC (0UL)
/**
* Cut-off count (legal range is [1, 255]):
* "0": Illegal.
* "1": 1 repetition.
* ...
* "255": 255 repetitions.
*/
#define CY_CRYPTO_TR_CUTOFF_COUNT8 (1UL)
/**
Cut-off count (legal range is [1, 65535]).
"0": Illegal.
"1": 1 occurrence.
...
"65535": 65535 occurrences.
*/
#define CY_CRYPTO_TR_CUTOFF_COUNT16 (1UL)
/**
* The window size (minus 1) :
* "0": 1 bit.
* ...
* "65535": 65536 bits.
*/
#define CY_CRYPTO_TR_WINDOW_SIZE (1uL)
/** the composed value for the TR_CTL0 register */
#define CY_CRYPTO_TR_CTL0_VAL (_VAL2FLD(CRYPTO_TR_CTL0_SAMPLE_CLOCK_DIV, CY_CRYPTO_TR_SAMPLE_CLOCK_DIV) | \
_VAL2FLD(CRYPTO_TR_CTL0_RED_CLOCK_DIV, CY_CRYPTO_TR_RED_CLOCK_DIV) | \
_VAL2FLD(CRYPTO_TR_CTL0_INIT_DELAY, CY_CRYPTO_TR_INIT_DELAY) | \
_VAL2FLD(CRYPTO_TR_CTL0_VON_NEUMANN_CORR, CY_CRYPTO_TR_VON_NEUMANN_CORR) | \
_VAL2FLD(CRYPTO_TR_CTL0_STOP_ON_AP_DETECT, CY_CRYPTO_TR_STOP_ON_AP_DETECT) | \
_VAL2FLD(CRYPTO_TR_CTL0_STOP_ON_RC_DETECT, CY_CRYPTO_TR_STOP_ON_RC_DETECT))
/** The composed value for the TR_CTL1 register */
#define CY_CRYPTO_TR_CTL1_VAL (_VAL2FLD(CRYPTO_TR_CTL1_RO11_EN, CY_CRYPTO_TR_RO11_EN) | \
_VAL2FLD(CRYPTO_TR_CTL1_RO15_EN, CY_CRYPTO_TR_RO15_EN) | \
_VAL2FLD(CRYPTO_TR_CTL1_GARO15_EN, CY_CRYPTO_TR_GARO15_EN) | \
_VAL2FLD(CRYPTO_TR_CTL1_GARO31_EN, CY_CRYPTO_TR_GARO31_EN) | \
_VAL2FLD(CRYPTO_TR_CTL1_FIRO15_EN, CY_CRYPTO_TR_FIRO15_EN) | \
_VAL2FLD(CRYPTO_TR_CTL1_FIRO31_EN, CY_CRYPTO_TR_FIRO31_EN))
/** The composed value for the TR_MON_CTL register */
#define CY_CRYPTO_TR_BTSTR_SEL (_VAL2FLD(CRYPTO_TR_MON_CTL_BITSTREAM_SEL, CY_CRYPTO_TR_BITSTREAM_SEL))
/** The composed value for the TR_MON_CMD register */
#define CY_CRYPTO_TR_START_MON (_VAL2FLD(CRYPTO_TR_MON_CMD_START_AP, CY_CRYPTO_TR_START_AP) | \
_VAL2FLD(CRYPTO_TR_MON_CMD_START_RC, CY_CRYPTO_TR_START_RC))
/** The composed value for the TR_MON_RC_CTL register */
#define CY_CRYPTO_TR_RC_CUTOFF (_VAL2FLD(CRYPTO_TR_MON_RC_CTL_CUTOFF_COUNT8, CY_CRYPTO_TR_CUTOFF_COUNT8))
/** The composed value for the TR_MON_AP_CTL register */
#define CY_CRYPTO_TR_AC_CUTOFF (_VAL2FLD(CRYPTO_TR_MON_AP_CTL_CUTOFF_COUNT16, CY_CRYPTO_TR_CUTOFF_COUNT16) | \
_VAL2FLD(CRYPTO_TR_MON_AP_CTL_WINDOW_SIZE, CY_CRYPTO_TR_WINDOW_SIZE))
/** Default TRNG configuration */
#define CY_CRYPTO_TR_DEFAULT_CONFIG \
{ \
CY_CRYPTO_TR_CTL0_VAL, \
CY_CRYPTO_TR_CTL1_VAL, \
CY_CRYPTO_TR_GARO, \
CY_CRYPTO_TR_FIRO, \
CY_CRYPTO_TR_BITSTREAM_SEL,\
CY_CRYPTO_TR_START_MON, \
CY_CRYPTO_TR_RC_CUTOFF, \
CY_CRYPTO_TR_AC_CUTOFF \
}
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_TR == 1)) */
#endif /* #if !defined(CY_CRYPTO_CORE_TRNG_CONFIG_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,485 @@
/***************************************************************************//**
* \file cy_crypto_core_util.c
* \version 1.0
*
* \brief
* This file provides the source code to the API for the utils
* in the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "crypto/cy_crypto_common.h"
#include "crypto/cy_crypto_core_util.h"
#include "crypto/cy_crypto_core_instructions.h"
#include "crypto/cy_crypto_core_vu_hw.h"
#include "syslib/cy_syslib.h"
#include <stdbool.h>
#if (CY_CPU_CORTEX_M0P)
#if (CPUSS_CRYPTO_PRESENT == 1)
/* The flag to state that an HW error occurred */
bool cy_crypto_IsHwErrorOccured = false;
void Cy_Crypto_Core_ErrorHandler(void);
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Enable
****************************************************************************//**
*
* The function to enable the Crypto hardware.
*
* This function available for CM0+ core only.
*
* \return
* Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Enable(void)
{
/* Enable Crypto HW */
CRYPTO->CTL = (uint32_t)(_VAL2FLD(CRYPTO_CTL_ISOLATE, 1uL) |
_VAL2FLD(CRYPTO_CTL_RETAIN, 0uL) |
_VAL2FLD(CRYPTO_CTL_POWER, 1uL) |
_VAL2FLD(CRYPTO_CTL_ENABLED, 1uL));
CRYPTO->CTL = (uint32_t)(_VAL2FLD(CRYPTO_CTL_ISOLATE, 0uL) |
_VAL2FLD(CRYPTO_CTL_RETAIN, 0uL) |
_VAL2FLD(CRYPTO_CTL_POWER, 1uL) |
_VAL2FLD(CRYPTO_CTL_ENABLED, 1uL));
#if (CPUSS_CRYPTO_VU == 1)
CRYPTO->VU_CTL1 = (uint32_t)CRYPTO->MEM_BUFF;
/* Set the stack pointer to the Crypto buff size, in words */
CY_CRYPTO_VU_SET_REG(15, CPUSS_CRYPTO_BUFF_SIZE, 1);
/* Clear whole register file */
CY_CRYPTO_VU_SET_REG(14, 0, 1);
CY_CRYPTO_VU_SET_REG(13, 0, 1);
CY_CRYPTO_VU_SET_REG(12, 0, 1);
CY_CRYPTO_VU_SET_REG(11, 0, 1);
CY_CRYPTO_VU_SET_REG(10, 0, 1);
CY_CRYPTO_VU_SET_REG(9, 0, 1);
CY_CRYPTO_VU_SET_REG(8, 0, 1);
CY_CRYPTO_VU_SET_REG(7, 0, 1);
CY_CRYPTO_VU_SET_REG(6, 0, 1);
CY_CRYPTO_VU_SET_REG(5, 0, 1);
CY_CRYPTO_VU_SET_REG(4, 0, 1);
CY_CRYPTO_VU_SET_REG(3, 0, 1);
CY_CRYPTO_VU_SET_REG(2, 0, 1);
CY_CRYPTO_VU_SET_REG(1, 0, 1);
CY_CRYPTO_VU_SET_REG(0, 0, 1);
#endif /* #if (CPUSS_CRYPTO_VU == 1) */
return (CY_CRYPTO_SUCCESS);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Disable
****************************************************************************//**
*
* Disables the operation of the CRYPTO block.
*
* This function available for CM0+ core only.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_Disable(void)
{
CRYPTO->CTL = (uint32_t)(_VAL2FLD(CRYPTO_CTL_ISOLATE, 0uL) |
_VAL2FLD(CRYPTO_CTL_RETAIN, 0uL) |
_VAL2FLD(CRYPTO_CTL_POWER, 0uL) |
_VAL2FLD(CRYPTO_CTL_ENABLED, 0uL));
return (CY_CRYPTO_SUCCESS);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_CheckHwForErrors
****************************************************************************//**
*
* The function checks if a Crypto HW error occurred. If yes, copy the error
* information from the Crypto registers to the communication structure.
*
* This function available for CM0+ core only.
*
* \param cryptoContext
* The pointer to vcy_stc_crypto_context_t structure which stores
* the Crypto driver context.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Core_CheckHwForErrors(cy_stc_crypto_context_t *cryptoContext)
{
cy_en_crypto_status_t result = CY_CRYPTO_SUCCESS;
if (cy_crypto_IsHwErrorOccured)
{
result = CY_CRYPTO_HW_ERROR;
}
cryptoContext->hwErrorStatus.errorStatus0 = _FLD2VAL(CRYPTO_ERROR_STATUS0_DATA32, CRYPTO->ERROR_STATUS0);
cryptoContext->hwErrorStatus.errorStatus1 = (_FLD2VAL(CRYPTO_ERROR_STATUS1_DATA23, CRYPTO->ERROR_STATUS1) |
_FLD2VAL(CRYPTO_ERROR_STATUS1_IDX, CRYPTO->ERROR_STATUS1) |
_FLD2VAL(CRYPTO_ERROR_STATUS1_VALID, CRYPTO->ERROR_STATUS1));
return (result);
}
/*******************************************************************************
* Function Name: Cy_Crypto_SetReg1Instr
****************************************************************************//**
*
* Writes one 32-Bit data word into Crypto FIFO.
*
* This function available for CM0+ core only.
*
* \param data0
* The address of data to be placed into Crypto FIFO
* on the address CRYPTO_REGFILE_R0.
*
*******************************************************************************/
void Cy_Crypto_SetReg1Instr(uint32_t data0)
{
/* Check whether FIFO has enough space for 1 instruction */
while(Cy_Crypto_Core_GetFIFOUsed() >= (CY_CRYPTO_FIFODEPTH - 1u))
{
}
CRYPTO->INSTR_FF_WR = (uint32_t)(((uint32_t)CY_CRYPTO_SET_REG1_OPC << CY_CRYPTO_OPCODE_POS) |
(uint32_t)CY_CRYPTO_REGFILE_R0);
CRYPTO->INSTR_FF_WR = data0;
}
/*******************************************************************************
* Function Name: Cy_Crypto_SetReg2Instr
****************************************************************************//**
*
* Writes two 32-Bit data words into Crypto FIFO.
*
* This function available for CM0+ core only.
*
* \param data0
* The address of data to be placed into Crypto FIFO
* on the address CRYPTO_REGFILE_R0.
*
* \param data1
* The address of data to be placed into Crypto FIFO
* on the address CRYPTO_REGFILE_R1.
*
*******************************************************************************/
void Cy_Crypto_SetReg2Instr(uint32_t data0, uint32_t data1)
{
/* Check whether FIFO has enough space for 2 instructions */
while(Cy_Crypto_Core_GetFIFOUsed() >= (CY_CRYPTO_FIFODEPTH - 2u))
{
}
CRYPTO->INSTR_FF_WR = (uint32_t)(((uint32_t)CY_CRYPTO_SET_REG2_OPC << CY_CRYPTO_OPCODE_POS) |
((uint32_t)CY_CRYPTO_REGFILE_R1 << CY_CRYPTO_RSRC4_SHIFT) |
(uint32_t)CY_CRYPTO_REGFILE_R0);
CRYPTO->INSTR_FF_WR = data0;
CRYPTO->INSTR_FF_WR = data1;
}
/*******************************************************************************
* Function Name: Cy_Crypto_SetReg3Instr
****************************************************************************//**
*
* Writes three 32-Bit data words into Crypto FIFO.
*
* This function available for CM0+ core only.
*
* \param data0
* The address of data to be placed into Crypto FIFO
* on the address CRYPTO_REGFILE_R0.
*
* \param data1
* The address of data to be placed into Crypto FIFO
* on the address CRYPTO_REGFILE_R1.
*
* \param data2
* The address of data to be be placed into Crypto FIFO
* on the address CRYPTO_REGFILE_R2.
*
*******************************************************************************/
void Cy_Crypto_SetReg3Instr(uint32_t data0, uint32_t data1, uint32_t data2)
{
/* Check whether FIFO has enough space for 3 instructions */
while(Cy_Crypto_Core_GetFIFOUsed() >= (CY_CRYPTO_FIFODEPTH - 3u))
{
}
CRYPTO->INSTR_FF_WR = (uint32_t)( ((uint32_t)CY_CRYPTO_SET_REG3_OPC << CY_CRYPTO_OPCODE_POS) |
((uint32_t)CY_CRYPTO_REGFILE_R2 << CY_CRYPTO_RSRC8_SHIFT) |
((uint32_t)CY_CRYPTO_REGFILE_R1 << CY_CRYPTO_RSRC4_SHIFT) |
(uint32_t)CY_CRYPTO_REGFILE_R0 );
CRYPTO->INSTR_FF_WR = data0;
CRYPTO->INSTR_FF_WR = data1;
CRYPTO->INSTR_FF_WR = data2;
}
/*******************************************************************************
* Function Name: Cy_Crypto_SetReg4Instr
****************************************************************************//**
*
* Writes four 32-Bit data words into Crypto FIFO.
*
* This function available for CM0+ core only.
*
* \param data0
* The address of data to be placed into Crypto FIFO
* on the address CRYPTO_REGFILE_R0.
*
* \param data1
* The address of data to be placed into Crypto FIFO
* on the address CRYPTO_REGFILE_R1.
*
* \param data2
* The address of data to be placed into Crypto FIFO
* on the address CRYPTO_REGFILE_R2.
*
* \param data3
* The address of data to be placed into Crypto FIFO
* on the address CRYPTO_REGFILE_R3.
*
*******************************************************************************/
void Cy_Crypto_SetReg4Instr(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3)
{
/* Check whether FIFO has enough space for 4 instructions */
while(Cy_Crypto_Core_GetFIFOUsed() >= (CY_CRYPTO_FIFODEPTH - 4u))
{
}
CRYPTO->INSTR_FF_WR = (uint32_t)(((uint32_t)CY_CRYPTO_SET_REG4_OPC << CY_CRYPTO_OPCODE_POS) |
((uint32_t)CY_CRYPTO_REGFILE_R3 << CY_CRYPTO_RSRC12_SHIFT) |
((uint32_t)CY_CRYPTO_REGFILE_R2 << CY_CRYPTO_RSRC8_SHIFT) |
((uint32_t)CY_CRYPTO_REGFILE_R1 << CY_CRYPTO_RSRC4_SHIFT) |
(uint32_t)CY_CRYPTO_REGFILE_R0);
CRYPTO->INSTR_FF_WR = data0;
CRYPTO->INSTR_FF_WR = data1;
CRYPTO->INSTR_FF_WR = data2;
CRYPTO->INSTR_FF_WR = data3;
}
/*******************************************************************************
* Function Name: Cy_Crypto_Run0ParamInstr
*****************************************************************************//**
*
* Run the Crypto instruction without parameters.
*
* This function available for CM0+ core only.
*
* \param instr
* The Opcode of the called instruction.
*
*******************************************************************************/
void Cy_Crypto_Run0ParamInstr(uint8_t instr)
{
/* Check whether FIFO has enough space for 1 instruction */
while(Cy_Crypto_Core_GetFIFOUsed() >= CY_CRYPTO_FIFODEPTH)
{
}
CRYPTO->INSTR_FF_WR = (uint32_t)((uint32_t)instr << CY_CRYPTO_OPCODE_POS);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Run1ParamInstr
*****************************************************************************//**
*
* Run the Crypto instruction with one parameter.
* The parameter must be placed into register 0
*
* This function available for CM0+ core only.
*
* \param instr
* The Opcode of the called instruction.
*
* \param rdst0Shift
* The shift for the instruction operand.
*
*******************************************************************************/
void Cy_Crypto_Run1ParamInstr(uint8_t instr,
uint32_t rdst0Shift)
{
/* Check whether FIFO has enough space for 1 instruction */
while(Cy_Crypto_Core_GetFIFOUsed() >= CY_CRYPTO_FIFODEPTH)
{
}
CRYPTO->INSTR_FF_WR = (uint32_t)(((uint32_t)instr << CY_CRYPTO_OPCODE_POS) |
((uint32_t)CY_CRYPTO_REGFILE_R0 << rdst0Shift));
}
/*******************************************************************************
* Function Name: Cy_Crypto_Run2ParamInstr
*****************************************************************************//**
*
* Run the Crypto instruction with two parameters.
* The zero parameter must be placed into register 0,
* the first parameter must be placed into register 1.
*
* This function available for CM0+ core only.
*
* \param instr
* The Opcode of the called instruction.
*
* \param rdst0Shift
* The shift for the zero instruction operand.
*
* \param rdst1Shift
* The shift for the second instruction operand.
*
*******************************************************************************/
void Cy_Crypto_Run2ParamInstr(uint8_t instr,
uint32_t rdst0Shift,
uint32_t rdst1Shift)
{
/* Check whether FIFO has enough space for 1 instruction */
while(Cy_Crypto_Core_GetFIFOUsed() >= CY_CRYPTO_FIFODEPTH)
{
}
CRYPTO->INSTR_FF_WR = (uint32_t)(((uint32_t)instr << CY_CRYPTO_OPCODE_POS) |
((uint32_t)CY_CRYPTO_REGFILE_R1 << rdst1Shift) |
((uint32_t)CY_CRYPTO_REGFILE_R0 << rdst0Shift));
}
/*******************************************************************************
* Function Name: Cy_Crypto_Run3ParamInstr
*****************************************************************************//**
*
* Run the Crypto instruction with three parameters.
* The zero parameter must be placed into register 0,
* the first parameter must be placed into register 1,
* the second parameter must be placed into register 2.
*
* This function available for CM0+ core only.
*
* \param instr
* The Opcode of the called instruction.
*
* \param rdst0Shift
* The shift for the zero instruction operand.
*
* \param rdst1Shift
* The shift for the second instruction operand.
*
** \param rdst2Shift
* The shift for the second instruction operand.
*
*******************************************************************************/
void Cy_Crypto_Run3ParamInstr(uint8_t instr,
uint8_t rdst0Shift,
uint8_t rdst1Shift,
uint8_t rdst2Shift)
{
/* Check whether FIFO has enough space for 1 instruction */
while(Cy_Crypto_Core_GetFIFOUsed() >= CY_CRYPTO_FIFODEPTH)
{
}
CRYPTO->INSTR_FF_WR = (uint32_t)(((uint32_t)instr << CY_CRYPTO_OPCODE_POS) |
((uint32_t)CY_CRYPTO_REGFILE_R2 << rdst2Shift) |
((uint32_t)CY_CRYPTO_REGFILE_R1 << rdst1Shift) |
((uint32_t)CY_CRYPTO_REGFILE_R0 << rdst0Shift));
}
/*******************************************************************************
* Function Name: Cy_Crypto_Run4ParamInstr
*****************************************************************************//**
*
* Run the Crypto instruction with four parameters.
* The zero parameter must be placed into register 0,
* the first parameter must be placed into register 1,
* the second parameter must be placed into register 2,
* the third parameter must be placed into register 3.
*
* This function available for CM0+ core only.
*
* \param instr
* The Opcode of the called instruction.
*
* \param rdst0Shift
* The shift for the zero instruction operand.
*
* \param rdst1Shift
* The shift for the first instruction operand.
*
* \param rdst2Shift
* The shift for the second instruction operand.
*
* \param rdst3Shift
* The shift for the third instruction operand.
*
*******************************************************************************/
void Cy_Crypto_Run4ParamInstr(uint8_t instr,
uint32_t rdst0Shift,
uint32_t rdst1Shift,
uint32_t rdst2Shift,
uint32_t rdst3Shift)
{
/* Check whether FIFO has enough space for 1 instruction */
while(Cy_Crypto_Core_GetFIFOUsed() >= CY_CRYPTO_FIFODEPTH)
{
}
CRYPTO->INSTR_FF_WR = (uint32_t)(((uint32_t)instr << CY_CRYPTO_OPCODE_POS) |
((uint32_t)CY_CRYPTO_REGFILE_R3 << rdst3Shift) |
((uint32_t)CY_CRYPTO_REGFILE_R2 << rdst2Shift) |
((uint32_t)CY_CRYPTO_REGFILE_R1 << rdst1Shift) |
((uint32_t)CY_CRYPTO_REGFILE_R0 << rdst0Shift));
}
/*******************************************************************************
* Function Name: Cy_Crypto_InvertEndian8
*****************************************************************************//**
*
* Inverts endianness for eight bytes.
*
* This function available for CM0+ core only.
*
* \param srcVal
* The input data whose endianness will be inverted.
*
* \return
* An input value with inverted endianness.
*
*******************************************************************************/
uint64_t Cy_Crypto_InvertEndian8(uint64_t srcVal)
{
uint64_t tmpVal;
tmpVal = ((srcVal << 8u) & 0xFF00FF00FF00FF00ULL) | ((srcVal >> 8u) & 0x00FF00FF00FF00FFULL);
tmpVal = ((tmpVal << 16u) & 0xFFFF0000FFFF0000ULL) | ((tmpVal >> 16u) & 0x0000FFFF0000FFFFULL);
return ((tmpVal << 32u) | (tmpVal >> 32u));
}
#endif /* #if (CPUSS_CRYPTO_PRESENT == 1) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
/* [] END OF FILE */

View File

@ -0,0 +1,132 @@
/***************************************************************************//**
* \file cy_crypto_core_util.h
* \version 1.0
*
* \brief
* This file provides the headers to the API for the utils
* in the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_UTIL_H)
#define CY_CRYPTO_CORE_UTIL_H
#include "cy_crypto_common.h"
#include "syslib/cy_syslib.h"
#include <stdbool.h>
#if (CY_CPU_CORTEX_M0P)
#if (CPUSS_CRYPTO_PRESENT == 1)
extern bool cy_crypto_IsHwErrorOccured;
typedef enum {
CY_CRYPTO_CTL_ENABLED_DISABLED = 0u,
CY_CRYPTO_CTL_ENABLED_ENABLED = 1u,
} cy_en_crypto_hw_enable_t;
cy_en_crypto_status_t Cy_Crypto_Core_Enable(void);
cy_en_crypto_status_t Cy_Crypto_Core_Disable(void);
cy_en_crypto_status_t Cy_Crypto_Core_CheckHwForErrors(cy_stc_crypto_context_t *cryptoContext);
void Cy_Crypto_SetReg1Instr(uint32_t data0);
void Cy_Crypto_SetReg2Instr(uint32_t data0, uint32_t data1);
void Cy_Crypto_SetReg3Instr(uint32_t data0, uint32_t data1, uint32_t data2);
void Cy_Crypto_SetReg4Instr(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3);
void Cy_Crypto_Run0ParamInstr(uint8_t instr);
void Cy_Crypto_Run1ParamInstr(uint8_t instr,
uint32_t rdst0Shift);
void Cy_Crypto_Run2ParamInstr(uint8_t instr,
uint32_t rdst0Shift,
uint32_t rdst1Shift);
void Cy_Crypto_Run3ParamInstr(uint8_t instr,
uint8_t rdst0Shift,
uint8_t rdst1Shift,
uint8_t rdst2Shift);
void Cy_Crypto_Run4ParamInstr(uint8_t instr,
uint32_t rdst0Shift,
uint32_t rdst1Shift,
uint32_t rdst2Shift,
uint32_t rdst3Shift);
uint64_t Cy_Crypto_InvertEndian8(uint64_t srcVal);
/*******************************************************************************
* Function Name: Crypto_Server_GetFIFOUsed
****************************************************************************//**
*
* Returns the number of instructions in the instruction FIFO.
* The value of this field ranges from 0 to 8
*
*******************************************************************************/
__STATIC_INLINE uint8_t Cy_Crypto_Core_GetFIFOUsed(void)
{
return((uint8_t)_FLD2VAL(CRYPTO_INSTR_FF_STATUS_USED, CRYPTO->INSTR_FF_STATUS));
}
/*******************************************************************************
* Function Name: Crypto_Server_WaitForFifoAvailable
*****************************************************************************//**
*
* Waits until number of entries in the instruction FIFO is less than
* specified in EVENT_LEVEL field in FF_CTL register, an event is generated:
* "event" = INSTR_FF_STATUS.USED < EVENT_LEVEL.
* By default EVENT_LEVEL = 0;
*
* This function available for CM0+ core only.
*
*******************************************************************************/
__STATIC_INLINE void Cy_Crypto_Core_WaitForFifoAvailable(void)
{
while((_FLD2VAL(CRYPTO_INSTR_FF_STATUS_EVENT, CRYPTO->INSTR_FF_STATUS)) == 0)
{
}
}
/*******************************************************************************
* Function Name: Crypto_Server_WaitForFifoAvailable ???
*****************************************************************************//**
*
* Waits until all instruction in FIFO will be completed
*
* This function available for CM0+ core only.
*
*******************************************************************************/
__STATIC_INLINE void Cy_Crypto_Core_WaitForReady(void)
{
while((_FLD2VAL(CRYPTO_INSTR_FF_STATUS_BUSY, CRYPTO->INSTR_FF_STATUS)) == 1)
{
}
}
#endif /* #if (CPUSS_CRYPTO_PRESENT == 1) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_CORE_UTIL_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,66 @@
/***************************************************************************//**
* \file cy_crypto_core_vu.c
* \version 1.0
*
* \brief
* This file provides the source code to the API for the Vector Unit functions
* in the Crypto block driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "crypto/cy_crypto_common.h"
#include "crypto/cy_crypto_core_instructions.h"
#include "crypto/cy_crypto_core_vu.h"
#include "crypto/cy_crypto_core_util.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1))
/*******************************************************************************
* Function Name: Cy_Crypto_Wait_Vu_ForComplete
****************************************************************************//**
*
* Waits until VU instruction will be completed
*
* This function available for CM0+ core only.
*
*******************************************************************************/
void Cy_Crypto_Core_Vu_WaitForComplete(void)
{
/* Wait until the VU instruction is complete */
while(0uL != _FLD2VAL(CRYPTO_STATUS_VU_BUSY, CRYPTO->STATUS))
{
}
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Vu_StatusRead
****************************************************************************//**
*
* Returns value of the VU status register
*
* This function available for CM0+ core only.
*
*******************************************************************************/
uint16_t Cy_Crypto_Core_Vu_StatusRead(void)
{
Cy_Crypto_Core_WaitForReady();
return((uint16_t)CRYPTO->VU_STATUS);
}
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
/* [] END OF FILE */

View File

@ -0,0 +1,136 @@
/***************************************************************************//**
* \file cy_crypto_core_vu.h
* \version 1.0
*
* \brief
* This file provides constants and function prototypes
* for the Vector Unit functions in the Crypto block driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_VU_H)
#define CY_CRYPTO_CORE_VU_H
#include "crypto/cy_crypto_common.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1))
/* Function Prototypes */
void Cy_Crypto_Core_Vu_WaitForComplete(void);
uint16_t Cy_Crypto_Core_Vu_StatusRead(void);
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Vu_RegRead
****************************************************************************//**
*
* Returns size of the data pointed in given register,
* it is lower 14Bit of the 32Bit word
*
* \param srcReg
*
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_Crypto_Core_Vu_RegRead(uint8_t srcReg)
{
return ((uint32_t)_FLD2VAL(CRYPTO_RF_DATA_DATA32, CRYPTO->RF_DATA[srcReg]));
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Vu_RegSizeRead
****************************************************************************//**
*
* Returns size of the data pointed in given register,
* it is lower 14Bit of the 32Bit word
*
* \param srcReg
*
*
*******************************************************************************/
__STATIC_INLINE uint16_t Cy_Crypto_Core_Vu_RegSizeRead(uint8_t srcReg)
{
return ((uint16_t)(_FLD2VAL(CRYPTO_RF_DATA_DATA32, CRYPTO->RF_DATA[srcReg]) & 0x00000fff));
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Vu_RegBitSizeRead
****************************************************************************//**
*
* Returns size of the data pointed in given register, in Bits.
* It is lower 14Bit of the 32Bit word
*
* \param srcReg
*
*
*******************************************************************************/
__STATIC_INLINE uint16_t Cy_Crypto_Core_Vu_RegBitSizeRead(uint8_t srcReg)
{
return ((uint16_t)(_FLD2VAL(CRYPTO_RF_DATA_DATA32, CRYPTO->RF_DATA[srcReg]) & 0x00000fff) + 1);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Vu_RegByteSizeRead
****************************************************************************//**
*
* Returns size of the data pointed in given register, in Bytes.
* It is lower 14Bit of the 32Bit word
*
* \param srcReg
*
*
*******************************************************************************/
__STATIC_INLINE uint16_t Cy_Crypto_Core_Vu_RegByteSizeRead(uint8_t srcReg)
{
return ((uint16_t)(_FLD2VAL(CRYPTO_RF_DATA_DATA32, CRYPTO->RF_DATA[srcReg]) & 0x00000fff) >> 3);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Vu_RegWordRead
****************************************************************************//**
*
* Returns size of the data pointed in given register, in words (uint32_t).
* It is lower 14Bit of the 32Bit word
*
* \param srcReg
*
*
*******************************************************************************/
__STATIC_INLINE uint16_t Cy_Crypto_Core_Vu_RegWordSizeRead(uint8_t srcReg)
{
return ((uint16_t)(_FLD2VAL(CRYPTO_RF_DATA_DATA32, CRYPTO->RF_DATA[srcReg]) & 0x00000fff) >> 5);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Core_Vu_RegDataRead
****************************************************************************//**
*
* Returns the data pointer, in 14-bit format of the data pointed in given register,
* it is upper 16Bit of the 32Bir word. Pointer is in words (uint32_t).
*
* \param srcReg
*
*
*******************************************************************************/
__STATIC_INLINE uint16_t Cy_Crypto_Core_Vu_RegDataPtrRead(uint8_t srcReg)
{
return ((uint16_t)(_FLD2VAL(CRYPTO_RF_DATA_DATA32, CRYPTO->RF_DATA[srcReg]) >> 16) & 0x00003fff);
}
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1)) */
#endif /* #if (CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_CORE_VU_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,380 @@
/***************************************************************************//**
* \file cy_crypto_core_vu_hw.h
* \version 1.0
*
* \brief
* This file provides constants and function prototypes
* for the Vector Unit functions in the Crypto block driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_CORE_VU_HW_H)
#define CY_CRYPTO_CORE_VU_HW_H
#include "cy_device_headers.h"
#include "crypto/cy_crypto_core_instructions.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_VU == 1))
/* VU Instructions */
#define CY_CRYPTO_VU_ALLOC_MEM(rdst, size) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_ALLOC_MEM_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)size - 1)))
#define CY_CRYPTO_VU_CALLOC_MEM(rdst, size) \
\
{CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_ALLOC_MEM_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)size - 1)); \
memset( (CRYPTO->MEM_BUFF + (((CRYPTO->RF_DATA[rdst] >> 16) & 0x00003fff) >> 2)), 0x00, 4 * (size + 31) / 32); }
#define CY_CRYPTO_VU_FREE_MEM(reg_mask) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_FREE_MEM_OPC << 24) | \
(uint32_t)reg_mask))
#define CY_CRYPTO_VU_SET_REG(rdst, data, size) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_SET_REG_OPC << 24) | \
((uint32_t)rdst << 26) | \
((uint32_t)data << 12) | \
((uint32_t)size - 1)))
#define CY_CRYPTO_VU_MOV_REG(rdst, rsrc) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_MOV_REG_TO_STATUS_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc << 0)))
#define CY_CRYPTO_VU_LD_REG(rdst, rsrc) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_LD_REG_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc << 0)))
#define CY_CRYPTO_VU_ST_REG(rdst, rsrc) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_ST_REG_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc << 0)))
#define CY_CRYPTO_VU_SWAP_REG(rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_SWAP_REG_OPC << 24) | \
((uint32_t)rsrc1 << 4) | \
((uint32_t)rsrc0 << 0)))
#define CY_CRYPTO_VU_COND_SWAP_REG(cc, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_SWAP_REG_OPC << 24) | \
((uint32_t)cc << 20) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_MOV_REG_TO_STATUS(rsrc) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_MOV_REG_TO_STATUS_OPC << 24) | (uint32_t)rsrc))
#define CY_CRYPTO_VU_MOV_STATUS_TO_REG(rdst) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_MOV_STATUS_TO_REG_OPC << 24) | ((uint32_t)rdst << 12)))
#define CY_CRYPTO_VU_PUSH_REG() (CRYPTO->INSTR_FF_WR = ((uint32_t)CY_CRYPTO_VU_PUSH_REG_OPC << 24))
#define CY_CRYPTO_VU_POP_REG() (CRYPTO->INSTR_FF_WR = ((uint32_t)CY_CRYPTO_VU_POP_REG_OPC << 24))
#define CY_CRYPTO_VU_ADD_REG(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_ADD_REG_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_SUB_REG(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_SUB_REG_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_OR_REG(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_OR_REG_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_AND_REG(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_AND_REG_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_XOR_REG(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_XOR_REG_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_NOR_REG(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_NOR_REG_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_NAND_REG(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_NAND_REG_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_MIN_REG(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_MIN_REG_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_MAX_REG(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_MAX_REG_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_LSL(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_LSL_OPC << 24) |\
((uint32_t)rdst << 12) |\
((uint32_t)rsrc1 << 4) |\
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_LSR(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_LSR_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_LSL1(rdst, rsrc1) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_LSL1_OPC << 24) |\
((uint32_t)rdst << 12) |\
((uint32_t)rsrc1 << 4)))
#define CY_CRYPTO_VU_LSL1_WITH_CARRY(rdst, rsrc1) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_LSL1_WITH_CARRY_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4)))
#define CY_CRYPTO_VU_LSR1(rdst, rsrc1) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_LSR1_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4)))
#define CY_CRYPTO_VU_LSR1_WITH_CARRY(rdst, rsrc1) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_LSR1_WITH_CARRY_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4)))
#define CY_CRYPTO_VU_SET_BIT(rdst, rsrc) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_SET_BIT_OPC << 24) | \
((uint32_t)rdst << 12) | \
(uint32_t)rsrc))
#define CY_CRYPTO_VU_CLR_BIT(rdst, rsrc) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_CLR_BIT_OPC << 24) | \
((uint32_t)rdst << 12) | \
(uint32_t)rsrc))
#define CY_CRYPTO_VU_INV_BIT(rdst, rsrc) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_INV_BIT_OPC << 24) | \
((uint32_t)rdst << 12) | \
(uint32_t)rsrc))
#define CY_CRYPTO_VU_GET_BIT(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_GET_BIT_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_CLSAME(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_CLSAME_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_CTSAME(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_CTSAME_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_SET_TO_ZERO(rdst) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_SET_TO_ZERO_OPC << 24) | ((uint32_t)rdst << 12)))
#define CY_CRYPTO_VU_SET_TO_ONE(rdst) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_SET_TO_ONE_OPC << 24) | ((uint32_t)rdst << 12)))
#define CY_CRYPTO_VU_MOV(rdst, rsrc) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_MOV_OPC << 24) | \
((uint32_t)rdst << 12) | \
(uint32_t)rsrc))
#define CY_CRYPTO_VU_COND_MOV(cc, rdst, rsrc) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_MOV_OPC << 24) | \
((uint32_t)cc << 20) | \
((uint32_t)rdst << 12) | \
(uint32_t)rsrc))
#define CY_CRYPTO_VU_XSQUARE(rdst, rsrc) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_XSQUARE_OPC << 24) | \
((uint32_t)rdst << 12) | \
(uint32_t)rsrc))
#define CY_CRYPTO_VU_CMP_SUB(rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_CMP_SUB_OPC << 24) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_COND_CMP_SUB(cc, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_CMP_SUB_OPC << 24) | \
((uint32_t)cc << 20) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_CMP_DEGREE(rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_CMP_DEGREE_OPC << 24) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_TST(rsrc0) (CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_TST_OPC << 24) | (uint32_t)rsrc0))
#define CY_CRYPTO_VU_XMUL(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_XMUL_OPC << 24) |\
((uint32_t)rdst << 12) |\
((uint32_t)rsrc1 << 4) |\
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_UMUL(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_UMUL_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_ADD(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_ADD_OPC << 24) |\
((uint32_t)rdst << 12) |\
((uint32_t)rsrc1 << 4) |\
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_COND_ADD(cc, rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_ADD_OPC << 24) | \
((uint32_t)cc << 20) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_SUB(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_SUB_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_COND_SUB(cc, rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_SUB_OPC << 24) | \
((uint32_t)cc << 20) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_OR(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_OR_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_AND(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_AND_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_XOR(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_XOR_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_COND_XOR(cc, rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_XOR_OPC << 24) | \
((uint32_t)cc << 20) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_NOR(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_NOR_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#define CY_CRYPTO_VU_NAND(rdst, rsrc1, rsrc0) \
\
(CRYPTO->INSTR_FF_WR = (((uint32_t)CY_CRYPTO_VU_NAND_OPC << 24) | \
((uint32_t)rdst << 12) | \
((uint32_t)rsrc1 << 4) | \
(uint32_t)rsrc0))
#endif /* #if ((CPUSS_CRYPTO_PRESENT == 1) && (CPUSS_CRYPTO_VU == 1)) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_CORE_VU_HW_H) */

View File

@ -0,0 +1,409 @@
/***************************************************************************//**
* \file cy_crypto_server.c
* \version 1.0
*
* \brief
* This file provides the source code to the API for Crypto Server
* in the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_device_headers.h"
#include "ipc/cy_ipc_drv.h"
#include "sysint/cy_sysint.h"
#include "syslib/cy_syslib.h"
#include "crypto/cy_crypto_common.h"
#include "crypto/cy_crypto_server.h"
#include "crypto/cy_crypto_core_aes.h"
#include "crypto/cy_crypto_core_sha.h"
#include "crypto/cy_crypto_core_hmac.h"
#include "crypto/cy_crypto_core_cmac.h"
#include "crypto/cy_crypto_core_prng.h"
#include "crypto/cy_crypto_core_trng.h"
#include "crypto/cy_crypto_core_rsa.h"
#include "crypto/cy_crypto_core_str.h"
#include "crypto/cy_crypto_core_crc.h"
#include "crypto/cy_crypto_core_des.h"
#include "crypto/cy_crypto_core_util.h"
#include "crypto/cy_crypto_core_instructions.h"
#include <stdbool.h>
#if (CY_CPU_CORTEX_M0P)
#if (CPUSS_CRYPTO_PRESENT == 1)
/* The number of the interrupt to catch Crypto HW errors */
IRQn_CM0P_Type cy_crypto_ErrorIrqNum;
/*
* The global variables to store a pointers on the customer callback functions.
* This variable is global because it is called from an interrupt.
*/
cy_israddress cy_cryptoGetDataHandlerPtr = NULL;
cy_israddress cy_cryptoErrorHandlerPtr = NULL;
/*
* The global variable to store a pointer to crypto processing context data.
*/
cy_stc_crypto_context_t *processData = NULL;
/* Functions Prototypes */
void Cy_Crypto_Server_PopulateHwErrInfo(cy_stc_crypto_context_t *cryptoContextPtr);
void Cy_Crypto_Server_Run(cy_stc_crypto_context_t* data);
void Cy_Crypto_Server_Invoke(void);
void Cy_Crypto_Server_ErrorHandler(void);
/*******************************************************************************
* Function Name: Cy_Crypto_Server_Start
****************************************************************************//**
*
* Starts the Crypto server on the M0 core, sets up an interrupt
* for the IPC Crypto channel on the M0 core, sets up an interrupt
* to catch Crypto HW errors. Should be invoked only on CM0.
*
* This function available for CM0+ core only.
*
* \param configStruct
* The Crypto configuration structure.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Server_Start(cy_stc_crypto_config_t const *configStruct)
{
/* Initialize the interrupt controller for M0 and IPC Interrupt */
cy_stc_sysint_t intrCfg;
intrCfg.intrSrc = (IRQn_Type)(cpuss_interrupts_ipc0_IRQn + CY_CRYPTO_NOTIFY_INTR);
intrCfg.intrCm0p = (IRQn_CM0P_Type)(configStruct->cm0NotifyIntrNum);
intrCfg.intrPriority = configStruct->notifyIntrPrior;
if (configStruct->userGetDataHandler != NULL)
{
Cy_SysInt_Init(&intrCfg, configStruct->userGetDataHandler);
cy_cryptoGetDataHandlerPtr = configStruct->userGetDataHandler;
}
else
{
Cy_SysInt_Init(&intrCfg, &Cy_Crypto_Server_GetDataHandler);
}
NVIC_EnableIRQ((IRQn_Type)intrCfg.intrCm0p);
/* Do not bring up an IPC release interrupt here, only set up a notify interrupt */
Cy_IPC_DRV_SetIntrMask(Cy_IPC_DRV_GetIntrBaseAddr(CY_CRYPTO_NOTIFY_INTR), CY_IPC_NO_NOTIFIFICATION, (1uL << CY_IPC_CHAN_CRYPTO));
/* Initialize and enable an interrupt to handle possible Crypto HW errors */
intrCfg.intrSrc = (IRQn_Type)(cpuss_interrupt_crypto_IRQn);
/* Initialize an interrupt to check a Crypto HW error*/
cy_crypto_ErrorIrqNum = (IRQn_CM0P_Type)(configStruct->cm0CryptoErrorIntrNum);
intrCfg.intrCm0p = cy_crypto_ErrorIrqNum;
intrCfg.intrPriority = configStruct->cryptoErrorIntrPrior;
if (configStruct->userErrorHandler != NULL)
{
Cy_SysInt_Init(&intrCfg, configStruct->userErrorHandler);
cy_cryptoErrorHandlerPtr = configStruct->userErrorHandler;
}
else
{
Cy_SysInt_Init(&intrCfg, &Cy_Crypto_Server_ErrorHandler);
}
NVIC_ClearPendingIRQ((IRQn_Type)intrCfg.intrCm0p);
NVIC_EnableIRQ((IRQn_Type)intrCfg.intrCm0p);
return (CY_CRYPTO_SUCCESS);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Server_Stop
****************************************************************************//**
*
* Stops the Crypto server by disabling the IPC notify interrupt
* and Crypto error interrupt. Should be invoked only on CM0.
*
* This function available for CM0+ core only.
*
* \param configStruct
* The Crypto configuration structure.
*
* \return
* A Crypto status \ref cy_en_crypto_status_t.
*
*******************************************************************************/
cy_en_crypto_status_t Cy_Crypto_Server_Stop(cy_stc_crypto_config_t const *configStruct)
{
uint32_t interruptMask;
/* Disable the Notify interrupt from IPC */
NVIC_DisableIRQ((IRQn_Type)configStruct->cm0NotifyIntrNum);
NVIC_ClearPendingIRQ((IRQn_Type)configStruct->cm0NotifyIntrNum);
/* Disable the Error interrupt from Crypto */
NVIC_DisableIRQ((IRQn_Type)configStruct->cm0CryptoErrorIntrNum);
NVIC_ClearPendingIRQ((IRQn_Type)configStruct->cm0CryptoErrorIntrNum);
/* Disable CRYPTO IPC interrupt */
interruptMask = Cy_IPC_DRV_GetIntrMask(Cy_IPC_DRV_GetIntrBaseAddr(CY_CRYPTO_NOTIFY_INTR));
Cy_IPC_DRV_SetIntrMask(Cy_IPC_DRV_GetIntrBaseAddr(CY_CRYPTO_NOTIFY_INTR), CY_IPC_NO_NOTIFIFICATION, interruptMask & ~(1uL << CY_IPC_CHAN_CRYPTO));
cy_cryptoGetDataHandlerPtr = NULL;
cy_cryptoErrorHandlerPtr = NULL;
return (CY_CRYPTO_SUCCESS);
}
/*******************************************************************************
* Function Name: Cy_Crypto_Server_ErrorHandler
****************************************************************************//**
*
* The routine to handle an interrupt caused by the Crypto hardware error.
*
* This function available for CM0+ core only.
*
*******************************************************************************/
void Cy_Crypto_Server_ErrorHandler(void)
{
NVIC_ClearPendingIRQ((IRQn_Type)cy_crypto_ErrorIrqNum);
cy_crypto_IsHwErrorOccured = true;
}
/*******************************************************************************
* Function Name: Cy_Crypto_Server_Process
****************************************************************************//**
*
* Parses input data received from the Crypto Client
* and runs the appropriate Crypto function.
*
* This function available for CM0+ core only.
*
*******************************************************************************/
void Cy_Crypto_Server_Process(void)
{
cy_stc_crypto_context_t* data = processData;
if (data != NULL)
{
/* Default error */
data->resp = CY_CRYPTO_HW_NOT_ENABLED;
if (CY_CRYPTO_INSTR_ENABLE == data->instr)
{
data->resp = Cy_Crypto_Core_Enable();
}
else
{
/* Check if Crypto HW is enabled */
if(1uL == (uint32_t)_FLD2VAL(CRYPTO_CTL_ENABLED, CRYPTO->CTL))
{
data->resp = CY_CRYPTO_SUCCESS;
switch(data->instr)
{
case CY_CRYPTO_INSTR_DISABLE:
data->resp = Cy_Crypto_Core_Disable();
break;
#if ((CPUSS_CRYPTO_PR == 1) && (CY_CRYPTO_USER_PR == 1))
case CY_CRYPTO_INSTR_PRNG_INIT:
data->resp = Cy_Crypto_Core_Prng_Init((cy_stc_crypto_context_prng_t*)data->xdata);
break;
case CY_CRYPTO_INSTR_PRNG:
data->resp = Cy_Crypto_Core_Prng((cy_stc_crypto_context_prng_t*)data->xdata);
break;
#endif /* #if ((CPUSS_CRYPTO_PR == 1) && (CY_CRYPTO_USER_PR == 1)) */
#if ((CPUSS_CRYPTO_TR == 1) && (CY_CRYPTO_USER_TR == 1))
case CY_CRYPTO_INSTR_TRNG:
data->resp = Cy_Crypto_Core_Trng((cy_stc_crypto_context_trng_t*)data->xdata);
break;
#endif /* #if ((CPUSS_CRYPTO_TR == 1) && (CY_CRYPTO_USER_TR == 1)) */
#if ((CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1))
case CY_CRYPTO_INSTR_AES_INIT:
data->resp = Cy_Crypto_Core_Aes_Init((cy_stc_crypto_context_aes_t *)data->xdata);
break;
#if (CY_CRYPTO_USER_AES_ECB == 1)
case CY_CRYPTO_INSTR_AES_ECB:
data->resp = Cy_Crypto_Core_Aes_Ecb((cy_stc_crypto_context_aes_t *)data->xdata);
break;
#endif /* #if (CRYPTO_USER_AES_ECB == 1) */
#if (CY_CRYPTO_USER_AES_CBC == 1)
case CY_CRYPTO_INSTR_AES_CBC:
data->resp = Cy_Crypto_Core_Aes_Cbc((cy_stc_crypto_context_aes_t *)data->xdata);
break;
#endif /* #if (CRYPTO_USER_AES_CBC == 1) */
#if (CY_CRYPTO_USER_AES_CFB == 1)
case CY_CRYPTO_INSTR_AES_CFB:
data->resp = Cy_Crypto_Core_Aes_Cfb((cy_stc_crypto_context_aes_t *)data->xdata);
break;
#endif /* #if (CRYPTO_USER_AES_CFB == 1) */
#if (CY_CRYPTO_USER_AES_CTR == 1)
case CY_CRYPTO_INSTR_AES_CTR:
data->resp = Cy_Crypto_Core_Aes_Ctr((cy_stc_crypto_context_aes_t *)data->xdata);
break;
#endif /* #if (CRYPTO_USER_AES_CTR == 1) */
#if (CY_CRYPTO_USER_CMAC == 1)
case CY_CRYPTO_INSTR_CMAC:
data->resp = Cy_Crypto_Core_Cmac((cy_stc_crypto_context_aes_t *)data->xdata);
break;
#endif /* #if (CRYPTO_USER_CMAC == 1) */
#endif /* #if ((CPUSS_CRYPTO_AES == 1) && (CY_CRYPTO_USER_AES_ENABLE == 1)) */
#if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1))
case CY_CRYPTO_INSTR_SHA:
data->resp = Cy_Crypto_Core_Sha((cy_stc_crypto_context_sha_t *)data->xdata);
break;
#endif /* #if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_SHA_ENABLE == 1)) */
#if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_HMAC == 1))
case CY_CRYPTO_INSTR_HMAC:
data->resp = Cy_Crypto_Core_Hmac((cy_stc_crypto_context_sha_t *)data->xdata);
break;
#endif /* #if ((CPUSS_CRYPTO_SHA == 1) && (CY_CRYPTO_USER_HMAC == 1)) */
#if ((CPUSS_CRYPTO_STR == 1) && (CY_CRYPTO_USER_STR == 1))
case CY_CRYPTO_INSTR_MEM_CPY:
Cy_Crypto_Core_Str_MemCpy(((cy_stc_crypto_context_str_t* )data->xdata)->dstPtr,
((cy_stc_crypto_context_str_t* )data->xdata)->srcPtr0,
(uint16_t)((cy_stc_crypto_context_str_t* )data->xdata)->dataSize );
break;
case CY_CRYPTO_INSTR_MEM_SET:
Cy_Crypto_Core_Str_MemSet(((cy_stc_crypto_context_str_t*)data->xdata)->dstPtr,
((cy_stc_crypto_context_str_t*)data->xdata)->data,
(uint16_t)(((cy_stc_crypto_context_str_t*)data->xdata)->dataSize) );
break;
case CY_CRYPTO_INSTR_MEM_CMP:
*(uint32_t* )(((cy_stc_crypto_context_str_t* )data->xdata)->dstPtr) =
Cy_Crypto_Core_Str_MemCmp(((cy_stc_crypto_context_str_t* )data->xdata)->srcPtr0,
((cy_stc_crypto_context_str_t* )data->xdata)->srcPtr1,
(uint16_t)((cy_stc_crypto_context_str_t* )data->xdata)->dataSize );
break;
case CY_CRYPTO_INSTR_MEM_XOR:
Cy_Crypto_Core_Str_MemXor(((cy_stc_crypto_context_str_t* )data->xdata)->srcPtr0,
((cy_stc_crypto_context_str_t* )data->xdata)->srcPtr1,
((cy_stc_crypto_context_str_t* )data->xdata)->dstPtr,
(uint16_t)((cy_stc_crypto_context_str_t* )data->xdata)->dataSize );
break;
#endif /* #if ((CPUSS_CRYPTO_STR == 1) && (CY_CRYPTO_USER_STR == 1)) */
#if ((CPUSS_CRYPTO_CRC == 1) && (CY_CRYPTO_USER_CRC == 1))
case CY_CRYPTO_INSTR_CRC_INIT:
data->resp = Cy_Crypto_Core_Crc_Init((cy_stc_crypto_context_crc_t*)data->xdata);
break;
case CY_CRYPTO_INSTR_CRC:
data->resp = Cy_Crypto_Core_Crc((cy_stc_crypto_context_crc_t*)data->xdata);
break;
#endif /* #if ((CPUSS_CRYPTO_CRC == 1) && (CY_CRYPTO_USER_CRC == 1)) */
#if ((CPUSS_CRYPTO_DES == 1) && (CY_CRYPTO_USER_DES == 1))
case CY_CRYPTO_INSTR_DES:
data->resp = Cy_Crypto_Core_Des((cy_stc_crypto_context_des_t *)data->xdata);
break;
case CY_CRYPTO_INSTR_3DES:
data->resp = Cy_Crypto_Core_Tdes((cy_stc_crypto_context_des_t *)data->xdata);
break;
#endif /* #if ((CPUSS_CRYPTO_DES == 1) && (CY_CRYPTO_USER_DES == 1)) */
#if ((CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1))
case CY_CRYPTO_INSTR_RSA_PROC:
data->resp = Cy_Crypto_Core_Rsa_Proc((cy_stc_crypto_context_rsa_t *)data->xdata);
break;
case CY_CRYPTO_INSTR_RSA_COEF:
data->resp = Cy_Crypto_Core_Rsa_Coef((cy_stc_crypto_context_rsa_t *)data->xdata);
break;
#endif /* #if ((CPUSS_CRYPTO_VU == 1) && (CY_CRYPTO_USER_VU == 1)) */
#if (CY_CRYPTO_USER_PKCS1_5 == 1)
case CY_CRYPTO_INSTR_RSA_VER:
data->resp = Cy_Crypto_Core_RsaVerify((cy_stc_crypto_context_rsa_ver_t *)data->xdata);
break;
#endif /* #if (CY_CRYPTO_USER_PKCS1_5 == 1) */
default:
data->resp = CY_CRYPTO_NOT_SUPPORTED;
break;
}
if (CY_CRYPTO_SUCCESS == data->resp)
{
data->resp = Cy_Crypto_Core_CheckHwForErrors(data);
}
}
}
}
}
/*******************************************************************************
* Function Name: Cy_Crypto_Server_GetDataHandler
****************************************************************************//**
*
* The IPC Crypto channel notify interrupt-routine,
* receives information from the Crypto client, runs the process
* (if user not setup own handler),
* releases the Crypto IPC channel after the Crypto server completes.
*
* This function available for CM0+ core only.
*
*******************************************************************************/
void Cy_Crypto_Server_GetDataHandler()
{
uint32_t interruptMasked;
interruptMasked = Cy_IPC_DRV_GetIntrStatusMasked(Cy_IPC_DRV_GetIntrBaseAddr(CY_CRYPTO_NOTIFY_INTR));
/*
* Check that there is really the IPC Crypto Notify interrupt,
* because the same line can be used for the IPC Crypto Release interrupt.
*/
if((1uL << (CY_IPC_CHAN_CRYPTO + IPC_INTR_STRUCT_INTR_MASKED_NOTIFY_Pos)) == (interruptMasked & IPC_INTR_STRUCT_INTR_MASKED_NOTIFY_Msk))
{
Cy_IPC_DRV_ClearIntr(Cy_IPC_DRV_GetIntrBaseAddr(CY_CRYPTO_NOTIFY_INTR), CY_IPC_NO_NOTIFIFICATION, interruptMasked >> IPC_INTR_STRUCT_INTR_MASKED_NOTIFY_Pos);
if(CY_IPC_DRV_SUCCESS == Cy_IPC_DRV_ReadMsgPtr(Cy_IPC_DRV_GetIpcBaseAddress(CY_IPC_CHAN_CRYPTO), (void**)&processData))
{
if (cy_cryptoGetDataHandlerPtr == NULL)
{
Cy_Crypto_Server_Process();
}
/* Release the Crypto IPC channel with the Release interrupt */
(void)Cy_IPC_DRV_Release(Cy_IPC_DRV_GetIpcBaseAddress(CY_IPC_CHAN_CRYPTO), (1uL << CY_CRYPTO_RELEASE_INTR));
}
}
}
#endif /* #if (CPUSS_CRYPTO_PRESENT == 1) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
/* [] END OF FILE */

View File

@ -0,0 +1,51 @@
/***************************************************************************//**
* \file cy_crypto_server.h
* \version 1.0
*
* \brief
* This file provides the prototypes for common API
* in the Crypto driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_CRYPTO_SERVER_H)
#define CY_CRYPTO_SERVER_H
#include "crypto/cy_crypto_common.h"
#include "syslib/cy_syslib.h"
#if (CY_CPU_CORTEX_M0P)
#if (CPUSS_CRYPTO_PRESENT == 1)
/**
* \addtogroup group_crypto_functions
* \{
*/
cy_en_crypto_status_t Cy_Crypto_Server_Start(cy_stc_crypto_config_t const *configStruct);
cy_en_crypto_status_t Cy_Crypto_Server_Stop(cy_stc_crypto_config_t const *configStruct);
void Cy_Crypto_Server_Process(void);
void Cy_Crypto_Server_GetDataHandler(void);
void Cy_Crypto_Server_ErrorHandler(void);
/** \} group_crypto_functions */
#endif /* #if (CPUSS_CRYPTO_PRESENT == 1) */
#endif /* #if (CY_CPU_CORTEX_M0P) */
#endif /* #if !defined(CY_CRYPTO_SERVER_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,470 @@
/***************************************************************************//**
* \file cy_flash.c
* \version 1.0
*
* \brief
* Provides the public functions for the API for the PSoC 6 Flash Driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_flash.h"
/*******************************************************************************
* Function Name: Cy_Flash_WriteRow
****************************************************************************//**
*
* This function writes an array of data to a single row of flash. Reports success or
* or a reason for failure. Does not return until the Write operation is complete.
* Returns immediately and reports a CY_FLASH_DRV_IPC_BUSY error in the case when another
* process is writing to flash. User firmware should not enter the hibernate
* mode until flash Write is complete. The Flash operation is allowed in Sleep and
* Deep-sleep modes. During the Flash operation, the device should not be reset,
* including the XRES pin, a software reset, and watchdog reset sources. Also,
* low-voltage detect circuits should be configured to generate an interrupt instead
* of a reset. Otherwise, portions of flash may undergo unexpected changes.
*
* \param rowAddr Address of the flash row number. The number of the flash rows
* is defined by the \ref CY_FLASH_NUMBER_ROWS macro for the selected device.
* The Read-while-Write violation occurs when the flash read operation is
* initiated in the same flash sector where the flash write operation is
* performing. Refer to the device datasheet for the details.
* Address must match row start address.
*
* \param data The pointer to the data which has to be written to flash. The size
* of the data array must be equal to the flash row size. The flash row size for
* the selected device is defined by the \ref CY_FLASH_SIZEOF_ROW macro. Refer to
* the device datasheet for the details.
*
* \param contextPtr The pointer to the Flash driver context defined by the user.
* The flash driver context contains configuration data for flash operation.
*
* \return Returns the status of the Flash operation (see \ref cy_en_flashdrv_status_t).
*
*******************************************************************************/
cy_en_flashdrv_status_t Cy_Flash_WriteRow(uint32_t rowAddr, const uint32_t* data, cy_stc_flash_context_t* contextPtr)
{
uint32_t result;
cy_en_flashdrv_status_t retVal = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
#if (CY_CPU_CORTEX_M0P)
uint32_t interruptState;
uint32_t regVal;
interruptState = Cy_SysLib_EnterCriticalSection();
regVal = Cy_IPC_DRV_GetIntrMask(IPC_INTR_STRUCT0);
Cy_IPC_DRV_SetIntrMask(IPC_INTR_STRUCT0, ((regVal >> IPC_INTR_STRUCT_INTR_NOTIFY_Pos) | 0x07u), \
((regVal & IPC_INTR_STRUCT_INTR_MASK_RELEASE_Msk) | 0x07u));
result = Cy_Flash_StartWrite (rowAddr, data, contextPtr);
/* Check whether the Flash operation was successfully initiated */
if (result == CY_FLASH_DRV_OPERATION_STARTED)
{
/* Polls whether IPC is released and the Flash operation is performed */
do
{
result = Cy_Flash_IsWriteComplete(contextPtr);
}
while (result == CY_FLASH_DRV_OPCODE_BUSY);
}
Cy_SysLib_ExitCriticalSection(interruptState);
#else
if (Cy_Flash_PrepeareContext(rowAddr, data, contextPtr) != CY_FLASH_DRV_INVALID_INPUT_PARAMETERS)
{
Cy_Flash_Proxy Cy_Flash_Cm4Proxy;
Cy_Flash_Cm4Proxy = (Cy_Flash_Proxy)CY_FLASH_CM4_FLASH_PROXY_ADDR;
result = Cy_Flash_Cm4Proxy(contextPtr);
}
else
{
result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
}
#endif /* (CY_CPU_CORTEX_M0P) */
/* Invalidates the flash cache and buffer */
FLASHC->FLASH_CMD = FLASHC_FLASH_CMD_INV_Msk;
retVal = Cy_Flash_ProcessOpcode(result);
return (retVal);
}
/*******************************************************************************
* Function Name: Cy_Flash_StartWrite
****************************************************************************//**
*
* Starts writing an array of data to a single row of flash. Returns immediately
* and reports a successful start or reason for failure. Returns immediately and
* reports a CY_FLASH_IPC_BUSY error in the case when another process is writing
* to flash. User firmware should not enter the hibernate mode until flash Write
* is complete. The Flash operation is allowed in Sleep and Deep-sleep modes.
* During the flash operation, the device should not be reset, including the
* XRES pin, a software reset, and watchdog reset sources. Also, the low-voltage
* detect circuits should be configured to generate an interrupt instead of a reset.
* Otherwise, portions of flash may undergo unexpected changes.
*
* \param rowAddr Address of the flash row number. The number of the flash rows
* is defined by the \ref CY_FLASH_NUMBER_ROWS macro for the selected device.
* The Read-while-Write violation occurs when the flash read operation is
* initiated in the same flash sector where the flash write operation is
* performing. Refer to the device datasheet for the details.
* Address must row start address.
*
* \param data The pointer to the data to be written to flash. The size
* of the data array must be equal to the flash row size. The flash row size for
* the selected device is defined by the \ref CY_FLASH_SIZEOF_ROW macro. Refer to
* the device datasheet for the details.
*
* \param contextPtr The pointer to the Flash driver context defined by the user.
* The Flash driver context contains configuration data for the Flash operation.
*
* \return Returns the status of the Flash operation (see \ref cy_en_flashdrv_status_t).
*
*******************************************************************************/
cy_en_flashdrv_status_t Cy_Flash_StartWrite(uint32_t rowAddr, const uint32_t* data, cy_stc_flash_context_t *contextPtr)
{
cy_en_flashdrv_status_t result;
result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
/* Checks whether the input parameters are valid */
if (Cy_Flash_PrepeareContext(rowAddr, data, contextPtr) != CY_FLASH_DRV_INVALID_INPUT_PARAMETERS)
{
/* Tries to acquire the IPC structure and pass the arguments to SROM API */
if (Cy_IPC_DRV_SendMsgPtr(CY_FLASH_IPC_STRUCT, CY_FLASH_IPC_NOTIFY_STRUCT0, (void*)contextPtr) == CY_IPC_DRV_SUCCESS)
{
/* The Flash operation is successfully initiated */
result = CY_FLASH_DRV_OPERATION_STARTED;
}
else
{
/* The IPC structure is already locked by another process */
result = CY_FLASH_DRV_IPC_BUSY;
}
}
else
{
result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
}
return (result);
}
/*******************************************************************************
* Function Name: Cy_Flash_IsWriteComplete
****************************************************************************//**
*
* Reports a successful Write, reason of failure or busy status (CY_FLASH_DRV_OPCODE_BUSY).
*
* \param contextPtr The pointer to the Flash driver context defined by the user.
*
* \return Returns the status of the Flash operation (see \ref cy_en_flashdrv_status_t).
*
*******************************************************************************/
cy_en_flashdrv_status_t Cy_Flash_IsWriteComplete(const cy_stc_flash_context_t* contextPtr)
{
cy_en_flashdrv_status_t retVal = CY_FLASH_DRV_OPCODE_BUSY;
/* Checks if the IPC structure is not locked */
if (Cy_IPC_DRV_GetLockStatus(CY_FLASH_IPC_STRUCT) == CY_IPC_DRV_RELEASED)
{
/* The result of SROM API calling is returned to the driver context */
retVal = Cy_Flash_ProcessOpcode(contextPtr->opcode);
}
return (retVal);
}
/*******************************************************************************
* Function Name: Cy_Flash_RowChecksum
****************************************************************************//**
*
* Returns a checksum value of the specified flash row.
*
* \param rowNum The Cheksum is calculated to the flash row.
*
* \param contextPtr The pointer to the Flash driver context defined by the user.
*
* \param cheksumPtr The pointer to the address whire cheksum is to be stored
*
* \return Returns the status of the Flash operation.
*
*******************************************************************************/
cy_en_flashdrv_status_t Cy_Flash_RowChecksum (uint32_t rowNum, cy_stc_flash_context_t* contextPtr, uint32_t* cheksumPtr)
{
cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
uint32_t resTmp;
/* Checks whether the input parameters are valid */
if ((rowNum >= CY_FLASH_NUMBER_ROWS) || (contextPtr == NULL))
{
result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
}
else
{
/* Prepares arguments to be passed to SROM API */
contextPtr->opcode = CY_FLASH_OPCODE_CHECKSUM | (rowNum << CY_FLASH_OPCODE_CHECKSUM_ROW_SHIFT);
/* Tries to acquire the IPC structure and pass the arguments to SROM API */
if (Cy_IPC_DRV_SendMsgPtr(CY_FLASH_IPC_STRUCT, CY_FLASH_IPC_NOTIFY_STRUCT0, (void*)contextPtr) == CY_IPC_DRV_SUCCESS)
{
/* Polls whether IPC is released and the Flash operation is performed */
while (Cy_IPC_DRV_GetLockStatus(CY_FLASH_IPC_STRUCT) != CY_IPC_DRV_RELEASED)
{
/* Wait till IPC is released */
}
resTmp = contextPtr->opcode;
if((resTmp >> CY_FLASH_ERROR_SHIFT) == CY_FLASH_ERROR_NO_ERROR)
{
result = CY_FLASH_DRV_SUCCESS;
*cheksumPtr = contextPtr->opcode & CY_FLASH_RESULT_MASK;
}
else
{
result = Cy_Flash_ProcessOpcode(result);
}
}
else
{
/* The IPC structure is already locked by another process */
result = CY_FLASH_DRV_IPC_BUSY;
}
}
return (result);
}
/*******************************************************************************
* Function Name: Cy_Flash_CalculateHash
****************************************************************************//**
*
* Returns a hash value of the specified region of flash.
*
* \param data Start the data address.
*
* \param numberOfBytes The hash value is calculated for the number of bytes after the
* start data address (0 1 byte,1- 2 bytes etc).
*
* \param contextPtr The pointer to the Flash driver context defined by the user.
*
* \param hashPtr The pointer to the address whire hash is to be stored
*
* \return Returns the status of the Flash operation.
*
*******************************************************************************/
cy_en_flashdrv_status_t Cy_Flash_CalculateHash (const uint32_t* data, uint32 numberOfBytes, cy_stc_flash_context_t* contextPtr, uint32_t* hashPtr)
{
cy_en_flashdrv_status_t result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
uint32_t resTmp;
/* Checks whether the input parameters are valid */
if ((data == NULL) || (contextPtr == NULL))
{
result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
}
else
{
/* Prepares arguments to be passed to SROM API */
contextPtr->opcode = CY_FLASH_OPCODE_HASH;
contextPtr->arg1 = (uint32_t)data;
contextPtr->arg2 = numberOfBytes;
/* Tries to acquire the IPC structure and pass the arguments to SROM API */
if (Cy_IPC_DRV_SendMsgPtr(CY_FLASH_IPC_STRUCT, CY_FLASH_IPC_NOTIFY_STRUCT0, (void*)contextPtr) == CY_IPC_DRV_SUCCESS)
{
/* Polls whether IPC is released and the Flash operation is performed */
while (Cy_IPC_DRV_GetLockStatus(CY_FLASH_IPC_STRUCT) != CY_IPC_DRV_RELEASED)
{
/* Wait till IPC is released */
}
resTmp = contextPtr->opcode;
if((resTmp >> CY_FLASH_ERROR_SHIFT) == CY_FLASH_ERROR_NO_ERROR)
{
result = CY_FLASH_DRV_SUCCESS;
*hashPtr = contextPtr->opcode & CY_FLASH_RESULT_MASK;
}
else
{
result = Cy_Flash_ProcessOpcode(result);
}
}
else
{
/* The IPC structure is already locked by another process */
result = CY_FLASH_DRV_IPC_BUSY;
}
}
return (result);
}
/*******************************************************************************
* Function Name: Cy_Flash_BoundsCheck
****************************************************************************//**
*
* Returns 1 if Flash addres is out of boundary, otherwise returns 0.
*
* \param flashAddr Address to be checked
*
* \return 1 - out of bound, 0 - in flash bounds
*
*******************************************************************************/
uint32_t Cy_Flash_BoundsCheck(uint32_t flashAddr)
{
uint32_t result = 1u;
if ((flashAddr < CY_FLASH_BASE) || (flashAddr >= (CY_FLASH_BASE + CY_FLASH_SIZE)))
{
if ((flashAddr < CY_WFLASH_BASE) || (flashAddr >= (CY_WFLASH_BASE + CY_WFLASH_SIZE)))
{
if ((flashAddr < SFLASH_BASE) || (flashAddr >= (SFLASH_BASE + SFLASH_SECTION_SIZE)))
{
result = 0u;
}
}
}
return (result);
}
/*******************************************************************************
* Function Name: Cy_Flash_PrepeareContext
****************************************************************************//**
*
* Returns 1 if parameters are correct and initialises contextPtr, otherwise returns
* CY_FLASH_DRV_INVALID_INPUT_PARAMETERS.
*
* \param rowAddr Address of the flash row number. The number of the flash rows
* is defined by the \ref CY_FLASH_NUMBER_ROWS macro for the selected device.
* The Read-while-Write violation occurs when the flash read operation is
* initiated in the same flash sector where the flash write operation is
* performing. Refer to the device datasheet for the details.
* Address must match row start address.
*
* \param data The pointer to the data which has to be written to flash. The size
* of the data array must be equal to the flash row size. The flash row size for
* the selected device is defined by the \ref CY_FLASH_SIZEOF_ROW macro. Refer to
* the device datasheet for the details.
*
* \param contextPtr The pointer to the Flash driver context defined by the user.
* The flash driver context contains configuration data for flash operation.
*
* \return 1 - Context ready, CY_FLASH_DRV_INVALID_INPUT_PARAMETERS - Wrong arguments
*
*******************************************************************************/
uint32_t Cy_Flash_PrepeareContext(uint32_t rowAddr, const uint32_t* data, cy_stc_flash_context_t *contextPtr)
{
uint32_t result;
if ((Cy_Flash_BoundsCheck(rowAddr) == 0) || (data == NULL) || (contextPtr == NULL))
{
result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
}
else
{
if (rowAddr%CY_FLASH_SIZEOF_ROW != 0)
{
result = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
}
else
{
/* Prepares arguments to be passed to SROM API */
contextPtr->opcode = CY_FLASH_OPCODE_WRITE_ROW;
contextPtr->arg1 = CY_FLASH_CONFIG_DATASIZE;
contextPtr->arg2 = rowAddr;
contextPtr->arg3 = (uint32_t)data;
result = 1u;
}
}
return (result);
}
/*******************************************************************************
* Function Name: Cy_Flash_ProcessOpcode
****************************************************************************//**
*
* Converts System Call returns to the Flash driver return defines.
*
* \param opcode The value retuned by the System Call.
*
* \return Flash driver return.
*
*******************************************************************************/
cy_en_flashdrv_status_t Cy_Flash_ProcessOpcode(uint32_t opcode)
{
cy_en_flashdrv_status_t retVal;
switch (opcode)
{
case 0UL:
{
retVal = CY_FLASH_DRV_SUCCESS;
break;
}
case CY_FLASH_ROMCODE_SUCCESS:
{
retVal = CY_FLASH_DRV_SUCCESS;
break;
}
case CY_FLASH_ROMCODE_INVALID_PROTECTION:
{
retVal = CY_FLASH_DRV_INV_PROT;
break;
}
case CY_FLASH_ROMCODE_INVALID_FM_PL:
{
retVal = CY_FLASH_DRV_INVALID_FM_PL;
break;
}
case CY_FLASH_ROMCODE_INVALID_FLASH_ADDR:
{
retVal = CY_FLASH_DRV_INVALID_FLASH_ADDR;
break;
}
case CY_FLASH_ROMCODE_ROW_PROTECTED:
{
retVal = CY_FLASH_DRV_ROW_PROTECTED;
break;
}
case CY_FLASH_ROMCODE_IN_PROGRESS_NO_ERROR:
{
retVal = CY_FLASH_DRV_PROGRESS_NO_ERROR;
break;
}
case CY_FLASH_DRV_INVALID_INPUT_PARAMETERS:
{
retVal = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
break;
}
default:
{
retVal = CY_FLASH_DRV_ERR_UNC;
}
}
return (retVal);
}
/* [] END OF FILE */

View File

@ -0,0 +1,283 @@
/***************************************************************************//**
* \file cy_flash.h
* \version 1.0
*
* Provides the API declarations of the Flash driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_FLASH_H)
#define CY_FLASH_H
/**
* \defgroup group_flash Flash System Routine (Flash)
* \{
* Internal flash memory programming
*
* Flash memory in PSoC devices provides non-volatile storage for user firmware,
* user configuration data, and bulk data storage.
*
* Flash operations are implemented as system calls. System calls are executed
* out of SROM in the privileged mode of operation. Users have no access to read
* or modify the SROM code. The driver API requests the system call by acquiring
* the Inter-processor communication (IPC) and writing the SROM function opcode
* and parameters to its input registers. As a result, an NMI interrupt is invoked
* and the requested SROM API is executed. The operation status is returned to the
* driver context and a release interrupt is triggered.
*
* Writing to flash can take up to 20 milliseconds. During this time,
* the device should not be reset (including XRES pin, software reset, and
* watchdog) or unexpected changes may be made to portions of the flash.
* Also, the low-voltage detect circuits should be configured to generate an
* interrupt instead of a reset.
*
* The Read while Write violation occurs when the flash Read operation is initiated
* in the same flash sector where the flash Write operation is performing. The
* violation leads to the exception generation. To avoid the Read while Write
* violation, the user has to carefully split the Read and Write operation from the
* same flash sector considering both cores in the multi-processor device.
* Use different flash sectors for code and data storage. The flash is divided
* into four equal sectors.
*
* \section group_flash_configuration Configuration Considerations
*
* There are no specific configuration parameters for the flash operations
* outside the driver API input parameters.
*
* \section group_flash_more_information More Information
*
* See the technical reference manual (TRM) for more information about the Flash architecture.
*
* \section group_flash_MISRA MISRA-C Compliance
*
* The Flash driver has the following specific deviations:
*
* <table class="doxtable">
* <tr>
* <th>MISRA Rule</th>
* <th>Rule Class (Required/Advisory)</th>
* <th>Rule Description</th>
* <th>Description of Deviation(s)</th>
* </tr>
* <tr>
* <td>19.7</td>
* <td>A</td>
* <td>A function shall be used in preference to a function-like macro</td>
* <td>Macro is used because of performance reasons</td>
* </tr>
* </table>
*
* \section group_flash_changelog Changelog
*
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_flash_macro Macro
* \defgroup group_flash_functions Functions
* \defgroup group_flash_data_structure Data Structures
*/
#include <cy_device_headers.h>
#include <stddef.h>
#include <ipc/cy_ipc_drv.h>
/***************************************
* Macro definitions
***************************************/
/**
* \addtogroup group_flash_macro
* \{
*/
/** Driver major version */
#define CY_FLASH_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_FLASH_DRV_VERSION_MINOR 0
/**
* \defgroup group_flash_returns Flash return values
* \{
* Specifies return values meaning
*/
#define CY_FLASH_ID (CY_PDL_DRV_ID(0x14u)) /**< FLASH PDL ID */
#define CY_FLASH_ID_INFO (uint32_t)( CY_FLASH_ID | CY_PDL_STATUS_INFO ) /**< Return prefix for FLASH driver function status codes */
#define CY_FLASH_ID_WARNING (uint32_t)( CY_FLASH_ID | CY_PDL_STATUS_WARNING) /**< Return prefix for FLASH driver function warning return values */
#define CY_FLASH_ID_ERROR (uint32_t)( CY_FLASH_ID | CY_PDL_STATUS_ERROR) /**< Return prefix for FLASH driver function error return values */
/** This enum has the return values of the Flash driver */
typedef enum
{
CY_FLASH_DRV_SUCCESS = 0x00ul, /**< Success */
CY_FLASH_DRV_INV_PROT = ( CY_FLASH_ID_ERROR + 0ul), /**< Invalid device protection state */
CY_FLASH_DRV_INVALID_FM_PL = ( CY_FLASH_ID_ERROR + 1ul), /**< Invalid flash page latch address */
CY_FLASH_DRV_INVALID_FLASH_ADDR = ( CY_FLASH_ID_ERROR + 2ul), /**< Invalid flash address */
CY_FLASH_DRV_ROW_PROTECTED = ( CY_FLASH_ID_ERROR + 3ul), /**< Row is write protected */
CY_FLASH_DRV_IPC_BUSY = ( CY_FLASH_ID_ERROR + 5ul), /**< IPC structure is already locked by another process */
CY_FLASH_DRV_INVALID_INPUT_PARAMETERS = ( CY_FLASH_ID_ERROR + 6ul), /**< Input parameters passed to Flash API are not valid */
CY_FLASH_DRV_ERR_UNC = ( CY_FLASH_ID_ERROR + 0xFul),/**< Unknown error */
CY_FLASH_DRV_PROGRESS_NO_ERROR = ( CY_FLASH_ID_INFO + 0ul), /**< Command in progress; no error */
CY_FLASH_DRV_OPERATION_STARTED = ( CY_FLASH_ID_INFO + 1ul), /**< Flash operation is successfully initiated */
CY_FLASH_DRV_OPCODE_BUSY = ( CY_FLASH_ID_INFO + 2ul), /**< Flash is under operation */
} cy_en_flashdrv_status_t;
/** \} group_flash_returns */
/** \cond INTERNAL */
/** Command completed with no errors */
#define CY_FLASH_ROMCODE_SUCCESS (0xA0000000UL)
/** Invalid device protection state */
#define CY_FLASH_ROMCODE_INVALID_PROTECTION (0xF0000001UL)
/** Invalid flash page latch address */
#define CY_FLASH_ROMCODE_INVALID_FM_PL (0xF0000003UL)
/** Invalid flash address */
#define CY_FLASH_ROMCODE_INVALID_FLASH_ADDR (0xF0000004UL)
/** Row is write protected */
#define CY_FLASH_ROMCODE_ROW_PROTECTED (0xF0000005UL)
/** Command in progress; no error */
#define CY_FLASH_ROMCODE_IN_PROGRESS_NO_ERROR (0xA0000009UL)
/** Flash operation is successfully initiated */
#define CY_FLASH_IS_OPERATION_STARTED (0x00000010UL)
/** Flash is under operation */
#define CY_FLASH_IS_BUSY (0x00000040UL)
/** IPC structure is already locked by another process */
#define CY_FLASH_IS_IPC_BUSY (0x00000080UL)
/** Input parameters passed to Flash API are not valid */
#define CY_FLASH_IS_INVALID_INPUT_PARAMETERS (0x00000100UL)
/** Result mask */
#define CY_FLASH_RESULT_MASK (0xFFFFFFFUL)
/** Error shift */
#define CY_FLASH_ERROR_SHIFT (28UL)
/** No error */
#define CY_FLASH_ERROR_NO_ERROR (0xAUL)
/** \endcond */
/**
* \addtogroup group_flash_config_macro Flash configuration
* \{
* Specifies the parameter values passed to SROM API
*/
/** SROM API opcode for flash write operation */
#if (CY_CPU_CORTEX_M0P) && (!defined(CY8C622PSVP) && !defined(CY8C622PSVP_DUAL))
#define CY_FLASH_OPCODE_WRITE_ROW (((0x05UL) << 24u) | ((0x01UL) << 8UL))
#else
#define CY_FLASH_OPCODE_WRITE_ROW ((0x05UL) << 24u)
#endif
/** SROM API opcode for flash checksum operation */
#define CY_FLASH_OPCODE_CHECKSUM ((0x0BUL) << 24u)
/** SROM API opcode for flash hash operation */
#define CY_FLASH_OPCODE_HASH ((0x0DUL) << 24u)
/** SROM API flash row shift for flash checksum operation */
#define CY_FLASH_OPCODE_CHECKSUM_ROW_SHIFT (8u)
/** SROM API flash data size parameter for flash write operation */
#define CY_FLASH_CONFIG_DATASIZE (0x06UL)
/** SROM API flash verification option for flash write operation */
#define CY_FLASH_CONFIG_VERIFICATION_EN ((0x01UL) << 16u)
/** \} group_flash_config_macro */
/**
* \addtogroup group_flash_general_macro Flash general parameters
* \{
* Provides general information about flash and IPC
*/
/** Flash row size */
#define CY_FLASH_SIZEOF_ROW (CPUSS_FLASHC_PA_SIZE * 4u)
/** Number of flash rows */
#define CY_FLASH_NUMBER_ROWS (CY_FLASH_SIZE / CY_FLASH_SIZEOF_ROW)
/** Long words flash row size */
#define CY_FLASH_SIZEOF_ROW_LONG_UNITS (CY_FLASH_SIZEOF_ROW / sizeof(uint32_t))
/** Calculates the flash address for a given row of flash */
#define CY_CALCULATE_FLASH_ADDRESS(rowNum) (CY_FLASH_BASE + ((rowNum) * CY_FLASH_SIZEOF_ROW))
/** IPC channel to be used */
#define CY_FLASH_IPC_STRUCT ((IPC_STRUCT_Type*) &IPC->STRUCT[CY_IPC_CHAN_SYSCALL])
/** IPC notify bit for IPC_STRUCT0 (dedicated to flash operation) */
#define CY_FLASH_IPC_NOTIFY_STRUCT0 (0x1UL)
/** \cond INTERNAL */
#define CY_FLASH_CM4_FLASH_PROXY_ADDR (0x16001101UL)
/** \endcond */
/** \} group_flash_general_macro */
/** \} group_flash_macro */
#if defined(__cplusplus)
extern "C" {
#endif
/***************************************
* Data Structure definitions
***************************************/
/**
* \addtogroup group_flash_data_structure
* \{
*/
/** Flash driver context */
typedef struct
{
uint32_t opcode; /**< Specifies the code of flash operation */
uint32_t arg1; /**< Specifies the configuration of flash operation */
uint32_t arg2; /**< Specifies the configuration of flash operation */
uint32_t arg3; /**< Specifies the configuration of flash operation */
}cy_stc_flash_context_t;
/** \} group_flash_data_structure */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_flash_functions
* \{
*/
cy_en_flashdrv_status_t Cy_Flash_WriteRow(uint32_t rowAddr, const uint32_t* data, cy_stc_flash_context_t* contextPtr);
cy_en_flashdrv_status_t Cy_Flash_StartWrite(uint32_t rowAddr, const uint32_t* data, cy_stc_flash_context_t* contextPtr);
cy_en_flashdrv_status_t Cy_Flash_IsWriteComplete(const cy_stc_flash_context_t* contextPtr);
cy_en_flashdrv_status_t Cy_Flash_RowChecksum (uint32_t rowNum, cy_stc_flash_context_t* contextPtr, uint32_t* cheksumPtr);
cy_en_flashdrv_status_t Cy_Flash_CalculateHash (const uint32_t* data, uint32 numberOfBytes, cy_stc_flash_context_t* contextPtr, uint32_t* hashPtr);
/** \cond INTERNAL */
uint32_t Cy_Flash_BoundsCheck(uint32_t flashAddr);
uint32_t Cy_Flash_PrepeareContext(uint32_t rowAddr, const uint32_t* data, cy_stc_flash_context_t *contextPtr);
cy_en_flashdrv_status_t Cy_Flash_ProcessOpcode(uint32_t opcode);
typedef cy_en_flashdrv_status_t (*Cy_Flash_Proxy)(cy_stc_flash_context_t *contextPtr);
/** \endcond */
/** \} group_flash_functions */
#if defined(__cplusplus)
}
#endif
#endif /* #if !defined(CY_FLASH_H) */
/** \endcond */
/** \} group_flash */
/* [] END OF FILE */

View File

@ -0,0 +1,137 @@
/***************************************************************************//**
* \file cy_gpio.c
* \version 1.0
*
* \brief
* Provides an API implementation of the GPIO driver
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_gpio.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_GPIO_Pin_Init
****************************************************************************//**
*
* \brief Initialize all pin configuration setting for the pin.
*
* \param base
* Pointer to the pin's port register base address
*
* \param pinNum
* Position of the pin bit-field within the port register
*
* \param config
* Pointer to the pin config structure base address
*
* \return
* void
*
* \note
* This function modifies port registers in read-modify-write operations. It is
* not thread safe as the resource is shared among multiple pins on a port.
*
*******************************************************************************/
cy_en_gpio_status_t Cy_GPIO_Pin_Init(GPIO_PRT_Type *base, uint32_t pinNum, const cy_stc_gpio_pin_config_t *config)
{
cy_en_gpio_status_t status = CY_GPIO_SUCCESS;
uint32_t maskCfgOut;
uint32_t tempReg;
if((NULL != base) && (NULL != config))
{
Cy_GPIO_Write(base, pinNum, config->outVal);
Cy_GPIO_SetDrivemode(base, pinNum, config->driveMode);
Cy_GPIO_SetHSIOM(base, pinNum, config->hsiom);
Cy_GPIO_SetInterruptEdge(base, pinNum, config->intEdge);
Cy_GPIO_SetInterruptMask(base, pinNum, config->intMask);
Cy_GPIO_SetVtrip(base, pinNum, config->vtrip);
/* Slew rate and Driver strength */
maskCfgOut = (CY_GPIO_CFG_OUT_SLOW_MASK << pinNum) | (CY_GPIO_CFG_OUT_DRIVE_SEL_MASK << (pinNum + CY_GPIO_CFG_OUT_DRIVE_OFFSET));
tempReg = base->CFG_OUT & ~(maskCfgOut);
base->CFG_OUT = tempReg | ((config->slewRate & CY_GPIO_CFG_OUT_SLOW_MASK) << pinNum)
| ((config->driveSel & CY_GPIO_CFG_OUT_DRIVE_SEL_MASK) << (pinNum + CY_GPIO_CFG_OUT_DRIVE_OFFSET));
/* SIO specific configuration */
tempReg = base->CFG_SIO & ~(CY_GPIO_SIO_PIN_MASK);
base->CFG_SIO = tempReg | (((config->vregEn & CY_GPIO_VREG_EN_MASK)
| ((config->ibufMode & CY_GPIO_IBUF_MASK) << CY_GPIO_IBUF_SHIFT)
| ((config->vtripSel & CY_GPIO_VTRIP_SEL_MASK) << CY_GPIO_VTRIP_SEL_SHIFT)
| ((config->vrefSel & CY_GPIO_VREF_SEL_MASK) << CY_GPIO_VREF_SEL_SHIFT)
| ((config->vohSel & CY_GPIO_VOH_SEL_MASK) << CY_GPIO_VOH_SEL_SHIFT))
<< ((pinNum & CY_GPIO_SIO_ODD_PIN_MASK) << CY_GPIO_CFG_SIO_OFFSET));
}
else
{
status = CY_GPIO_BAD_PARAM;
}
return(status);
}
/*******************************************************************************
* Function Name: Cy_GPIO_Port_Init
****************************************************************************//**
*
* \brief Initialize a complete port of pins from a single init structure.
*
* \param base
* Pointer to the pin's port register base address
*
* \param config
* Pointer to the pin config structure base address
*
* \return
* void
*
*******************************************************************************/
cy_en_gpio_status_t Cy_GPIO_Port_Init(GPIO_PRT_Type* base, const cy_stc_gpio_prt_config_t *config)
{
cy_en_gpio_status_t status = CY_GPIO_SUCCESS;
uint32_t portNum;
HSIOM_PRT_Type* baseHSIOM;
if((NULL != base) && (NULL != config))
{
portNum = ((uint32_t)(base) - GPIO_BASE) / GPIO_PRT_SECTION_SIZE;
baseHSIOM = (HSIOM_PRT_Type*)(HSIOM_BASE + (HSIOM_PRT_SECTION_SIZE * portNum));
base->OUT = config->out;
base->CFG = config->cfg;
base->CFG_IN = config->cfgIn;
base->CFG_OUT = config->cfgOut;
base->INTR_CFG = config->intrCfg;
base->INTR_MASK = config->intrMask;
base->CFG_SIO = config->cfgSIO;
baseHSIOM->PORT_SEL0 = config->sel0Active;
baseHSIOM->PORT_SEL1 = config->sel1Active;
}
else
{
status = CY_GPIO_BAD_PARAM;
}
return(status);
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,464 @@
/***************************************************************************//**
* \file
* \version 1.0
*
* \breif
* IPC Driver - This source file contains the low level driver code for
* the IPC hardware.
*
********************************************************************************
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_ipc_drv.h"
/*******************************************************************************
* Function Name: Cy_IPC_DRV_LockAcquire
****************************************************************************//**
*
* This function is used to acquire the IPC lock. The function acquires the lock corresponding to the ipcPtr passed.
*
* \param ipcPtr
* This parameter is a handle which represents the base address of the registers of the IPC channel.
* The parameter is generally returned from a call to the \ref Cy_IPC_DRV_GetIpcBaseAddress
*
* \return
* Status for the function:
* CY_IPC_DRV_SUCCESS: The IPC was successfully acquired
* CY_IPC_DRV_ERROR: The IPC was not acquired since it was already acquired by another master
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_DRV_LockAcquire (IPC_STRUCT_Type const * ipcPtr)
{
cy_en_ipcdrv_status_t retStatus;
if( 0ul != (IPC_STRUCT_ACQUIRE_SUCCESS_Msk & ipcPtr->ACQUIRE))
{
retStatus = CY_IPC_DRV_SUCCESS;
}
else
{
retStatus = CY_IPC_DRV_ERROR;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_DRV_GetLockStatus
****************************************************************************//**
*
* The function is used to read the lock status of an IPC channel. The function tells the reader if the IPC was in the locked or released state.
*
* \param ipcPtr
* This parameter is a handle which represents the base address of the registers of the IPC channel.
* The parameter is generally returned from a call to the \ref Cy_IPC_DRV_GetIpcBaseAddress
*
* \return
* Status for the function:
* CY_IPC_DRV_LOCKED: The IPC is in the Locked state
* CY_IPC_DRV_RELEASED: The IPC is in the Released state
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_DRV_GetLockStatus (IPC_STRUCT_Type const * ipcPtr)
{
cy_en_ipcdrv_status_t retStatus;
if( IPC_STRUCT_ACQUIRE_SUCCESS_Msk == (IPC_STRUCT_ACQUIRE_SUCCESS_Msk & ipcPtr->LOCK_STATUS) )
{
retStatus = CY_IPC_DRV_LOCKED;
}
else
{
retStatus = CY_IPC_DRV_RELEASED;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_DRV_Release
****************************************************************************//**
*
* The function is used to release an IPC from the locked state.
* The function also has a way to specify through a parameter, which IPC interrupts need to be notified during the release event.
*
* \param ipcPtr
* This parameter is a handle which represents the base address of the registers of the IPC channel.
* The parameter is generally returned from a call to the \ref Cy_IPC_DRV_GetIpcBaseAddress
*
* \param releaseEventIntr
* Bit encoded list of IPC interrupt lines that are triggered by a release event
*
* \return
* Status for the function:
* CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC was released
* CY_IPC_DRV_NOT_ACQUIRED: The IPC channel was not acquired before the function call.
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_DRV_Release (IPC_STRUCT_Type* ipcPtr, uint32_t releaseEventIntr)
{
cy_en_ipcdrv_status_t retStatus;
/* Check to make sure the IPC is Acquired */
if( IPC_STRUCT_ACQUIRE_SUCCESS_Msk == ( IPC_STRUCT_ACQUIRE_SUCCESS_Msk & ipcPtr->LOCK_STATUS) )
{
/* The IPC was acquired, release the IPC channel */
ipcPtr->RELEASE = (IPC_INTR_STRUCT_INTR_RELEASE_Msk & releaseEventIntr);
retStatus = CY_IPC_DRV_SUCCESS;
}
else /* The IPC channel was already released (not acquired) */
{
retStatus = CY_IPC_DRV_NOT_ACQUIRED;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_DRV_Notify
****************************************************************************//**
*
* The function generates a notify event to an IPC interrupt structure.
*
* \param ipcPtr
* This parameter is a handle which represents the base address of the registers of the IPC channel.
* The parameter is generally returned from a call to the \ref Cy_IPC_DRV_GetIpcBaseAddress
*
* \param notifyEventIntr
* Bit encoded list of IPC interrupt lines that are triggered by a notification
*
* \return
* void
*
*******************************************************************************/
void Cy_IPC_DRV_Notify (IPC_STRUCT_Type* ipcPtr, uint32_t notifyEventIntr)
{
ipcPtr->NOTIFY = (IPC_STRUCT_NOTIFY_INTR_NOTIFY_Msk & notifyEventIntr);
}
/*******************************************************************************
* Function Name: Cy_IPC_DRV_SendMsgWord
****************************************************************************//**
*
* This function is used to send a 32 bit word message through an IPC channel.
* The function also has an associated notification field that will let the message notify one or multiple IPC interrupts.
* The IPC channel is locked and remains locked after the function returns. The receiver
* of the message should release the channel.
*
* \param ipcPtr
* This parameter is a handle which represents the base address of the registers of the IPC channel.
* The parameter is generally returned from a call to the \ref Cy_IPC_DRV_GetIpcBaseAddress.
*
* \param notifyEventIntr
* Bit encoded list of IPC interrupt lines that are triggered by a notification.
*
* \param message
* The message word that is the data placed in the IPC data register.
*
* \return
* Status for the function:
* CY_IPC_DRV_SUCCESS: The send operation was successful
* CY_IPC_DRV_ERROR: The IPC channel is unavailable since it is already locked.
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_DRV_SendMsgWord (IPC_STRUCT_Type* ipcPtr, uint32_t notifyEventIntr, uint32_t message)
{
cy_en_ipcdrv_status_t retStatus;
if( CY_IPC_DRV_SUCCESS == Cy_IPC_DRV_LockAcquire(ipcPtr) )
{
/* If the channel was acquired, send the message. */
ipcPtr->DATA = message;
ipcPtr->NOTIFY = (IPC_STRUCT_NOTIFY_INTR_NOTIFY_Msk & notifyEventIntr);
retStatus = CY_IPC_DRV_SUCCESS;
}
else
{
/* Channel was already acquired, return Error */
retStatus = CY_IPC_DRV_ERROR;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_DRV_ReadMsgWord
****************************************************************************//**
*
* This function is used to read a 32 bit word message through an IPC channel.
* This function assumes that the channel is locked (in order for a valid message). If
* the channel is not locked the message is invalid. The user needs to call
* Cy_IPC_DRV_Release() function after reading the message, to release the lock.
*
* \param ipcPtr
* This parameter is a handle which represents the base address of the registers of the IPC channel.
* The parameter is generally returned from a call to the \ref Cy_IPC_DRV_GetIpcBaseAddress.
*
* \param message
* A variable where the read data is copied.
*
* \return
* Status for the function
* CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC was released.
* CY_IPC_DRV_ERROR: The function encountered an error since the IPC channel was already in a released state meaning the data may be invalid
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_DRV_ReadMsgWord (IPC_STRUCT_Type* ipcPtr, uint32_t * message)
{
cy_en_ipcdrv_status_t retStatus;
if( CY_IPC_DRV_LOCKED == Cy_IPC_DRV_GetLockStatus(ipcPtr) )
{
/* The channel is locked, message is valid. */
*message = ipcPtr->DATA;
retStatus = CY_IPC_DRV_SUCCESS;
}
else
{
/* The channel is not locked so channel is invalid. */
retStatus = CY_IPC_DRV_ERROR;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_DRV_SendMsgPtr
****************************************************************************//**
*
* This function is used to send a message pointer through an IPC channel.
* The message structure may hold a generic pointer which may contain the address of
* any user data type or structure. This parameter could be a pointer to a 32 bit integer, an
* array or even a data structure defined in the user code. This function acts
* as a transfer engine for sending the pointer. Any memory management of the pointer
* allocation and deallocation is up to the application code.
* The function also has an associated notification field that will let the message
* notify one or multiple interrupts.
*
* \param ipcPtr
* This parameter is a handle which represents the base address of the registers of the IPC channel.
* The parameter is generally returned from a call to the \ref Cy_IPC_DRV_GetIpcBaseAddress
*
* \param notifyEventIntr
* Bit encoded list of IPC interrupt lines that are triggered during the release action.
*
* \param msgPtr
* The message pointer that is being sent over the IPC channel
*
* \return
* Status for the function:
* CY_IPC_DRV_SUCCESS: The send operation was successful
* CY_IPC_DRV_ERROR: The IPC channel is unavailable since it is already locked
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_DRV_SendMsgPtr(IPC_STRUCT_Type* ipcPtr, uint32_t notifyEventIntr, void const * msgPtr)
{
cy_en_ipcdrv_status_t retStatus;
if( CY_IPC_DRV_SUCCESS == Cy_IPC_DRV_LockAcquire(ipcPtr) )
{
/* If the channel was acquired, send the message. */
ipcPtr->DATA = (uint32_t)msgPtr;
ipcPtr->NOTIFY = ((uint32_t)IPC_STRUCT_NOTIFY_INTR_NOTIFY_Msk & notifyEventIntr);
retStatus = CY_IPC_DRV_SUCCESS;
}
else
{
/* Chaneel was already acquired, Error */
retStatus = CY_IPC_DRV_ERROR;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_DRV_ReadMsgPtr
****************************************************************************//**
*
* This function is used to read a 32 bit pointer message through an IPC channel.
*
* \param ipcPtr
* This parameter is a handle which represents the base address of the registers of the IPC channel.
* The parameter is generally returned from a call to the \ref Cy_IPC_DRV_GetIpcBaseAddress
*
* \param msgPtr
* Pointer variable to hold the data pointer that is being read from the IPC channel
*
*
* \return
* Status for the function
* CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC was released
* CY_IPC_DRV_ERROR: The function encountered an error since the IPC channel was already in a released state meaning the data in it is invalid
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_DRV_ReadMsgPtr (IPC_STRUCT_Type* ipcPtr, void ** msgPtr)
{
cy_en_ipcdrv_status_t retStatus;
if( CY_IPC_DRV_LOCKED == Cy_IPC_DRV_GetLockStatus(ipcPtr) )
{
/* The channel is locked, message is valid. */
*msgPtr = (void *)(ipcPtr->DATA);
retStatus = CY_IPC_DRV_SUCCESS;
}
else
{
/* The channel is not locked so channel is invalid. */
retStatus = CY_IPC_DRV_ERROR;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_DRV_SetIntrMask
****************************************************************************//**
*
* This function is used to set the interrupt mask for an IPC Interrupt.
* The mask can be set for release or notification events of all available IPC ports.
*
* \param ipcIntrPtr
* This is a handle to the IPC interrupt. This handle can be calculated from the IPC interrupt number using \ref Cy_IPC_DRV_GetIntrBaseAddr
*
* \param ipcReleaseMask
* An encoded list of all IPC structures that can trigger the interrupt on a release event
*
* \param ipcNotifyMask
* An encoded list of all IPC structures that can trigger the interrupt on a notify event.
*
* \return
* void
*
*******************************************************************************/
void Cy_IPC_DRV_SetIntrMask (IPC_INTR_STRUCT_Type* ipcIntrPtr, uint32_t ipcReleaseMask, uint32_t ipcNotifyMask)
{
ipcIntrPtr->INTR_MASK = ( ipcNotifyMask << IPC_INTR_STRUCT_INTR_NOTIFY_Pos) | ( ipcReleaseMask & IPC_INTR_STRUCT_INTR_MASK_RELEASE_Msk);
}
/*******************************************************************************
* Function Name: Cy_IPC_DRV_GetIntrMask
****************************************************************************//**
*
* This function is used to read the interrupt mask.
* \param ipcIntrPtr
* This is a handle to the IPC interrupt. This handle can be calculated from the IPC interrupt number using \ref Cy_IPC_DRV_GetIntrBaseAddr
*
* \return
* The return value is encoded as follows
* <table>
* <tr><th>Interrupt sources <th>Value
* <tr><td>Ipc_PORTX_RELEASE <td>Xth bit set
* <tr><td>Ipc_PORTX_NOTIFY <td>X+16 th bit set
* </table>
*
*******************************************************************************/
uint32_t Cy_IPC_DRV_GetIntrMask(IPC_INTR_STRUCT_Type const * ipcIntrPtr)
{
return(ipcIntrPtr->INTR_MASK);
}
/*******************************************************************************
* Function Name: Cy_IPC_DRV_GetIntrStatusMasked
****************************************************************************//**
*
* This function is used to read the active unmasked interrupt. This function can be used in the interrupt service routine to
* find which source triggered the interrupt.
*
* \param ipcIntrPtr
* This is a handle to the IPC interrupt. This handle can be calculated from the IPC interrupt number using \ref Cy_IPC_DRV_GetIntrBaseAddr
*
* \return
* The return value is encoded as follows
* <table>
* <tr><th>Interrupt sources <th>Value
* <tr><td>Ipc_PORTX_RELEASE <td>Xth bit set
* <tr><td>Ipc_PORTX_NOTIFY <td>X+16 th bit set
* </table>
*
*******************************************************************************/
uint32_t Cy_IPC_DRV_GetIntrStatusMasked (IPC_INTR_STRUCT_Type const * ipcIntrPtr)
{
return(ipcIntrPtr->INTR_MASKED);
}
/*******************************************************************************
* Function Name: Cy_IPC_DRV_GetIntrStatus
****************************************************************************//**
*
* This function is used to read the pending interrupts. Note that this read is an unmasked read of the interrupt status
* Interrupt sources read as active by this function would generate interrupts only if they were not masked
* \param ipcIntrPtr
* This is a handle to the IPC interrupt. This handle can be calculated from the IPC interrupt number using \ref Cy_IPC_DRV_GetIntrBaseAddr
*
* \return
* The return value is encoded as follows
* <table>
* <tr><th>Interrupt sources <th>Value
* <tr><td>Ipc_PORTX_RELEASE <td>Xth bit set
* <tr><td>Ipc_PORTX_NOTIFY <td>X+16 th bit set
* </table>
*
*******************************************************************************/
uint32_t Cy_IPC_DRV_GetIntrStatus(IPC_INTR_STRUCT_Type const * ipcIntrPtr)
{
return(ipcIntrPtr->INTR);
}
/*******************************************************************************
* Function Name: Cy_IPC_DRV_SetIntr
****************************************************************************//**
*
* This function is used to set the interrupt source. This function can be used to activate interrupts through software.
* Note that interrupt sources set using this interrupt would generate interrupts only if they are not masked
*
* \param ipcIntrPtr
* This is a handle to the IPC interrupt. This handle can be calculated from the IPC interrupt number using \ref Cy_IPC_DRV_GetIntrBaseAddr
*
* \param ipcReleaseMask
* An encoded list of all IPC structures that can trigger the interrupt on a release event
*
* \param ipcNotifyMask
* An encoded list of all IPC structures that can trigger the interrupt on a notify event.
*
* \return
* void
*
*******************************************************************************/
void Cy_IPC_DRV_SetIntr(IPC_INTR_STRUCT_Type* ipcIntrPtr, uint32_t ipcReleaseMask, uint32_t ipcNotifyMask)
{
ipcIntrPtr->INTR_SET = (ipcNotifyMask << IPC_INTR_STRUCT_INTR_NOTIFY_Pos) | ( ipcReleaseMask & IPC_INTR_STRUCT_INTR_MASK_RELEASE_Msk) ;
}
/*******************************************************************************
* Function Name: Cy_IPC_DRV_ClearIntr
****************************************************************************//**
*
* This function is used to clear the interrupt source. Use this function to clear a pending interrupt source in the interrupt status
*
* \param ipcIntrPtr
* This is a handle to the IPC interrupt. This handle can be calculated from the IPC interrupt number using \ref Cy_IPC_DRV_GetIntrBaseAddr
*
* \param ipcReleaseMask
* An encoded list of all IPC structures that can trigger the interrupt on a release event
*
* \param ipcNotifyMask
* An encoded list of all IPC structures that can trigger the interrupt on a notify event.
*
* \return
* void
*
*******************************************************************************/
void Cy_IPC_DRV_ClearIntr(IPC_INTR_STRUCT_Type* ipcIntrPtr, uint32_t ipcReleaseMask, uint32_t ipcNotifyMask)
{
ipcIntrPtr->INTR = (ipcNotifyMask << IPC_INTR_STRUCT_INTR_NOTIFY_Pos) | ( ipcReleaseMask & IPC_INTR_STRUCT_INTR_MASK_RELEASE_Msk) ;
(void)ipcIntrPtr->INTR; /* Read the register to flush the cache */
}
/* [] END OF FILE */

View File

@ -0,0 +1,288 @@
/***************************************************************************//**
* \file cy_ipc_drv.h
* \version 1.0
*
* Provides an API declaration of the IPC driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#if !defined(CY_IPC_DRV_H)
#define CY_IPC_DRV_H
/**
* \defgroup group_ipc Inter Process Communication (IPC)
* \{
* Contains the driver API for low level IPC interface as well as Lock and Pipe
* upper level interfaces.
*
* The IPC driver provides a safe and reliable method to transfer data between
* CPUs or processes in a single device. Hardware locking provides a reliable
* method to ensure that only one device can acquire and transfer data at one
* time so no data is lost or over written by asynchronous processes or CPUs.
*
* The Lock functions made use of a single IPC channel to allow multiple locks
* that can be used by system or user function calls. By default there are
* 128 locks provided, although the user may modify the default value to any
* number, limited only by SRAM.
*
* The Pipe functions provide a method to transfer one or more words of data
* between CPUs or tasks. The data can be defined as a single 32-bit unsigned
* word, an array of data, or a user defined structure. The only limitation is
* that the first word in the array or structure must be a 32-bit unsigned word
* in which a client ID number is passed. The client ID dictates the callback
* function that will be called by the receiver of the message. After the
* callback function returns by the receiver, it will invoke a release callback
* function defined by the sender of the message.
*
* A User Pipe is provided for the user to transfer data between CPUs and
* tasks.
*
* \section group_ipc_configuration Configuration Considerations
*
* All IPC channels have been defined by the system. Users should not
* call any of the low level IPC functions. Only the Lock and Pipe functions
* are accessible by the user. The CyPipe is reserved for system level
* functions such as BLE and CapSense at this time.
*
* \section group_ipc_more_information More Information
*
* See TRM (Technical Reference Manual) for more information on IPC.
*
* \section group_ipc_MISRA MISRA-C Compliance
*
* <table class="doxtable">
* <tr>
* <th>MISRA Rule</th>
* <th>Rule Class (Required/Advisory)</th>
* <th>Rule Description</th>
* <th style="width: 50%;">Description of Deviation(s)</th>
* </tr>
* <tr>
* <td>8.8</td>
* <td>R</td>
* <td>An external object or function shall be declared in one and only one
* file.</td>
* <td>This rule is violated in the following files:
* cy_ipc_pipe.c, cy_ipc_lock.c, cy_ipc_config.c</td>
* </tr>
* <tr>
* <td>10.1</td>
* <td>R</td>
* <td>The value of an expression of integer type shall not be
* implicitly converted to a different underlying type.</td>
* <td>Implicit conversion from signed to unsigned is present in the
* following files: cy_ipc_pipe.c, cy_ipc_config.c</td>
* </tr>
* <tr>
* <td>11.4</td>
* <td>A</td>
* <td>A cast should not be performed between a pointer to object type
* and a different pointer to object type.</td>
* <td>In file cy_ipc_pipe.c, the message pointer is set to a void pointer
* because the message structure is defined by the user and is unknown.
* </td>
* </tr>
* <tr>
* <td>14.10</td>
* <td>R</td>
* <td>All if ... else if constructs shall be terminated with an else clause.
* </td>
* <td>In file cy_ipc_pipe.c this rule is violated intentionally and safely.
* </td>
* </tr>
* <tr>
* <td>16.7</td>
* <td>A</td>
* <td>A pointer parameter in a function prototype should be declared as
* pointer to const if the pointer is not used to modify the addressed
* object.</td>
* <td>In file cy_ipc_drv.c this rule is violated because the API
* implementation is expected in future to modify the parameter.</td>
* </tr>
* <tr>
* <td>16.9</td>
* <td>R</td>
* <td>A function identifier shall only be used with either a preceding &,
* or with a parenthesised parameter list, which may be empty.</td>
* <td>In file cy_ipc_config.c this rule is violated intentionally.</td>
* </tr>
* <tr>
* <td>16.10</td>
* <td>R</td>
* <td>If a function returns error information, then that error information
* shall be tested.</td>
* <td>In file cy_ipc_pipe.c this rule is violated intentionally.</td>
* </tr>
* </table>
*
* \section group_ipc_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_ipc_macro Macro
* \defgroup group_ipc_functions Functions
* \defgroup group_ipc_data_structures Data Structures
* \defgroup group_ipc_enums Enumerated Types
*
*/
/******************************************************************************/
/* Include files */
/******************************************************************************/
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
/**
* \addtogroup group_ipc_data_structures
* \{
*/
/** \} group_ipc_data_structures */
/**
* \addtogroup group_ipc_macro
* \{
*/
/** Driver major version */
#define CY_IPC_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_IPC_DRV_VERSION_MINOR 0
/* defined in the device.h */
/* Constants for ACQUIRE register */
#define CY_IPC_ACQ_NOT_ACQUIRED (uint32_t)(0x00000000ul) /**< Used to determine if lock was not acquired */
#define CY_IPC_NO_NOTIFIFICATION (uint32_t)(0x00000000ul) /**< Return value when no notifications have occurred or will be forced */
/* Error Code constants */
#define CY_IPC_ID CY_PDL_DRV_ID(0x22u) /**< Software PDL driver ID for IPC */
#define CY_IPC_ID_INFO (uint32_t)( CY_IPC_ID | CY_PDL_STATUS_INFO ) /**< Return prefix for IPC driver function status codes */
#define CY_IPC_ID_WARNING (uint32_t)( CY_IPC_ID | CY_PDL_STATUS_WARNING) /**< Return prefix for IPC driver function warning return values */
#define CY_IPC_ID_ERROR (uint32_t)( CY_IPC_ID | CY_PDL_STATUS_ERROR) /**< Return prefix for IPC driver function error return values */
/** \} group_ipc_macro */
/* end of definition in device.h */
/**
* \addtogroup group_ipc_enums
* \{
*/
/**
* This is a list of ENUMs used for function return status.
*/
typedef enum
{
CY_IPC_DRV_SUCCESS = 0x00u, /**< Function was successfully executed */
CY_IPC_DRV_ERROR = ( CY_IPC_ID_ERROR + 1ul), /**< Function was not executed due to an error. Typical conditions for the error explained in the function description */
CY_IPC_DRV_NOT_ACQUIRED = ( CY_IPC_ID_ERROR + 2ul), /**< IPC was not previously acquired */
CY_IPC_DRV_RELEASED = ( CY_IPC_ID_INFO + 0ul), /**< IPC was in a released state */
CY_IPC_DRV_LOCKED = ( CY_IPC_ID_INFO + 1ul) /**< IPC was in a locked/acquired state */
} cy_en_ipcdrv_status_t;
/** \} group_ipc_enums */
/******************************************************************************/
/* Global function prototypes (definition in C source) */
/******************************************************************************/
/**
* \addtogroup group_ipc_functions
* \{
*/
#ifdef __cplusplus
extern "C" {
#endif
cy_en_ipcdrv_status_t Cy_IPC_DRV_LockAcquire (IPC_STRUCT_Type const * ipcPtr);
cy_en_ipcdrv_status_t Cy_IPC_DRV_GetLockStatus (IPC_STRUCT_Type const * ipcPtr);
cy_en_ipcdrv_status_t Cy_IPC_DRV_Release (IPC_STRUCT_Type* ipcPtr, uint32_t releaseEventIntr);
void Cy_IPC_DRV_Notify (IPC_STRUCT_Type* ipcPtr, uint32_t notifyEventIntr);
cy_en_ipcdrv_status_t Cy_IPC_DRV_SendMsgWord (IPC_STRUCT_Type* ipcPtr, uint32_t notifyEventIntr, uint32_t message);
cy_en_ipcdrv_status_t Cy_IPC_DRV_ReadMsgWord (IPC_STRUCT_Type* ipcPtr, uint32_t * message);
cy_en_ipcdrv_status_t Cy_IPC_DRV_SendMsgPtr (IPC_STRUCT_Type* ipcPtr, uint32_t notifyEventIntr, void const * msgPtr);
cy_en_ipcdrv_status_t Cy_IPC_DRV_ReadMsgPtr (IPC_STRUCT_Type* ipcPtr, void** msgPtr);
void Cy_IPC_DRV_SetIntrMask (IPC_INTR_STRUCT_Type* ipcIntrPtr, uint32_t ipcReleaseMask, uint32_t ipcNotifyMask);
uint32_t Cy_IPC_DRV_GetIntrMask(IPC_INTR_STRUCT_Type const * ipcIntrPtr);
uint32_t Cy_IPC_DRV_GetIntrStatusMasked (IPC_INTR_STRUCT_Type const * ipcIntrPtr);
uint32_t Cy_IPC_DRV_GetIntrStatus(IPC_INTR_STRUCT_Type const * ipcIntrPtr);
void Cy_IPC_DRV_SetIntr(IPC_INTR_STRUCT_Type* ipcIntrPtr, uint32_t ipcReleaseMask, uint32_t ipcNotifyMask);
void Cy_IPC_DRV_ClearIntr(IPC_INTR_STRUCT_Type* ipcIntrPtr, uint32_t ipcReleaseMask, uint32_t ipcNotifyMask);
__STATIC_INLINE IPC_STRUCT_Type* Cy_IPC_DRV_GetIpcBaseAddress (uint32_t ipcIndex);
__STATIC_INLINE IPC_INTR_STRUCT_Type* Cy_IPC_DRV_GetIntrBaseAddr (uint32_t ipcIntrIndex);
/*******************************************************************************
* Function Name: Cy_IPC_DRV_GetIpcBaseAddress
****************************************************************************//**
*
* This function takes an IPC index as a parameter and returns the base address the IPC registers corresponding to the IPC channel.
* The function returns a zero value if the ipcIndex passed was invalid.
*
* \param ipcIndex
* Represents the hardware IPC index. This is converted to base address of the IPC channel registers.
*
* \return
* Returns a pointer to the base of the IPC registers. If the ipcIndex passed was invalid the function returns zero
*
*******************************************************************************/
__STATIC_INLINE IPC_STRUCT_Type* Cy_IPC_DRV_GetIpcBaseAddress (uint32_t ipcIndex)
{
CY_ASSERT((uint32_t)CPUSS_IPC_IPC_NR > ipcIndex);
return ( (IPC_STRUCT_Type*) ( &IPC->STRUCT[ipcIndex] ) );
}
/*******************************************************************************
* Function Name: Cy_IPC_DRV_GetIntrBaseAddr
****************************************************************************//**
*
* This function takes an IPC index and returns the base address of the IPC interrupt registers corresponding to the IPC Interrupt.
* The function returns a zero value if the ipcIntrIndex passed was invalid.
*
* \param ipcIntrIndex
* Represents the hardware IPC interrupt number. This is converted to the base address of the IPC interrupt registers.
*
* \return
* Returns a pointer to the base of the IPC interrupt registers. If the IpcIntIndex passed was invalid, the function returns zero
*
*******************************************************************************/
__STATIC_INLINE IPC_INTR_STRUCT_Type* Cy_IPC_DRV_GetIntrBaseAddr (uint32_t ipcIntrIndex)
{
CY_ASSERT((uint32_t)CPUSS_IPC_IPC_IRQ_NR > ipcIntrIndex);
return ( (IPC_INTR_STRUCT_Type*) ( &IPC->INTR_STRUCT[ipcIntrIndex] ) );
}
/** \} group_ipc_functions */
#ifdef __cplusplus
}
#endif
/** \} group_ipc */
#endif /* !defined(CY_IPC_DRV_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,268 @@
/***************************************************************************//**
* \file
* \version 1.0
*
* Description:
* IPC Lock Driver - This source file contains the source code for the lock
* level APIs for the IPC interface.
*
********************************************************************************
* Copyright2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_ipc_drv.h"
#include "cy_ipc_lock.h"
/* Assign the IPC structure used for Lock functions */
IPC_STRUCT_Type* CY_IPC_LOCK_Ptr = (IPC_STRUCT_Type*) &IPC->STRUCT[CY_IPC_CHAN_LOCK]; /**< Pointer to IPC structure used for locks */
struct CY_IPC_LOCK_STRUCT {
uint32_t maxLocks; /* Maximum locks in system */
uint32_t *arrayPtr; /* Pointer to lock array */
} CY_IPC_LOCK_data;
typedef struct CY_IPC_LOCK_STRUCT CY_IPC_LOCK_STRUCT;
/*******************************************************************************
* Function Name: Cy_IPC_LOCK_Init
****************************************************************************//**
*
* This function initializes the lock subsystem. The user must create an array of
* unsigned 32-bit words to hold the lock bits. The amount of locks will be
* the size of the array * 32. The total lock count will always be a multiple of 32.
* Note that only one of the CPUs in a multi-CPU system should call this
* init function and provide a pointer to SRAM that can be shared between all
* the CPUs in the system that will use locks.
*
* \param count
* The maximum number of locks to be supported (multiple of 32).
*
* \param memPtr
* This points to the array of (count/32) words that contain the lock data.
*
* \return
* CY_IPC_LOCK_SUCCESS: Sucessfully initialized
* CY_IPC_LOCK_INIT_ERROR: Init error, count value was zero, or greater than 31 and not a multiple of 32.
*
*
*******************************************************************************/
cy_en_ipclock_status_t Cy_IPC_LOCK_Init(uint32_t count, uint32_t memPtr[])
{
extern IPC_STRUCT_Type* CY_IPC_LOCK_Ptr;
cy_en_ipclock_status_t retStatus = CY_IPC_LOCK_INIT_ERROR;
uint32_t cnt;
CY_IPC_LOCK_data.maxLocks = count;
CY_IPC_LOCK_data.arrayPtr = memPtr;
/* Initialize all locks to released */
for(cnt= 0u ; cnt < (count/CY_IPC_LOCKS_PER_WORD); cnt++)
{
CY_IPC_LOCK_data.arrayPtr[cnt] = (uint32_t)0x00000000ul;
}
/* Make sure locks start out released */
(void) Cy_IPC_DRV_Release (CY_IPC_LOCK_Ptr, CY_IPC_NO_NOTIFIFICATION);
/* Set the IPC Data with the pointer to the array. */
if( CY_IPC_DRV_SUCCESS == Cy_IPC_DRV_SendMsgPtr (CY_IPC_LOCK_Ptr, CY_IPC_NO_NOTIFIFICATION, &CY_IPC_LOCK_data))
{
if(CY_IPC_DRV_SUCCESS == Cy_IPC_DRV_Release (CY_IPC_LOCK_Ptr, CY_IPC_NO_NOTIFIFICATION))
{
retStatus = CY_IPC_LOCK_SUCCESS;
}
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_LOCK_Acquire
****************************************************************************//**
*
* This functions tries to acquire a lock. If the lock is available, this
* function returns immediately with CY_IPC_LOCK_ERROR_NONE. If the lock is not
* available, this function returns immediately with CY_IPC_LOCK_ERROR_LOCKED.
*
* \param lockNumber
* The lock number to acquire.
*
* \return
* CY_IPC_LOCK_SUCCESS: The lock was acquired
* CY_IPC_LOCK_LOCKED: The lock channel is busy or locked by another process
* CY_IPC_LOCK_NOT_ACQUIRED: Lock was already acquired
* CY_IPC_LOCK_OUT_OF_RANGE: The lock number is not valid
*
*
*******************************************************************************/
cy_en_ipclock_status_t Cy_IPC_LOCK_Acquire(uint32_t lockNumber)
{
uint32_t lockIndex, lockMask;
cy_en_ipclock_status_t retStatus = CY_IPC_LOCK_LOCKED;
CY_IPC_LOCK_STRUCT *lockStructPtr;
/* Check to make sure the Lock channel is released */
/* If so, check is specific channel can be locked. */
if(CY_IPC_DRV_SUCCESS == Cy_IPC_DRV_LockAcquire (CY_IPC_LOCK_Ptr))
{
/* Get the index into the lock array and calculate the mask */
lockIndex = lockNumber / CY_IPC_LOCKS_PER_WORD;
lockMask = (0x00000001ul) << (lockNumber - (lockIndex * CY_IPC_LOCKS_PER_WORD) );
/* Get pointer to structure */
lockStructPtr = (CY_IPC_LOCK_STRUCT *)CY_IPC_LOCK_Ptr->DATA;
if(lockNumber < lockStructPtr->maxLocks)
{
if((lockStructPtr->arrayPtr[lockIndex] & lockMask) == (uint32_t)0)
{
lockStructPtr->arrayPtr[lockIndex] |= lockMask;
retStatus = CY_IPC_LOCK_SUCCESS;
}
else
{
retStatus = CY_IPC_LOCK_NOT_ACQUIRED;
}
}
else
{
retStatus = CY_IPC_LOCK_OUT_OF_RANGE;
}
/* Do not send an event on a lock acquire when the lock channel */
/* is released, since the lock was just acquired. */
(void) Cy_IPC_DRV_Release (CY_IPC_LOCK_Ptr, CY_IPC_NO_NOTIFIFICATION);
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_LOCK_Status
****************************************************************************//**
*
* This function returns the status of any given lock.
*
* \param lockNumber
* The index of the lock to return status.
*
* \return
* CY_IPC_LOCK_STATUS_LOCKED: The lock is in the acquired state. (return a 1)
* CY_IPC_LOCK_STATUS_UNLOCKED: The lock is in the released state. ( return 0)
* CY_IPC_LOCK_OUT_OF_RANGE: The lock number is not valid
*
*
*******************************************************************************/
cy_en_ipclock_status_t Cy_IPC_LOCK_Status(uint32_t lockNumber)
{
cy_en_ipclock_status_t retStatus;
uint32_t lockIndex, lockMask;
CY_IPC_LOCK_STRUCT *lockStructPtr;
lockStructPtr = (CY_IPC_LOCK_STRUCT *)CY_IPC_LOCK_Ptr->DATA;
if(lockNumber < lockStructPtr->maxLocks)
{
/* Get the index into the lock array and calculate the mask */
lockIndex = lockNumber / CY_IPC_LOCKS_PER_WORD;
lockMask = (0x00000001ul) << (lockNumber - (lockIndex * CY_IPC_LOCKS_PER_WORD) );
if((lockStructPtr->arrayPtr[lockIndex] & lockMask) != (uint32_t)0)
{
retStatus = CY_IPC_LOCK_STATUS_LOCKED;
}
else
{
retStatus = CY_IPC_LOCK_STATUS_UNLOCKED;
}
}
else
{
retStatus = CY_IPC_LOCK_OUT_OF_RANGE;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_LOCK_Release
****************************************************************************//**
*
* This functions tries to releases a lock.
*
* \param lockNumber
* The index of the lock in which to release.
*
* \return
* CY_IPC_LOCK_SUCCESS: The lock was released
* CY_IPC_LOCK_NOT_ACQUIRED: The lock was already released
* CY_IPC_LOCK_LOCKED: The lock channel was locked or busy
* CY_IPC_LOCK_OUT_OF_RANGE: The lock number is not valid
*
*
*******************************************************************************/
cy_en_ipclock_status_t Cy_IPC_LOCK_Release(uint32_t lockNumber)
{
uint32_t lockIndex, lockMask;
cy_en_ipclock_status_t retStatus = CY_IPC_LOCK_LOCKED;
CY_IPC_LOCK_STRUCT *lockStructPtr;
/* Check to make sure the Lock channel is released */
/* If so, check is specific channel can be locked. */
if(CY_IPC_DRV_SUCCESS == Cy_IPC_DRV_LockAcquire (CY_IPC_LOCK_Ptr))
{
lockIndex = lockNumber / CY_IPC_LOCKS_PER_WORD;
lockMask = (0x00000001ul) << (lockNumber - (lockIndex * CY_IPC_LOCKS_PER_WORD) );
/* Get pointer to structure */
lockStructPtr = (CY_IPC_LOCK_STRUCT *)CY_IPC_LOCK_Ptr->DATA;
if(lockNumber < lockStructPtr->maxLocks)
{
if((lockStructPtr->arrayPtr[lockIndex] & lockMask) != (uint32_t)0u)
{
lockStructPtr->arrayPtr[lockIndex] &= ~lockMask;
retStatus = CY_IPC_LOCK_SUCCESS;
}
else
{
retStatus = CY_IPC_LOCK_NOT_ACQUIRED;
}
}
else
{
retStatus = CY_IPC_LOCK_OUT_OF_RANGE;
}
/* Release, but do not trigger a release event */
(void) Cy_IPC_DRV_Release (CY_IPC_LOCK_Ptr, CY_IPC_NO_NOTIFIFICATION);
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_LOCK_GetMaxLocks
****************************************************************************//**
*
* This function returns the maximum lock count.
*
* \param
*
* \return
* Returns the maximum lock count as configured.
*
*
*******************************************************************************/
uint32_t Cy_IPC_LOCK_GetMaxLocks(void)
{
CY_IPC_LOCK_STRUCT *lockStructPtr;
lockStructPtr = (CY_IPC_LOCK_STRUCT *)CY_IPC_LOCK_Ptr->DATA;
return(lockStructPtr->maxLocks);
}
/* [] END OF FILE */

View File

@ -0,0 +1,84 @@
/***************************************************************************//**
* \file
* \version 1.0
*
* \brief
* Header file for IPC LOCK functions
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#ifndef _CY_IPC_LOCK_H_
#define _CY_IPC_LOCK_H_
/******************************************************************************/
/* Include files */
/******************************************************************************/
#include "cy_ipc_drv.h"
/**
* \addtogroup group_ipc_macro
* \{
*/
#define CY_IPC_LOCK_RTN 0x0100ul /**< Software PDL driver ID for IPC lock functions */
#define CY_IPC_LOCK_ID_INFO (uint32_t)( CY_IPC_ID_INFO | CY_IPC_LOCK_RTN) /**< Return prefix for IPC lock function status codes */
#define CY_IPC_LOCK_ID_WARNING (uint32_t)( CY_IPC_ID_WARNING | CY_IPC_LOCK_RTN) /**< Return prefix for IPC lock function warning return values */
#define CY_IPC_LOCK_ID_ERROR (uint32_t)( CY_IPC_ID_ERROR | CY_IPC_LOCK_RTN) /**< Return prefix for IPC lock function error return values */
/**< Return constants for IPC lock functions. */
typedef enum
{
CY_IPC_LOCK_SUCCESS = (uint32_t)0x00u, /**< No error has occured */
CY_IPC_LOCK_ERROR_LOCKED = (uint32_t)(CY_IPC_LOCK_ID_ERROR | 1ul), /**< Lock has already been locked */
CY_IPC_LOCK_ERROR_UNLOCKED = (uint32_t)(CY_IPC_LOCK_ID_ERROR | 2ul), /**< Lock is unlocked */
CY_IPC_LOCK_INIT_ERROR = (uint32_t)(CY_IPC_LOCK_ID_ERROR | 3ul), /**< Lock API return when the init function has failed */
CY_IPC_LOCK_OUT_OF_RANGE = (uint32_t)(CY_IPC_LOCK_ID_ERROR | 4ul), /**< Lock API return when lock is out of the range of valid locks */
CY_IPC_LOCK_NOT_ACQUIRED = (uint32_t)(CY_IPC_LOCK_ID_INFO | 2ul), /**< Lock API return when lock was not acquired */
CY_IPC_LOCK_LOCKED = (uint32_t)(CY_IPC_LOCK_ID_INFO | 3ul), /**< Lock API return status when lock was already locked */
CY_IPC_LOCK_STATUS_LOCKED = (uint32_t)(CY_IPC_LOCK_ID_INFO | 1ul), /**< Lock status return that the channel is locked */
CY_IPC_LOCK_STATUS_UNLOCKED = (uint32_t)(CY_IPC_LOCK_ID_INFO | 0ul) /**< Lock status return that the channel is unlocked */
} cy_en_ipclock_status_t;
#define CY_IPC_LOCKS_PER_WORD (uint32_t)32u /**< 32 locks per word */
/** \} group_ipc_macro */
/** \} group_ipc_data_structures */
/******************************************************************************/
/* Global function prototypes (definition in C source) */
/******************************************************************************/
/**
* \addtogroup group_ipc_functions
* \{
*/
#ifdef __cplusplus
extern "C" {
#endif
cy_en_ipclock_status_t Cy_IPC_LOCK_Init(uint32_t count, uint32_t mem_p[]);
cy_en_ipclock_status_t Cy_IPC_LOCK_Acquire(uint32_t lockNumber);
cy_en_ipclock_status_t Cy_IPC_LOCK_Release(uint32_t lockNumber);
cy_en_ipclock_status_t Cy_IPC_LOCK_Status(uint32_t lockNumber);
uint32_t Cy_IPC_LOCK_GetMaxLocks(void);
#ifdef __cplusplus
}
#endif
/** \} group_ipc_functions */
#endif /* _CY_IPC_LOCK_H_ */
/* [] END OF FILE */

View File

@ -0,0 +1,345 @@
/***************************************************************************//**
* \file
* \version 1.0
*
* Description:
* IPC Pipe Driver - This source file includes code for the Pipe layer on top
* of the IPC driver.
*
********************************************************************************
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_ipc_pipe.h"
/* Define a pointer to array of endPoints. */
cy_stc_ipc_pipe_ep_t * cy_ipc_pipe_epArray;
/*******************************************************************************
* Function Name: Cy_IPC_PIPE_Config
****************************************************************************//**
*
* This function stores a copy of a pointer to the array of endpoints. All
* access to endpoints will be via the index of the endpoint in this array.
*
* \param theEpArray
* This is the pointer to an array of endpoint structures that the designer
* created and will be used to reference all endpoints.
*
*
* \return
* void
*
*******************************************************************************/
void Cy_IPC_PIPE_Config(cy_stc_ipc_pipe_ep_t * theEpArray)
{
/* Keep copy of this endpoint */
cy_ipc_pipe_epArray = theEpArray;
}
/*******************************************************************************
* Function Name: Cy_IPC_PIPE_Init
****************************************************************************//**
*
* This function initializes the endpoint of a pipe for the current CPU. An
* endpoint of a pipe is IPC channel that receives a message for the current
* CPU. The current CPU is the CPU that is executing the code.
* After this function is called, the callbackArray needs to be populated
* with the callback functions for that endpoint using the Cy_IPC_PIPE_RegisterCallback()
* function.
*
* \param epAddr
* This parameter is the address (or index in the array of endpoint structure)
* that designates the endpoint in which you want to initialize.
*
* \param cbArray
* This is a pointer to the callback function array. Based on the client ID, one
* of the functions in this array is called to process the message.
*
* \param cbCnt
* This is the size of the callback array, or the number of defined clients.
*
* \param epConfig
* This value defines the IPC channel, IPC interrupt number, and the interrupt
* mask for the entire pipe.
* The format of the endPoint configuration
* Bits[31:16] Interrupt Mask
* Bits[15:8 ] IPC interrupt
* Bits[ 7:0 ] IPC channel
*
* \return
* void
*
*******************************************************************************/
void Cy_IPC_PIPE_Init(uint32_t epAddr, cy_ipc_pipe_callback_array_ptr_t cbArray, uint32_t cbCnt, uint32_t epConfig)
{
cy_stc_ipc_pipe_ep_t * endPoint;
endPoint = &cy_ipc_pipe_epArray[epAddr];
/* Extract the channel, interrupt and interrupt mask */
endPoint->ipcChan = (epConfig & CY_IPC_PIPE_CFG_CHAN_MASK) >> CY_IPC_PIPE_CFG_CHAN_SHIFT ;
endPoint->intrChan = (epConfig & CY_IPC_PIPE_CFG_INTR_MASK) >> CY_IPC_PIPE_CFG_INTR_SHIFT;
endPoint->pipeIntMask = (epConfig & CY_IPC_PIPE_CFG_IMASK_MASK) >> CY_IPC_PIPE_CFG_IMASK_SHIFT;
/* Assign IPC channel to this endpoint */
endPoint->ipcPtr = Cy_IPC_DRV_GetIpcBaseAddress (endPoint->ipcChan);
/* Assign interrupt structure to endpoint and Initialize the interrupt mask for this endpoint */
endPoint->ipcIntrPtr = Cy_IPC_DRV_GetIntrBaseAddr(endPoint->intrChan);
endPoint->ipcIntrPtr->INTR_MASK = endPoint->pipeIntMask | (endPoint->pipeIntMask << 16); /* Only allow notify and release interrupts */
/* from endpoints in this pipe. */
/* Save the Client count and the callback array pointer */
endPoint->clientCount = cbCnt;
endPoint->callbackArray = cbArray;
endPoint->busy = CY_IPC_PIPE_ENDPOINT_NOTBUSY;
}
/*******************************************************************************
* Function Name: Cy_IPC_PIPE_SendMessage
****************************************************************************//**
*
* This function is used to send a message from one endpoint to another. It
* generates an interrupt on the endpoint that receives the message and a
* release interrupt to the sender to acknowledge the message has been processed.
*
* \param toAddr
* This parameter is the address (or index in the array of endpoint structures)
* of the endpoint to which you are sending the message.
*
* \param fromAddr
* This parameter is the address (or index in the array of endpoint structures)
* of the endpoint to which the message is being sent.
*
* \param msgPtr
* Pointer to the message structure to be sent.
*
* \param callBackPtr
* Pointer to the Release callback function.
*
*
* \return
* CY_IPC_PIPE_SUCCESS: Message was sent to the other end of the pipe
* CY_IPC_PIPE_BAD_HANDLE: The handle provided for the pipe was not valid
* CY_IPC_PIPE_SEND_BUSY: The pipe is already busy sending a message
* CY_IPC_PIPE_DIR_ERROR: Tried to send on the "to" end of a unidirectional pipe
*******************************************************************************/
cy_en_ipc_pipe_status_t Cy_IPC_PIPE_SendMessage(uint32_t toAddr, uint32_t fromAddr, void * msgPtr, cy_ipc_pipe_relcallback_ptr_t callBackPtr)
{
cy_en_ipc_pipe_status_t returnStatus;
uint32_t releaseMask;
uint32_t notifyMask;
cy_stc_ipc_pipe_ep_t * fromEp;
cy_stc_ipc_pipe_ep_t * toEp;
toEp = &(cy_ipc_pipe_epArray[toAddr]);
fromEp = &cy_ipc_pipe_epArray[fromAddr];
/* Check if IPC channel valid */
if( toEp->ipcPtr != (void *)0u)
{
if(fromEp->busy == CY_IPC_PIPE_ENDPOINT_NOTBUSY)
{
/* Attempt to acquire the channel */
if( CY_IPC_DRV_SUCCESS == Cy_IPC_DRV_LockAcquire(toEp->ipcPtr) )
{
/* Create the release mask for the "fromAddr" channel's interrupt channel */
releaseMask = (0x0001 << fromEp->intrChan);
* (uint32_t *) msgPtr &= ~(CY_IPC_PIPE_MSG_RELEASE_MASK); /* Mask out the release mask area */
releaseMask = ((releaseMask << CY_IPC_PIPE_MSG_RELEASE_SHIFT) & CY_IPC_PIPE_MSG_RELEASE_MASK); /* shift into position */
* (uint32_t *) msgPtr |= releaseMask; /* OR in the release mask */
/* If the channel was acquired, write the message. */
toEp->ipcPtr->DATA = (uint32_t) msgPtr;
/* The last thing to do is create the notify event that causes the interrupt */
/* Create the notify mask for the "toAddr" channel's interrupt channel */
notifyMask = (0x0001 << toEp->intrChan);
fromEp->busy = CY_IPC_PIPE_ENDPOINT_BUSY; /* Set the busy flag. The ISR clears this after the release */
/* Setup release callback function */
fromEp->releaseCallbackPtr = callBackPtr; /* Set the callback function */
/* Cause notify event/interrupt */
toEp->ipcPtr->NOTIFY = (IPC_STRUCT_NOTIFY_INTR_NOTIFY_Msk & notifyMask);
returnStatus = CY_IPC_PIPE_SUCCESS;
}
else
{
/* Channel was already acquired, return Error */
returnStatus = CY_IPC_PIPE_ERROR_SEND_BUSY;
}
}
else
{
/* Channel may not be acquired, but the release interrupt has not executed yet */
returnStatus = CY_IPC_PIPE_ERROR_SEND_BUSY;
}
}
else
{
/* Null pipe handle. */
returnStatus = CY_IPC_PIPE_ERROR_BAD_HANDLE;
}
return(returnStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_PIPE_RegisterCallback
****************************************************************************//**
*
* This function registers a callback when a message is received on a pipe.
* The client_ID is the same as the index of the callback function array. The callback
* may be a real function pointer or NULL if no callback is required.
*
* \param epAddr
* This parameter is the address (or index in the array of endpoint structures)
* that designates the endpoint to which you want to add callback functions.
*
* \param callBackPtr
* Pointer to the callback function called when the endpoint has received a message.
*
* \param clientId
* The index in the callback array (Client ID) where the function pointer is saved.
*
*
* \return
* CY_IPC_PIPE_SUCCESS: Callback registered successfully
* CY_IPC_PIPE_ERROR_BAD_CLIENT: Client ID out of range, callback not registered.
*******************************************************************************/
cy_en_ipc_pipe_status_t Cy_IPC_PIPE_RegisterCallback(uint32_t epAddr, cy_ipc_pipe_callback_ptr_t callBackPtr, uint32_t clientId)
{
cy_en_ipc_pipe_status_t returnStatus; /* Return Status */
cy_stc_ipc_pipe_ep_t * thisEp;
thisEp = &cy_ipc_pipe_epArray[epAddr];
/* Check if clientId is between 0 and less than client count */
if(clientId <= thisEp->clientCount)
{
/* Copy callback function into callback function pointer array */
thisEp->callbackArray[clientId] = callBackPtr;
returnStatus = CY_IPC_PIPE_SUCCESS;
}
else
{
returnStatus = CY_IPC_PIPE_ERROR_BAD_CLIENT;
}
return(returnStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_PIPE_RegisterRecvCallbackRel
****************************************************************************//**
*
* This function registers a default callback if a release interrupt
* is generated but the current release callback function is null.
*
*
* \param epAddr
* This parameter is the address (or index in the array of endpoint structures)
* that designates the endpoint to which you want to add a release callback function.
*
* \param callBackPtr
* Pointer to the callback executed when the endpoint has received a message.
*
* \return
* None
*******************************************************************************/
void Cy_IPC_PIPE_RegisterCallbackRel(uint32_t epAddr, cy_ipc_pipe_relcallback_ptr_t callBackPtr)
{
cy_stc_ipc_pipe_ep_t * endPoint;
endPoint = &cy_ipc_pipe_epArray[epAddr];
/* Copy callback function into callback function pointer array */
endPoint->defaultReleaseCbPtr = callBackPtr;
}
/*******************************************************************************
* Function Name: Cy_IPC_PIPE_ExecCallback
****************************************************************************//**
*
* This function is called by the ISR for a given pipe endpoint to dispatch
* the appropriate callback function based on the client ID for that endpoint.
*
* \param endPoint
* Pointer to endpoint structure.
*
* \return
* None
*******************************************************************************/
void Cy_IPC_PIPE_ExecCallback(cy_stc_ipc_pipe_ep_t * endPoint)
{
uint32_t * msgPtr = (void *)0uL;
uint32_t clientID;
uint32_t shadowIntr;
uint32_t releaseMask = (uint32_t)0;
cy_ipc_pipe_callback_ptr_t callbackPtr;
/* Check to make sure the interrupt was a notify interrupt */
shadowIntr = endPoint->ipcIntrPtr->INTR_MASKED;
if( 0 != (shadowIntr & IPC_INTR_STRUCT_INTR_MASK_NOTIFY_Msk))
{
/* Clear the notify interrupt. */
endPoint->ipcIntrPtr->INTR = (shadowIntr & IPC_INTR_STRUCT_INTR_MASK_NOTIFY_Msk);
if( CY_IPC_DRV_LOCKED == Cy_IPC_DRV_GetLockStatus (endPoint->ipcPtr) )
{
/* Extract Client ID */
if( CY_IPC_DRV_SUCCESS == Cy_IPC_DRV_ReadMsgPtr (endPoint->ipcPtr, (void **)&msgPtr))
{
/* Get release mask */
releaseMask = (uint32_t)((*msgPtr & CY_IPC_PIPE_MSG_RELEASE_MASK) >> CY_IPC_PIPE_MSG_RELEASE_SHIFT);
clientID = *msgPtr & CY_IPC_PIPE_MSG_CLIENT_MASK;
/* Make sure client ID is within valid range */
if(endPoint->clientCount > clientID)
{
callbackPtr = endPoint->callbackArray[clientID]; /* Get the callback function */
if(callbackPtr != (void *)0)
{
callbackPtr(msgPtr); /* Call the function pointer for "clientID" */
}
}
}
/* Must always release the IPC channel */
Cy_IPC_DRV_Release (endPoint->ipcPtr, releaseMask);
}
}
/* Check to make sure the interrupt was a release interrupt */
if( 0 != (shadowIntr & IPC_INTR_STRUCT_INTR_MASK_RELEASE_Msk)) /* Check for a Release interrupt */
{
/* Clear the release callback function */
endPoint->ipcIntrPtr->INTR = (shadowIntr & IPC_INTR_STRUCT_INTR_MASK_RELEASE_Msk);
if(endPoint->releaseCallbackPtr != (void *)0)
{
endPoint->releaseCallbackPtr();
/* Clear the pointer after it was called */
endPoint->releaseCallbackPtr = (void *)0;
}
else if( endPoint->defaultReleaseCbPtr != (void *)0)
{
endPoint->defaultReleaseCbPtr();
}
/* Clear the busy flag when release is detected */
endPoint->busy = CY_IPC_PIPE_ENDPOINT_NOTBUSY;
}
(void)endPoint->ipcIntrPtr->INTR;
}
/* [] END OF FILE */

View File

@ -0,0 +1,191 @@
/***************************************************************************//**
* \file
* \version 1.0
*
* Description:
* IPC Pipe Driver - This header file contains all the function prototypes,
* structure definitions, pipe constants, and pipe endpoint address definitions.
*
* Warning: The API for the pipe level functions are preliminary and may change
* prior to release.
*
********************************************************************************
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#ifndef CY_IPC_PIPE_H
#define CY_IPC_PIPE_H
/******************************************************************************/
/* Include files */
/******************************************************************************/
#include "syslib/cy_syslib.h"
#include "cy_ipc_drv.h"
/*
* This section defines the system level constants required to define
* callback arrays for the Cypress pipe and the user pipe. These defines
* are used for both the max callback count and maximum clients.
*/
typedef void (* cy_ipc_pipe_callback_ptr_t)(uint32_t * msgPtr); /**< Typedef for pipe callback function pointer */
typedef void (* cy_ipc_pipe_relcallback_ptr_t)(void); /**< Typedef for a pipe release callback function pointer */
typedef void (** cy_ipc_pipe_callback_array_ptr_t)(uint32_t * msgPtr); /**< Typedef for array of callback function pointers */
/**
* \addtogroup group_ipc_macro
* \{
*/
/*
* The System pipe address is what is used to send a message to one of the
* endpoints of a pipe. Currently the Cypress pipe and the User pipe
* are supported. For parts with extra IPC channels users may create
* their own custom pipes and create their own pipe addresses.
*
* The format of the endPoint configuration
* Bits[31:16] Interrupt Mask
* Bits[15:8 ] IPC interrupt
* Bits[ 7:0 ] IPC channel
*/
#define CY_IPC_PIPE_CFG_IMASK_SHIFT (16UL) /**< Interrupt mask shift value for Pipe functions */
#define CY_IPC_PIPE_CFG_IMASK_MASK (0xFFFF0000UL) /**< Interrupt mask for endpoint address */
#define CY_IPC_PIPE_CFG_INTR_SHIFT (8UL) /**< Interrupt shift Pipe functions */
#define CY_IPC_PIPE_CFG_INTR_MASK (0x0000FF00UL) /**< Interrupt mask for endpoint address */
#define CY_IPC_PIPE_CFG_CHAN_SHIFT (0UL) /**< Interrupt shift Pipe functions */
#define CY_IPC_PIPE_CFG_CHAN_MASK (0x000000FFUL) /**< Pipe channel address for endpoint address */
#define CY_IPC_PIPE_MSG_CLIENT_MASK (0x000000FFul) /**< Client mask for first word of Pipe message */
#define CY_IPC_PIPE_MSG_USR_MASK (0x0000FF00ul) /**< User data mask for first word of Pipe message */
#define CY_IPC_PIPE_MSG_RELEASE_MASK (0xFFFF0000ul) /**< Mask for message release mask */
#define CY_IPC_PIPE_MSG_RELEASE_SHIFT (16UL) /**< Shift require to line up mask to LSb */
#define CY_IPC_PIPE_ENDPOINT_BUSY (1UL) /**< Use to set the busy flag when waiting for a release interrupt */
#define CY_IPC_PIPE_ENDPOINT_NOTBUSY (0UL) /**< Denotes that a release interrupt is not pending */
/** \} group_ipc_macro */
/**
* \addtogroup group_ipc_data_structures
* \{
*/
/*
* This is the definition of a pipe endpoint. There is one endpoint structure for each CPU in
* a pipe. It contains all the information to process a message sent from one of the other
* CPUs in the pipe.
*/
/**
* This is the definition of a pipe endpoint. There is one endpoint structure for each CPU in
* a pipe. It contains all the information to process a message send from one of the other
* CPUs in the pipe.
*/
typedef struct
{
uint32_t ipcChan; /**< IPC channel number used for this endpoint to receive messages */
uint32_t intrChan; /**< IPC interrupt channel number used for this endpoint to receive interrupts */
uint32_t pipeIntMask; /**< Release/Notify interrupt mask that includes all endpoints on pipe */
IPC_STRUCT_Type * ipcPtr; /**< Pointer to receive IPC channel ( If ptr == NULL, cannot receive ) */
IPC_INTR_STRUCT_Type * ipcIntrPtr; /**< Pointer to IPC interrupt, needed to clear the interrupt */
uint32_t busy; /**< Endpoint busy flag. If sent no messages can be sent from this endpoint */
uint32_t clientCount; /**< Client count and size of MsgCallback array */
cy_ipc_pipe_callback_array_ptr_t callbackArray; /**< Pointer to array of callback functions, one for each Client */
cy_ipc_pipe_relcallback_ptr_t releaseCallbackPtr; /**< Pointer to release callback function */
cy_ipc_pipe_relcallback_ptr_t defaultReleaseCbPtr; /**< Pointer to default release callback function */
} cy_stc_ipc_pipe_ep_t;
/** \} goup_ipc_data_structures */
/**
* \addtogroup group_ipc_macro
* \{
*/
/* Status and error types */
#define CY_IPC_PIPE_RTN 0x0200ul /**< Software PDL driver ID for IPC pipe functions */
#define CY_IPC_PIPE_ID_INFO (uint32_t)( CY_IPC_ID_INFO | CY_IPC_PIPE_RTN) /**< Return prefix for IPC pipe function status codes */
#define CY_IPC_PIPE_ID_WARNING (uint32_t)( CY_IPC_ID_WARNING | CY_IPC_PIPE_RTN) /**< Return prefix for IPC pipe function warning return values */
#define CY_IPC_PIPE_ID_ERROR (uint32_t)( CY_IPC_ID_ERROR | CY_IPC_PIPE_RTN) /**< Return prefix for IPC pipe function error return values */
/**< Return constants for IPC pipe functions. */
typedef enum
{
CY_IPC_PIPE_SUCCESS =(uint32_t)0x00u, /**< Pipe API return for no error */
CY_IPC_PIPE_ERROR_NO_IPC =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 1ul), /**< Pipe API return for no valid IPC channel */
CY_IPC_PIPE_ERROR_NO_INTR =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 2ul), /**< Pipe API return for no valid interrupt */
CY_IPC_PIPE_ERROR_BAD_PRIORITY =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 3ul), /**< Pipe API return for bad priority parameter */
CY_IPC_PIPE_ERROR_BAD_HANDLE =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 4ul), /**< Pipe API return for bad pipe handle */
CY_IPC_PIPE_ERROR_BAD_ID =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 5ul), /**< Pipe API return for bad pipe ID */
CY_IPC_PIPE_ERROR_DIR_ERROR =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 6ul), /**< Pipe API return for invalid direction (Not used at this time) */
CY_IPC_PIPE_ERROR_SEND_BUSY =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 7ul), /**< Pipe API return for pipe is currently busy */
CY_IPC_PIPE_ERROR_NO_MESSAGE =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 8ul), /**< Pipe API return for no message indicated */
CY_IPC_PIPE_ERROR_BAD_CPU =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 9ul), /**< Pipe API return for invalid CPU value */
CY_IPC_PIPE_ERROR_BAD_CLIENT =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 10ul) /**< Pipe API return for client out of range */
} cy_en_ipc_pipe_status_t;
/** \} group_ipc_macro */
/**
* \addtogroup group_ipc_data_structures
* \{
*/
/** \cond
* NOTE: This doxygen comment must be placed before some code entity, or else
* it will belong to a random entity that follows it, e.g. group_ipc_functions
*
* Client identifier for a message.
* For a given pipe, traffic across the pipe can be multiplexed with multiple
* senders on one end and multiple receivers on the other end.
*
* The first 32-bit word of the message is used to identify the client that owns
* the message.
*
* The upper 16 bits are the client ID.
*
* The lower 16 bits are for use by the client in any way desired.
*
* The lower 16 bits are preserved (not modified) and not interpreted in any way.
* \endcond
*/
/** \} group_ipc_data_structures */
/******************************************************************************/
/* Global function prototypes (definition in C source) */
/******************************************************************************/
/**
* \addtogroup group_ipc_functions
* \{
*/
#ifdef __cplusplus
extern "C" {
#endif
/* The API for the pipes level functions are preliminary and may change prior to release */
void Cy_IPC_PIPE_Init(uint32_t epAddr, cy_ipc_pipe_callback_array_ptr_t cbArray, uint32_t cbCnt, uint32_t epConfig);
cy_en_ipc_pipe_status_t Cy_IPC_PIPE_SendMessage(uint32_t toAddr, uint32_t fromAddr, void *msg_ptr, cy_ipc_pipe_relcallback_ptr_t callBack_ptr);
cy_en_ipc_pipe_status_t Cy_IPC_PIPE_RegisterCallback(uint32_t epAddr, cy_ipc_pipe_callback_ptr_t callBack_ptr, uint32_t clientID);
void Cy_IPC_PIPE_ExecCallback(cy_stc_ipc_pipe_ep_t * endPoint);
void Cy_IPC_PIPE_RegisterCallbackRel(uint32_t epAddr, cy_ipc_pipe_relcallback_ptr_t callBack_ptr);
void Cy_IPC_PIPE_Config(cy_stc_ipc_pipe_ep_t * theEpArray);
#ifdef __cplusplus
}
#endif
/** \} group_ipc_functions */
#endif /* _CY_IPC_PIPE_H_ */
/* [] END OF FILE */

View File

@ -0,0 +1,374 @@
/***************************************************************************//**
* \file cy_profile.c
* \version 1.0
*
* Provides an API implementation of the energy profiler (EP) driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_profile.h"
#include <string.h>
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/* # of elements in an array */
#define CY_N_ELMTS(a) (sizeof(a)/sizeof((a)[0]))
static uint32_t Cy_Profile_IsPtrValid(const cy_stc_profile_ctr_ptr_t ctrAddr);
/* control and status information for each counter */
static cy_stc_profile_ctr_t cy_ep_ctrs[PROFILE_PRFL_CNT_NR];
/* ========================================================================== */
/* ===================== LOCAL FUNCTIONS SECTION ====================== */
/* ========================================================================== */
/*******************************************************************************
* Function Name: Cy_Profile_IsPtrValid
****************************************************************************//**
*
* Local utility function: reports (1) whether or not a given pointer points into
* the cy_ep_ctrs[] array, and (2) whether the counter has been assigned.
*
* \param ctrAddr The handle to (address of) the assigned counter
*
* \return CY_PROFILE_SUCCESS, or CY_PROFILE_BAD_PARAM for invalid ctrAddr or counter not
* in use.
*
*******************************************************************************/
static uint32_t Cy_Profile_IsPtrValid(const cy_stc_profile_ctr_ptr_t ctrAddr)
{
uint32_t retVal = CY_PROFILE_BAD_PARAM;
/* check for valid ctrAddr */
uint32_t p_epCtrs = (uint32_t)cy_ep_ctrs;
if ((p_epCtrs <= (uint32_t)ctrAddr) && ((uint32_t)ctrAddr < (p_epCtrs + (uint32_t)sizeof(cy_ep_ctrs))))
{
if (ctrAddr->used != 0u) /* check for counter being used */
{
retVal = CY_PROFILE_SUCCESS;
}
}
return (retVal);
}
/* ========================================================================== */
/* ==================== INTERRUPT FUNCTION SECTION ==================== */
/* ========================================================================== */
/*******************************************************************************
* Function Name: Cy_Profile_ISR
****************************************************************************//**
*
* EP interrupt handler: Increments the overflow member of the counter structure,
* for each counter that is in use and has an overflow.
*
* This handler is not configured or used automatically. You must configure the
* interrupt handler for the EP, using Cy_SysInt_Init(). Typically you configure
* the system to use \ref Cy_Profile_ISR() as the overflow interrupt handler. You
* can provide a custom interrupt handler to perform additional operations if
* required. Your handler can call \ref Cy_Profile_ISR() to handle counter
* overflow.
*
*******************************************************************************/
void Cy_Profile_ISR(void)
{
uint32_t ctr;
/* Grab a copy of the overflow register. Each bit in the register indicates
whether or not the respective counter has overflowed. */
uint32_t ovflowBits = _FLD2VAL(PROFILE_INTR_MASKED_CNT_OVFLW, PROFILE->INTR_MASKED);
PROFILE->INTR = ovflowBits; /* clear the sources of the interrupts */
/* scan through the overflow bits, i.e., for each counter */
for (ctr = 0UL; (ctr < (uint32_t)(PROFILE_PRFL_CNT_NR)) && (ovflowBits != 0UL); ctr++)
{
/* Increment the overflow bit only if the counter is being used.
(Which should always be the case.) */
if (((ovflowBits & 1UL) != 0UL) && (cy_ep_ctrs[ctr].used != 0u))
{
cy_ep_ctrs[ctr].overflow++;
}
ovflowBits >>= 1; /* check the next bit, by shifting it into the LS position */
}
}
/* ========================================================================== */
/* ================== GENERAL EP FUNCTIONS SECTION ==================== */
/* ========================================================================== */
/*******************************************************************************
* Function Name: Cy_Profile_StartProfiling
****************************************************************************//**
*
* Starts profiling.
*
* \note Before calling this function, the user must enable the EP interrupt.
*******************************************************************************/
void Cy_Profile_StartProfiling(void)
{
uint32_t i;
/* clear all of the counter array overflow variables */
for (i = 0UL; i < CY_N_ELMTS(cy_ep_ctrs); cy_ep_ctrs[i++].overflow = 0UL){}
/* send the hardware command */
PROFILE->CMD = CY_PROFILE_START_TR;
}
/* ========================================================================== */
/* =================== COUNTER FUNCTIONS SECTION ====================== */
/* ========================================================================== */
/*******************************************************************************
* Function Name: Cy_Profile_ClearConfiguration
****************************************************************************//**
*
* Clears all counter configuration and sets all counters and overflow counters to 0.
* Calls Cy_Profile_ClearCounters() to clear counter registers.
*
*******************************************************************************/
void Cy_Profile_ClearConfiguration(void)
{
(void)memset((void *)cy_ep_ctrs, 0, sizeof(cy_ep_ctrs));
Cy_Profile_ClearCounters();
}
/*******************************************************************************
* Function Name: Cy_Profile_ConfigureCounter
****************************************************************************//**
*
* Assigns a given monitor source to a counter, and loads the CTL register
* bitfields of an assigned counter.
*
* \param monitor The monitor source #
*
* \param duration Events are monitored (0), or duration is monitored (1)
*
* \param refClk The reference clock to use; see \ref cy_en_profile_ref_clk_t.
* In general, it is recommended to use CY_PROFILE_CLK_HF to maximize resolution.
*
* \param weight Weighting factor for the counter value
*
* \return A pointer to the counter data structure. NULL if no counter is
* available.
*
* \note The counter is not enabled by this function. See functions
* \ref Cy_Profile_EnableCounter() and \ref Cy_Profile_DisableCounter(). See the
* Technical Reference Manual chapter on the EP for reference clock considerations.
*
*******************************************************************************/
cy_stc_profile_ctr_ptr_t Cy_Profile_ConfigureCounter(en_ep_mon_sel_t monitor, uint32_t duration,
cy_en_profile_ref_clk_t refClk, uint32_t weight)
{
cy_stc_profile_ctr_ptr_t retVal = NULL; /* error value if no counter is available */
volatile uint8_t i;
/* scan through the counters for an unused one */
for (i = 0u; (cy_ep_ctrs[i].used != 0u) && (i < CY_N_ELMTS(cy_ep_ctrs)); i++){}
if (i < CY_N_ELMTS(cy_ep_ctrs))
{ /* found one, fill in its data structure */
cy_ep_ctrs[i].ctrNum = i;
cy_ep_ctrs[i].used = 1u;
cy_ep_ctrs[i].cntAddr = (PROFILE_CNT_STRUCT_Type *)&(PROFILE->CNT_STRUCT[i]);
cy_ep_ctrs[i].ctlRegVals.cntDuration = (uint8_t)duration;
cy_ep_ctrs[i].ctlRegVals.refClkSel = refClk;
cy_ep_ctrs[i].ctlRegVals.monSel = monitor;
cy_ep_ctrs[i].overflow = 0UL;
cy_ep_ctrs[i].weight = weight;
/* pass back the handle to (address of) the counter data structure */
retVal = &cy_ep_ctrs[i];
/* Load the CTL register bitfields of the assigned counter. */
retVal->cntAddr->CTL =
_VAL2FLD(PROFILE_CNT_STRUCT_CTL_CNT_DURATION, retVal->ctlRegVals.cntDuration) |
_VAL2FLD(PROFILE_CNT_STRUCT_CTL_REF_CLK_SEL, retVal->ctlRegVals.refClkSel) |
_VAL2FLD(PROFILE_CNT_STRUCT_CTL_MON_SEL, retVal->ctlRegVals.monSel);
}
return (retVal);
}
/*******************************************************************************
* Function Name: Cy_Profile_FreeCounter
****************************************************************************//**
*
* Frees up a counter from a previously-assigned monitor source.
* \ref Cy_Profile_ConfigureCounter() must have been called for this counter before
* calling this function.
*
* \param ctrAddr The handle to (address of) the assigned counter, which is
* obtained by a call to \ref Cy_Profile_ConfigureCounter()
*
* \return \ref CY_PROFILE_SUCCESS, or \ref CY_PROFILE_BAD_PARAM for counter not in use.
*
* \note The counter is not disabled by this function. See functions
* \ref Cy_Profile_EnableCounter() and \ref Cy_Profile_DisableCounter().
*******************************************************************************/
uint32_t Cy_Profile_FreeCounter(cy_stc_profile_ctr_ptr_t ctrAddr)
{
uint32_t retVal = Cy_Profile_IsPtrValid(ctrAddr);
if (retVal == CY_PROFILE_SUCCESS)
{
ctrAddr->used = 0u;
}
return (retVal);
}
/*******************************************************************************
* Function Name: Cy_Profile_EnableCounter
****************************************************************************//**
*
* Enables an assigned counter. \ref Cy_Profile_ConfigureCounter() must have been
* called for this counter before calling this function.
*
* \param ctrAddr The handle to (address of) the assigned counter, which is
* obtained by a call to \ref Cy_Profile_ConfigureCounter()
*
* \return \ref CY_PROFILE_SUCCESS, or \ref CY_PROFILE_BAD_PARAM for counter not in use.
*
*******************************************************************************/
uint32_t Cy_Profile_EnableCounter(cy_stc_profile_ctr_ptr_t ctrAddr)
{
uint32_t retVal = Cy_Profile_IsPtrValid(ctrAddr);
if (retVal == CY_PROFILE_SUCCESS)
{
/* set the ENABLED bit */
ctrAddr->cntAddr->CTL |= _VAL2FLD(PROFILE_CNT_STRUCT_CTL_ENABLED, 1UL);
/* set the INTR_MASK bit for the counter being used */
PROFILE->INTR_MASK |= (1UL << (ctrAddr->ctrNum));
}
return (retVal);
}
/*******************************************************************************
* Function Name: Cy_Profile_DisableCounter
****************************************************************************//**
*
* Disables an assigned counter. \ref Cy_Profile_ConfigureCounter() must have been
* called for this counter before calling this function.
*
* \param ctrAddr The handle to (address of) the assigned counter, which is
* obtained by a call to \ref Cy_Profile_ConfigureCounter()
*
* \return \ref CY_PROFILE_SUCCESS, or \ref CY_PROFILE_BAD_PARAM for counter not in use.
*
*******************************************************************************/
uint32_t Cy_Profile_DisableCounter(cy_stc_profile_ctr_ptr_t ctrAddr)
{
uint32_t retVal = Cy_Profile_IsPtrValid(ctrAddr);
if (retVal == CY_PROFILE_SUCCESS)
{
/* clear the ENABLED bit */
ctrAddr->cntAddr->CTL &= ~(_VAL2FLD(PROFILE_CNT_STRUCT_CTL_ENABLED, 1UL));
/* clear the INTR_MASK bit for the counter being used */
PROFILE->INTR_MASK &= ~(1UL << (ctrAddr->ctrNum));
}
return (retVal);
}
/* ========================================================================== */
/* ================== CALCULATION FUNCTIONS SECTION =================== */
/* ========================================================================== */
/*******************************************************************************
* Function Name: Cy_Profile_GetRawCount
****************************************************************************//**
*
* Reports the count value for a specified counter.
*
* \param ctrAddr the handle to (address of) the assigned counter, which is
* obtained by a call to \ref Cy_Profile_ConfigureCounter()
*
* \param result the address to which to write the result
*
* \return \ref CY_PROFILE_SUCCESS, or \ref CY_PROFILE_BAD_PARAM for counter not in use.
*
*******************************************************************************/
uint32_t Cy_Profile_GetRawCount(cy_stc_profile_ctr_ptr_t ctrAddr, uint64_t *result)
{
uint32_t retVal = Cy_Profile_IsPtrValid(ctrAddr);
if (retVal == CY_PROFILE_SUCCESS)
{
/* read the counter control register, and the counter current value */
ctrAddr->ctlReg = ctrAddr->cntAddr->CTL;
ctrAddr->cntReg = ctrAddr->cntAddr->CNT;
/* report the count with overflow */
*result = ((uint64_t)(ctrAddr->overflow) << 32) | (uint64_t)(ctrAddr->cntReg);
}
return (retVal);
}
/*******************************************************************************
* Function Name: Cy_Profile_GetWeightedCount
****************************************************************************//**
*
* Reports the count value for a specified counter, multiplied by the weight
* factor set in \ref Cy_Profile_ConfigureCounter() for that counter.
*
* \param ctrAddr the handle to (address of) the assigned counter, which is
* obtained by a call to \ref Cy_Profile_ConfigureCounter()
*
* \param result the address to which to write the result
*
* \return \ref CY_PROFILE_SUCCESS, or \ref CY_PROFILE_BAD_PARAM for counter not in use.
*
*******************************************************************************/
uint32_t Cy_Profile_GetWeightedCount(cy_stc_profile_ctr_ptr_t ctrAddr, uint64_t *result)
{
uint64_t temp;
uint32_t retVal = Cy_Profile_GetRawCount(ctrAddr, &temp);
if (retVal == CY_PROFILE_SUCCESS)
{
/* calculate weighted count */
*result = temp * (uint64_t)(ctrAddr->weight);
}
return (retVal);
}
/*******************************************************************************
* Function Name: Cy_Profile_GetSumWeightedCounts
****************************************************************************//**
*
* Calls \ref Cy_Profile_GetWeightedCount() for all specified counters. Reports the sum
* across all valid counters.
*
* \param ptrsArray array of handles to (addresses of) assigned counters
*
* \param numCounters number of scanned elements in ptrsArray[]
*
* \return The sum
*
*******************************************************************************/
uint64_t Cy_Profile_GetSumWeightedCounts(const cy_stc_profile_ctr_ptr_t ptrsArray[],
uint32_t numCounters)
{
uint64_t daSum = (uint64_t)0ul;
uint64_t num;
uint32_t i;
for (i = 0ul; i < numCounters; i++)
{
/* ignore error reported by Ep_GetWeightedCount() */
if (Cy_Profile_GetWeightedCount(ptrsArray[i], &num) == CY_PROFILE_SUCCESS)
{
daSum += num;
}
}
return (daSum);
}
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/* [] END OF FILE */

View File

@ -0,0 +1,540 @@
/***************************************************************************//**
* \file cy_profile.h
* \version 1.0
*
* Provides an API declaration of the energy profiler (EP) driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_energy_profiler Energy Profiler (Profile)
* \{
*
* The energy profiler (EP) driver contains an API for configuring and using the
* energy profiler hardware. The profiler enables measurement of the relative
* amount of energy consumed by particular peripherals. Traditional energy
* profilers correlate energy consumption to the program counter, which helps you
* understand when power is consumed. The EP provides additional insight into the
* device so you can identify an asynchronous activity that causes energy
* consumption. In other words, the EP helps you understand where power is consumed.
*
* The EP does not measure or report actual energy consumption. It measures either
* clock cycles or the number of events that have occurred in the profiling window.
* To derive relative energy consumption for each source, you can multiply the
* absolute count (clock cycles or events) for that source by a coefficient.
*
* Many of the sources available for monitoring are asynchronous operations where
* the cause of energy consumption may be difficult to identify using external hardware.
*
* \section group_profile_configuration Configuration Considerations
*
* There is no PSoC Creator component for this peripheral. To use the profiler you
* include the header file and configure the counters by writing code and calling
* the Profiler API functions.
*
* At the highest level, you perform these tasks:
* - Initialize the profiling block
* - Set up the profiling interrupt
* - Configure, initialize, and enable the counters
* - Start and stop profiling
* - Get the results
* - Exit gracefully
*
* The EP manages a set of counters. For each counter you use, you assign the source
* you want monitored, a reference clock, and a coefficient used to calculate results.
* You can also get the raw count for any counter.
*
* Each counter is a 32-bit register that counts either a number of clock cycles,
* or a number of events. It is possible to overflow the 32-bit register. The
* firmware implements a 32-bit overflow counter. Combined with the 32-bit register,
* this gives you a 64-bit counter for each monitored source. The profiler generates
* an interrupt when an overflow occurs. You must configure the interrupt handler
* using Cy_SysInt_Init(). You can use Cy_Profile_ISR() as the interrupt handler. It
* increments the overflow counter for each profiling counter that is in use.
*
* See notes on individual function definitions.
*
* \section group_profile_more_information More Information
*
* See the EP chapter of the device technical reference manual (TRM).
*
* \section group_profile_MISRA MISRA-C Compliance
* <table class="doxtable">
* <tr>
* <th>MISRA Rule</th>
* <th>Rule Class (Required/Advisory)</th>
* <th>Rule Description</th>
* <th>Description of Deviation(s)</th>
* </tr>
* <tr>
* <td>10.1</td>
* <td>R</td>
* <td>The value of an expression of integer type shall not be implicitly converted to a different, underlying type
* if the expression is complex.</td>
* <td>Using a Cypress defined macro to access memory mapped objects.
* Checking that a function pointer points to within the correct memory region.
* Calculating address of register structure.</td>
* </tr>
* <tr>
* <td>10.5</td>
* <td>R</td>
* <td>If the bitwise operators ~ and << are applied to an operand of underlying type uint8 or uint16, the result
* shall be immediately cast to the underlying type of the operand.</td>
* <td>Using a Cypress-defined macro to access memory-mapped objects.</td>
* </tr>
* <tr>
* <td>11.5</td>
* <td>R</td>
* <td>Dangerous pointer cast results in loss of volatile qualification.</td>
* <td>Using a Cypress-defined macro to access memory-mapped objects.</td>
* </tr>
* <tr>
* <td>12.4</td>
* <td>R</td>
* <td>Right hand operand of '&&' or '||' is an expression with possible side effects.</td>
* <td>Function-like macros are used to achieve more efficient code.</td>
* </tr>
* <tr>
* <td>12.7</td>
* <td>R</td>
* <td>Bitwise operator applied to signed underlying type.</td>
* <td>Using a Cypress-defined macro to access memory-mapped objects.</td>
* </tr>
* <tr>
* <td>16.7</td>
* <td>A</td>
* <td>A pointer parameter can be of type 'pointer to const'.</td>
* <td>The pointer is cast for comparison purposes and thus can't be a const.</td>
* </tr>
* <tr>
* <td>19.7</td>
* <td>A</td>
* <td>A function shall be used in preference to a function-like macro.</td>
* <td>Function-like macros are used to achieve more efficient code.</td>
* </tr>
* </table>
*
* \section group_profile_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_profile_macro Macro
* \{
* \defgroup group_profile_macro_return Function return values
* \}
* \defgroup group_profile_functions Functions
* \{
* \defgroup group_profile_functions_interrupt Interrupt Functions
* \defgroup group_profile_functions_general General Functions
* \defgroup group_profile_functions_counter Counter Functions
* \defgroup group_profile_functions_calculation Calculation Functions
* \}
* \defgroup group_profile_data_structures Data Structures
* \defgroup group_profile_enums Enumerated Types
*/
#if !defined(CY_PROFILE_H)
#define CY_PROFILE_H
#include "cy_device_headers.h"
#include "syslib/cy_syslib.h"
#include <stddef.h>
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/** \addtogroup group_profile_macro
* \{
*/
/** Driver major version */
#define CY_PROFILE_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_PROFILE_DRV_VERSION_MINOR 0
/** Start profiling command for the CMD register */
#define CY_PROFILE_START_TR 1UL
/** Stop profiling command for the CMD register */
#define CY_PROFILE_STOP_TR 2UL
/** Command to clear all counter registers to 0 */
#define CY_PROFILE_CLR_ALL_CNT 0x100UL
/**
* \addtogroup group_profile_returns
* \{
* Specifies return values meaning
*/
/** Command completed with no errors */
#define CY_PROFILE_SUCCESS 0ul
/** Invalid function input parameter */
#define CY_PROFILE_BAD_PARAM 1ul
/** \} group_profile_returns */
/** \} group_profile_macro */
/**
* \addtogroup group_profile_enums
* \{
*/
/**
* The possible values for CTR register, REF_CLK_SEL bitfield. See the
* technical reference manual (TRM) for reference clock considerations.
*/
typedef enum
{
CY_PROFILE_CLK_TIMER = 0, /**< See SRSS register CLK_TIMER_CTL.TIMER_SEL */
CY_PROFILE_CLK_IMO = 1, /**< Internal main oscillator */
CY_PROFILE_CLK_ECO = 2, /**< External crystal oscillator */
CY_PROFILE_CLK_LF = 3, /**< See SRSS register CLK_SELECT.LFCLK_SEL */
CY_PROFILE_CLK_HF = 4, /**< See SRSS registers CLK_ROOT_SELECT[0].ROOT_MUX and CLK_ROOT_SELECT[0].ROOT_DIV */
CY_PROFILE_CLK_PERI = 5, /**< See CPUSS register CM0_CLOCK_CTL.PERI_INT_DIV */
} cy_en_profile_ref_clk_t;
/** \} group_profile_enums */
/**
* \addtogroup group_profile_data_structures
* \{
*/
/**
* EP counter control register structure. For each counter, holds the CTL register fields.
*/
typedef struct
{
uint8_t cntDuration; /**< 0 = events are monitored; 1 = duration is monitored */
cy_en_profile_ref_clk_t refClkSel; /**< The reference clock used by this counter; 3 bits */
en_ep_mon_sel_t monSel; /**< The monitor signal to be observed by this counter; # bits = PROFILE_CNT_STRUCT_PRFL_MONITOR_NR_LOG2 */
} cy_stc_profile_ctr_ctl_t;
/**
* Structure holding all information for an EP counter.
*/
typedef struct
{
uint8_t ctrNum; /**< hardware counter # */
uint8_t used; /**< used 0 = available, 1 = being used */
cy_stc_profile_ctr_ctl_t ctlRegVals; /**< counter CTL reg bitfield values */
PROFILE_CNT_STRUCT_Type * cntAddr; /**< base MMIO addr of counter registers */
uint32_t ctlReg; /**< also includes enabled/disabled status */
uint32_t cntReg; /**< current counter value */
uint32_t overflow; /**< this register and cntReg form a 64-bit counter value */
uint32_t weight; /**< counter weighting factor */
} cy_stc_profile_ctr_t;
/**
* Pointer to structure holding all information for an EP counter.
*/
typedef cy_stc_profile_ctr_t * cy_stc_profile_ctr_ptr_t;
/** \} group_profile_data_structures */
/**
* \addtogroup group_profile_functions
* \{
*/
/**
* \addtogroup group_profile_functions_interrupt
* \{
*/
/* ========================================================================== */
/* ==================== INTERRUPT FUNCTION SECTION ==================== */
/* ========================================================================== */
/*******************************************************************************
* Function Name: Cy_Profile_ISR
****************************************************************************//**
*
* EP interrupt handler: Increments the overflow member of the counter structure,
* for each counter that is in use and has an overflow.
*
* This handler is not configured or used automatically. You must configure the
* interrupt handler for the EP, using Cy_SysInt_Init(). Typically you configure
* the system to use \ref Cy_Profile_ISR() as the overflow interrupt handler. You
* can provide a custom interrupt handler to perform additional operations if
* required. Your handler can call \ref Cy_Profile_ISR() to handle counter
* overflow.
*
*******************************************************************************/
void Cy_Profile_ISR(void);
/** \} group_profile_functions_interrupt */
/**
* \addtogroup group_profile_functions_general
* \{
*/
/* ========================================================================== */
/* ================== GENERAL EP FUNCTIONS SECTION ==================== */
/* ========================================================================== */
/*******************************************************************************
* Function Name: Cy_Profile_Init
****************************************************************************//**
*
* Turns on the EP for profiling. It must be called once when energy profiling is
* desired. This does not start a profiling session. Use Cy_Profile_StartProfiling()
* to start a profiling session.
*
* \note Before calling this function, the user must configure the EP interrupt
* so that \ref Cy_Profile_ISR() is executed.
*******************************************************************************/
__STATIC_INLINE void Cy_Profile_Init(void)
{
PROFILE->CTL = _VAL2FLD(PROFILE_CTL_ENABLED, 1UL/*enabled */) |
_VAL2FLD(PROFILE_CTL_WIN_MODE, 0UL/*start/stop mode*/);
PROFILE->INTR_MASK = 0UL; /* clear all counter interrupt mask bits */
}
/*******************************************************************************
* Function Name: Cy_Profile_DeInit
****************************************************************************//**
*
* Turns off the EP. It should be called when energy profiling is no longer
* desired.
*
* \note When calling this function, the user should consider also unconfiguring
* the EP interrupt.
*******************************************************************************/
__STATIC_INLINE void Cy_Profile_DeInit(void)
{
PROFILE->CTL = _VAL2FLD(PROFILE_CTL_ENABLED, 0UL/*disabled */);
PROFILE->INTR_MASK = 0UL; /* clear all counter interrupt mask bits */
}
/*******************************************************************************
* Function Name: Cy_Profile_StartProfiling
****************************************************************************//**
*
* Starts profiling.
*
* \note Before calling this function, the user must enable the EP interrupt.
*******************************************************************************/
void Cy_Profile_StartProfiling(void);
/*******************************************************************************
* Function Name: Cy_Profile_StopProfiling
****************************************************************************//**
*
* Stops profiling.
*
* \note When calling this function, the user should also disable the EP
* interrupt.
*******************************************************************************/
__STATIC_INLINE void Cy_Profile_StopProfiling(void)
{
PROFILE->CMD = CY_PROFILE_STOP_TR;
}
/*******************************************************************************
* Function Name: Cy_Profile_IsProfiling
****************************************************************************//**
*
* Reports whether or not profiling is active.
*
* \return 0 = profiling is not active; 1 = profiling is active
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_Profile_IsProfiling(void)
{
return _FLD2VAL(PROFILE_STATUS_WIN_ACTIVE, PROFILE->STATUS);
}
/** \} group_profile_functions_general */
/**
* \addtogroup group_profile_functions_counter
* \{
*/
/* ========================================================================== */
/* =================== COUNTER FUNCTIONS SECTION ====================== */
/* ========================================================================== */
/*******************************************************************************
* Function Name: Cy_Profile_ClearConfiguration
****************************************************************************//**
*
* Clears all counter configuration and sets all counters and overflow counters to 0.
* Calls Cy_Profile_ClearCounters() to clear counter registers.
*
*******************************************************************************/
void Cy_Profile_ClearConfiguration(void);
/*******************************************************************************
* Function Name: Cy_Profile_ClearCounters
****************************************************************************//**
*
* Clears all hardware counters to 0.
*
*******************************************************************************/
__STATIC_INLINE void Cy_Profile_ClearCounters(void)
{
PROFILE->CMD = CY_PROFILE_CLR_ALL_CNT;
}
/*******************************************************************************
* Function Name: Cy_Profile_ConfigureCounter
****************************************************************************//**
*
* Assigns a given monitor source to a counter, and loads the CTL register
* bitfields of an assigned counter.
*
* \param monitor The monitor source #
*
* \param duration Events are monitored (0), or duration is monitored (1)
*
* \param refClk The reference clock to use; see \ref cy_en_profile_ref_clk_t.
* In general, you should use CY_PROFILE_CLK_HF to maximize resolution.
*
* \param weight Weighting factor for the counter value
*
* \return A pointer to the counter data structure. NULL if no counter is
* available.
*
* \note The counter is not enabled by this function. See functions
* \ref Cy_Profile_EnableCounter() and \ref Cy_Profile_DisableCounter(). See the
* technical reference manual (TRM) chapter on the EP for reference clock considerations.
*
*******************************************************************************/
cy_stc_profile_ctr_ptr_t Cy_Profile_ConfigureCounter(en_ep_mon_sel_t monitor, uint32_t duration,
cy_en_profile_ref_clk_t refClk, uint32_t weight);
/*******************************************************************************
* Function Name: Cy_Profile_FreeCounter
****************************************************************************//**
*
* Frees up a counter from a previously-assigned monitor source.
* \ref Cy_Profile_ConfigureCounter() must have been called for this counter before
* calling this function.
*
* \param ctrAddr The handle to (address of) the assigned counter, which is
* obtained by a call to \ref Cy_Profile_ConfigureCounter().
*
* \return \ref CY_PROFILE_SUCCESS, or \ref CY_PROFILE_BAD_PARAM for counter not in use.
*
* \note The counter is not disabled by this function. See functions
* \ref Cy_Profile_EnableCounter() and \ref Cy_Profile_DisableCounter().
*******************************************************************************/
uint32_t Cy_Profile_FreeCounter(cy_stc_profile_ctr_ptr_t ctrAddr);
/*******************************************************************************
* Function Name: Cy_Profile_EnableCounter
****************************************************************************//**
*
* Enables an assigned counter. \ref Cy_Profile_ConfigureCounter() must have been
* called for this counter before calling this function.
*
* \param ctrAddr The handle to (address of) the assigned counter, which is
* obtained by a call to \ref Cy_Profile_ConfigureCounter().
*
* \return \ref CY_PROFILE_SUCCESS, or \ref CY_PROFILE_BAD_PARAM for counter not in use.
*
*******************************************************************************/
uint32_t Cy_Profile_EnableCounter(cy_stc_profile_ctr_ptr_t ctrAddr);
/*******************************************************************************
* Function Name: Cy_Profile_DisableCounter
****************************************************************************//**
*
* Disables an assigned counter. \ref Cy_Profile_ConfigureCounter() must have been
* called for this counter before calling this function.
*
* \param ctrAddr The handle to (address of) the assigned counter, which is
* obtained by a call to \ref Cy_Profile_ConfigureCounter().
*
* \return \ref CY_PROFILE_SUCCESS, or \ref CY_PROFILE_BAD_PARAM for counter not in use.
*
*******************************************************************************/
uint32_t Cy_Profile_DisableCounter(cy_stc_profile_ctr_ptr_t ctrAddr);
/** \} group_profile_functions_counter */
/**
* \addtogroup group_profile_functions_calculation
* \{
*/
/* ========================================================================== */
/* ================== CALCULATION FUNCTIONS SECTION =================== */
/* ========================================================================== */
/*******************************************************************************
* Function Name: Cy_Profile_GetRawCount
****************************************************************************//**
*
* Reports the count value for a specified counter.
*
* \param ctrAddr the handle to (address of) the assigned counter, which is
* obtained by a call to \ref Cy_Profile_ConfigureCounter().
*
* \param result The address to which to write the result.
*
* \return \ref CY_PROFILE_SUCCESS, or \ref CY_PROFILE_BAD_PARAM for counter not in use.
*
*******************************************************************************/
uint32_t Cy_Profile_GetRawCount(cy_stc_profile_ctr_ptr_t ctrAddr, uint64_t *result);
/*******************************************************************************
* Function Name: Cy_Profile_GetWeightedCount
****************************************************************************//**
*
* Reports the count value for a specified counter, multiplied by the weight
* factor set in \ref Cy_Profile_ConfigureCounter() for that counter.
*
* \param ctrAddr the handle to (address of) the assigned counter, which is
* obtained by a call to \ref Cy_Profile_ConfigureCounter().
*
* \param result The address to which to write the result.
*
* \return \ref CY_PROFILE_SUCCESS, or \ref CY_PROFILE_BAD_PARAM for counter not in use.
*
*******************************************************************************/
uint32_t Cy_Profile_GetWeightedCount(cy_stc_profile_ctr_ptr_t ctrAddr, uint64_t *result);
/*******************************************************************************
* Function Name: Cy_Profile_GetSumWeightedCounts
****************************************************************************//**
*
* Calls \ref Cy_Profile_GetWeightedCount() for all specified counters. Reports the sum
* across all valid counters.
*
* \param ptrsArray Array of handles to (addresses of) assigned counters
*
* \param numCounters Number of scanned elements in ptrsArray[]
*
* \return The sum
*
*******************************************************************************/
uint64_t Cy_Profile_GetSumWeightedCounts(const cy_stc_profile_ctr_ptr_t ptrsArray[],
uint32_t numCounters);
/** \} group_profile_functions_calculation */
/** \} group_profile_functions */
#if defined(__cplusplus)
}
#endif /* __cplusplus */
#endif /* CY_PROFILE_H */
/** \} group_profile */
/* [] END OF FILE */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,558 @@
/***************************************************************************//**
* \file cy_prot.h
* \version 1.0
*
* \brief
* Provides an API declaration of the Protection Unit driver
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_prot Protection Unit (Prot)
* \{
*
* The Protection Unit driver provides an API to configure the Memory Protection
* Units (MPU), Shared Memory Protection Units (SMPU), and Peripheral Protection
* Units (PPU). These are separate from the ARM Core MPUs and provide additional
* mechanisms for securing resource accesses. The Protection units address the
* following concerns in an embedded design:
* - Security requirements. This includes the prevention of malicious attacks
* to access secure memory or peripherals.
* - Safety requirements. This includes detection of accidental (non-malicious)
* SW errors and random HW errors. It is important to enable failure analysis
* to investigate the root cause of a safety violation.
*
* \n
* <b> Memory Protection </b>
*
* Memory protection is provided by MPUs and SMPUs and allows control of
* memory accesses by bus masters (e.g., CM0+, CM4, Crypto):
* - MPUs are used to distinguish user and privileged accesses from a single bus
* master such as task switching in an OS/kernel. For ARM core MPUs, the
* assigned Cypress MPUs for those cores provide additional functionality
* such as protection contexts (PC) and security attributes.
* - SMPUs are used to distinguish memory accesses between bus masters. This is
* achieved by using protection contexts and secure-/non-secure attributes.
*
* \n
* <b> Peripheral Protection </b>
*
* Peripheral protection is provided by PPUs and allows control of peripheral
* register accesses by bus masters. Four types of PPUs are available.
* - Programmable (PROG) PPUs are used to protect any peripheral memory region
* in a device from invalid bus master accesses. It is the most versatile
* type of peripheral protection unit.
* - Fixed Group (GR) PPUs are used to protect an entire peripheral MMIO group
* from invalid bus master accesses. The MMIO grouping information and which
* resource belongs to which group is device specific and can be obtained
* from the device technical reference manual (TRM).
* - Fixed Region (RG) PPUs are used to protect an entire peripheral slave
* instance from invalid bus master accesses. For example, TCPWM0, TCPWM1,
* SCB0, and SCB1, etc.
* - Fixed Slave (SL) PPUs are used to protect specified regions of peripheral
* instances. For example, individual DW channel structs, SMPU structs, and
* IPC structs, etc.
*
* \n
* <b> Driver Usage </b>
*
* Each protection unit is distinguished by its type (e.g.
* PROT_MPU_MPU_STRUCT_Type). The list of supported protection units can be
* obtained from the device header file. Choose a protection unit of interest,
* and call its corresponding Cy_Prot_Config<X>Struct() function with its
* software protection unit configuration structure populated. Then enable the
* protection unit by calling the Cy_Prot_Enable<X>Struct() function.
*
* Each bus master can be configured to allow/disallow certain types of accesses
* by calling the Cy_Prot_ConfigBusMaster() function. For example, CM0+ core
* is a bus master. By configuring it to allow only protection contexts (PC)
* 2 and 3, the bus master will be able to set its protection context only to
* 2 or 3. In a thread execution, the CM0+ core can set its protection context
* to 2 by calling Cy_Prot_SetActivePC() and access all regions of memory that
* allow PC=2. A fault will be triggered if a resource is protected with different
* protection settings.
*
* \section group_prot_configuration Configuration Considerations
*
* With the exception of MPUs, Protection structures are implemented in
* hardware as master and slave pairs. The master protection structure protects
* the slave protection structure. The slave protection structure protects the
* memory region that is to be protected.
* For example, a slave protection structure is configured to allow protection
* contexts 3 and 4 to access a set of peripheral registers. The corresponding
* master protection structure can then be used to protect the slave structure
* configuration and allow only protection context 1 to make modifications.
* Any bus master attempting to change the slave protection structure must then
* have a protection context 1. Otherwise an access fault will occur.
*
* \section group_prot_more_information More Information
*
* Refer to Technical Reference Manual (TRM) and the device datasheet.
*
* \section group_prot_MISRA MISRA-C Compliance]
* <table class="doxtable">
* <tr>
* <th>MISRA rule</th>
* <th>Rule Class (Required/Advisory)</th>
* <th>Rule Description</th>
* <th>Description of Deviation(s)</th>
* </tr>
* <tr>
* <td>11.5</td>
* <td>R</td>
* <td>Dangerous pointer cast results in loss of volatile qualification.</td>
* <td>Required to access bus master control register</td>
* </tr>
* </table>
*
* \section group_prot_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_prot_macro Macro
* \defgroup group_prot_functions Functions
* \{
* \defgroup group_prot_functions_busmaster Bus Master and PC Functions
* \defgroup group_prot_functions_mpu MPU Functions
* \defgroup group_prot_functions_smpu SMPU Functions
* \defgroup group_prot_functions_ppu_prog PPU Programmable (PROG) Functions
* \defgroup group_prot_functions_ppu_gr PPU Group (GR) Functions
* \defgroup group_prot_functions_ppu_sl PPU Slave (SL) Functions
* \defgroup group_prot_functions_ppu_rg PPU Region (RG) Functions
* \}
* \defgroup group_prot_data_structures Data structures
* \defgroup group_prot_enums Enumerated types
*/
#if !defined(__CY_PROT_H__)
#define __CY_PROT_H__
#include <stdbool.h>
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
#if defined(__cplusplus)
extern "C" {
#endif
/** \addtogroup group_prot_macro
* \{
*/
/** Driver major version */
#define CY_PROT_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_PROT_DRV_VERSION_MINOR 0
/** Prot driver ID */
#define CY_PROT_ID CY_PDL_DRV_ID(0x30u)
/** \} group_prot_macro */
/**
* \addtogroup group_prot_enums
* \{
*/
/**
* Prot Driver error codes
*/
typedef enum
{
CY_PROT_SUCCESS = 0x00u, /**< Returned successful */
CY_PROT_BAD_PARAM = CY_PROT_ID | CY_PDL_STATUS_ERROR | 0x01u, /**< Bad parameter was passed */
CY_PROT_FAILURE = CY_PROT_ID | CY_PDL_STATUS_ERROR | 0x03u /**< The resource is locked */
} cy_en_prot_status_t;
/**
* User/Privileged permission
*/
typedef enum
{
CY_PROT_PERM_DISABLED = 0x00u, /**< Read, Write and Execute disabled */
CY_PROT_PERM_R = 0x01u, /**< Read enabled */
CY_PROT_PERM_W = 0x02u, /**< Write enabled */
CY_PROT_PERM_RW = 0x03u, /**< Read and Write enabled */
CY_PROT_PERM_X = 0x04u, /**< Execute enabled */
CY_PROT_PERM_RX = 0x05u, /**< Read and Execute enabled */
CY_PROT_PERM_WX = 0x06u, /**< Write and Execute enabled */
CY_PROT_PERM_RWX = 0x07u /**< Read, Write and Execute enabled */
}cy_en_prot_perm_t;
/**
* Memory region size
*/
typedef enum
{
CY_PROT_SIZE_256B = 7u, /**< 256 bytes */
CY_PROT_SIZE_512B = 8u, /**< 512 bytes */
CY_PROT_SIZE_1KB = 9u, /**< 1 Kilobyte */
CY_PROT_SIZE_2KB = 10u, /**< 2 Kilobytes */
CY_PROT_SIZE_4KB = 11u, /**< 4 Kilobytes */
CY_PROT_SIZE_8KB = 12u, /**< 8 Kilobytes */
CY_PROT_SIZE_16KB = 13u, /**< 16 Kilobytes */
CY_PROT_SIZE_32KB = 14u, /**< 32 Kilobytes */
CY_PROT_SIZE_64KB = 15u, /**< 64 Kilobytes */
CY_PROT_SIZE_128KB = 16u, /**< 128 Kilobytes */
CY_PROT_SIZE_256KB = 17u, /**< 256 Kilobytes */
CY_PROT_SIZE_512KB = 18u, /**< 512 Kilobytes */
CY_PROT_SIZE_1MB = 19u, /**< 1 Megabyte */
CY_PROT_SIZE_2MB = 20u, /**< 2 Megabytes */
CY_PROT_SIZE_4MB = 21u, /**< 4 Megabytes */
CY_PROT_SIZE_8MB = 22u, /**< 8 Megabytes */
CY_PROT_SIZE_16MB = 23u, /**< 16 Megabytes */
CY_PROT_SIZE_32MB = 24u, /**< 32 Megabytes */
CY_PROT_SIZE_64MB = 25u, /**< 64 Megabytes */
CY_PROT_SIZE_128MB = 26u, /**< 128 Megabytes */
CY_PROT_SIZE_256MB = 27u, /**< 256 Megabytes */
CY_PROT_SIZE_512MB = 28u, /**< 512 Megabytes */
CY_PROT_SIZE_1GB = 29u, /**< 1 Gigabyte */
CY_PROT_SIZE_2GB = 30u, /**< 2 Gigabytes */
CY_PROT_SIZE_4GB = 31u /**< 4 Gigabytes */
}cy_en_prot_size_t;
/**
* Protection Context (PC)
*/
enum cy_en_prot_pc_t
{
CY_PROT_PC1 = 1u, /**< PC = 1 */
CY_PROT_PC2 = 2u, /**< PC = 2 */
CY_PROT_PC3 = 3u, /**< PC = 3 */
CY_PROT_PC4 = 4u, /**< PC = 4 */
CY_PROT_PC5 = 5u, /**< PC = 5 */
CY_PROT_PC6 = 6u, /**< PC = 6 */
CY_PROT_PC7 = 7u, /**< PC = 7 */
CY_PROT_PC8 = 8u, /**< PC = 8 */
CY_PROT_PC9 = 9u, /**< PC = 9 */
CY_PROT_PC10 = 10u, /**< PC = 10 */
CY_PROT_PC11 = 11u, /**< PC = 11 */
CY_PROT_PC12 = 12u, /**< PC = 12 */
CY_PROT_PC13 = 13u, /**< PC = 13 */
CY_PROT_PC14 = 14u, /**< PC = 14 */
CY_PROT_PC15 = 15u /**< PC = 15 */
};
/**
* Subregion disable (0-7)
*/
enum cy_en_prot_subreg_t
{
CY_PROT_SUBREGION_DIS0 = 0x01u, /**< Disable subregion 0 */
CY_PROT_SUBREGION_DIS1 = 0x02u, /**< Disable subregion 1 */
CY_PROT_SUBREGION_DIS2 = 0x04u, /**< Disable subregion 2 */
CY_PROT_SUBREGION_DIS3 = 0x08u, /**< Disable subregion 3 */
CY_PROT_SUBREGION_DIS4 = 0x10u, /**< Disable subregion 4 */
CY_PROT_SUBREGION_DIS5 = 0x20u, /**< Disable subregion 5 */
CY_PROT_SUBREGION_DIS6 = 0x40u, /**< Disable subregion 6 */
CY_PROT_SUBREGION_DIS7 = 0x80u /**< Disable subregion 7 */
};
/**
* Protection context mask (PC_MASK)
*/
enum cy_en_prot_pcmask_t
{
CY_PROT_PCMASK1 = 0x0001u, /**< Mask to allow PC = 1 */
CY_PROT_PCMASK2 = 0x0002u, /**< Mask to allow PC = 2 */
CY_PROT_PCMASK3 = 0x0004u, /**< Mask to allow PC = 3 */
CY_PROT_PCMASK4 = 0x0008u, /**< Mask to allow PC = 4 */
CY_PROT_PCMASK5 = 0x0010u, /**< Mask to allow PC = 5 */
CY_PROT_PCMASK6 = 0x0020u, /**< Mask to allow PC = 6 */
CY_PROT_PCMASK7 = 0x0040u, /**< Mask to allow PC = 7 */
CY_PROT_PCMASK8 = 0x0080u, /**< Mask to allow PC = 8 */
CY_PROT_PCMASK9 = 0x0100u, /**< Mask to allow PC = 9 */
CY_PROT_PCMASK10 = 0x0200u, /**< Mask to allow PC = 10 */
CY_PROT_PCMASK11 = 0x0400u, /**< Mask to allow PC = 11 */
CY_PROT_PCMASK12 = 0x0800u, /**< Mask to allow PC = 12 */
CY_PROT_PCMASK13 = 0x1000u, /**< Mask to allow PC = 13 */
CY_PROT_PCMASK14 = 0x2000u, /**< Mask to allow PC = 14 */
CY_PROT_PCMASK15 = 0x4000u /**< Mask to allow PC = 15 */
};
/** \} group_prot_enums */
/***************************************
* Constants
***************************************/
/** \cond INTERNAL */
/* General Masks and shifts */
#define CY_PROT_MSX_CTL_SHIFT (0x02UL) /**< Shift for MSx_CTL register */
#define CY_PROT_STRUCT_ENABLE (0x01UL) /**< Enable protection unit struct */
#define CY_PROT_ADDR_SHIFT (8UL) /**< Address shift for MPU, SMPU and PROG PPU structs */
/* Permission masks and shifts */
#define CY_PROT_ATT_PERMISSION_MASK (0x07UL) /**< Protection Unit attribute permission mask */
#define CY_PROT_ATT_USER_PERMISSION_SHIFT (0x00UL) /**< Protection Unit user attribute permission shift */
#define CY_PROT_ATT_PRIV_PERMISSION_SHIFT (0x03UL) /**< Protection Unit priliged attribute permission shift */
/* Protection Context limit masks */
#define CY_PROT_MPU_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS0_PC_NR_MINUS1)
#define CY_PROT_SMPU_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_SMPU_STRUCT_PC_NR_MINUS1)
#define CY_PROT_PPU_PROG_PC_LIMIT_MASK (0xFFFFFFFFUL << PERI_PPU_PROG_STRUCT_PC_NR_MINUS1)
#define CY_PROT_PPU_FIXED_PC_LIMIT_MASK (0xFFFFFFFFUL << PERI_PPU_FIXED_STRUCT_PC_NR_MINUS1)
/* Parameter validation masks to check for read-only values */
#define CY_PROT_SMPU_ATT0_MASK ((uint32_t)~(PROT_SMPU_SMPU_STRUCT_ATT0_PC_MASK_0_Msk))
#define CY_PROT_SMPU_ATT1_MASK ((uint32_t)~(PROT_SMPU_SMPU_STRUCT_ATT1_UR_Msk \
| PROT_SMPU_SMPU_STRUCT_ATT1_UX_Msk \
| PROT_SMPU_SMPU_STRUCT_ATT1_PR_Msk \
| PROT_SMPU_SMPU_STRUCT_ATT1_PX_Msk \
| PROT_SMPU_SMPU_STRUCT_ATT1_PC_MASK_0_Msk \
| PROT_SMPU_SMPU_STRUCT_ATT1_REGION_SIZE_Msk \
))
#define CY_PROT_PPU_PROG_ATT0_MASK ((uint32_t)~(PERI_PPU_GR_ATT1_UX_Msk \
| PERI_PPU_GR_ATT1_PX_Msk \
|PERI_PPU_PR_ATT0_PC_MASK_0_Msk \
))
#define CY_PROT_PPU_PROG_ATT1_MASK ((uint32_t)~(PERI_PPU_PR_ATT1_UR_Msk \
| PERI_PPU_PR_ATT1_UX_Msk \
| PERI_PPU_PR_ATT1_PR_Msk \
| PERI_PPU_PR_ATT1_PX_Msk \
| PERI_PPU_PR_ATT1_PC_MASK_0_Msk \
| PERI_PPU_PR_ATT1_REGION_SIZE_Msk \
))
#define CY_PROT_PPU_GR_ATT0_MASK ((uint32_t)~(PERI_PPU_GR_ATT0_UX_Msk \
| PERI_PPU_GR_ATT0_PX_Msk \
| PERI_PPU_GR_ATT0_PC_MASK_0_Msk \
| PERI_PPU_GR_ATT0_REGION_SIZE_Msk \
))
#define CY_PROT_PPU_GR_ATT1_MASK ((uint32_t)~(PERI_PPU_GR_ATT1_UR_Msk \
| PERI_PPU_GR_ATT1_UX_Msk \
| PERI_PPU_GR_ATT1_PR_Msk \
| PERI_PPU_GR_ATT1_PX_Msk \
| PERI_PPU_GR_ATT1_PC_MASK_0_Msk \
| PERI_PPU_GR_ATT1_REGION_SIZE_Msk \
))
#define CY_PROT_PPU_SL_ATT0_MASK ((uint32_t)~(PERI_GR_PPU_SL_ATT0_UX_Msk \
| PERI_GR_PPU_SL_ATT0_PX_Msk \
| PERI_GR_PPU_SL_ATT0_PC_MASK_0_Msk \
| PERI_GR_PPU_SL_ATT0_REGION_SIZE_Msk \
))
#define CY_PROT_PPU_SL_ATT1_MASK ((uint32_t)~(PERI_GR_PPU_SL_ATT1_UR_Msk \
| PERI_GR_PPU_SL_ATT1_UX_Msk \
| PERI_GR_PPU_SL_ATT1_PR_Msk \
| PERI_GR_PPU_SL_ATT1_PX_Msk \
| PERI_GR_PPU_SL_ATT1_PC_MASK_0_Msk \
| PERI_GR_PPU_SL_ATT1_REGION_SIZE_Msk \
))
#define CY_PROT_PPU_RG_ATT0_MASK ((uint32_t)~(PERI_GR_PPU_RG_ATT0_UX_Msk \
| PERI_GR_PPU_RG_ATT0_PX_Msk \
| PERI_GR_PPU_RG_ATT0_PC_MASK_0_Msk \
| PERI_GR_PPU_RG_ATT0_REGION_SIZE_Msk \
))
#define CY_PROT_PPU_RG_ATT1_MASK ((uint32_t)~(PERI_GR_PPU_RG_ATT1_UR_Msk \
| PERI_GR_PPU_RG_ATT1_UX_Msk \
| PERI_GR_PPU_RG_ATT1_PR_Msk \
| PERI_GR_PPU_RG_ATT1_PX_Msk \
| PERI_GR_PPU_RG_ATT1_PC_MASK_0_Msk \
| PERI_GR_PPU_RG_ATT1_REGION_SIZE_Msk \
))
/** \endcond */
/***************************************
* Configuration Structures
***************************************/
/**
* \addtogroup group_prot_data_structures
* \{
*/
/** Configuration structure for MPU Struct initialization */
typedef struct
{
uint32_t* address; /**< Base address of the memory region */
cy_en_prot_size_t regionSize; /**< Size of the memory region */
uint8_t subregions; /**< Mask of the 8 subregions to disable */
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
} cy_stc_mpu_cfg_t;
/** Configuration structure for SMPU struct initialization */
typedef struct
{
uint32_t* address; /**< Base address of the memory region (Only applicable to slave) */
cy_en_prot_size_t regionSize; /**< Size of the memory region (Only applicable to slave) */
uint8_t subregions; /**< Mask of the 8 subregions to disable (Only applicable to slave) */
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
uint16_t pcMask; /**< Mask of allowed protection context(s) */
} cy_stc_smpu_cfg_t;
/** Configuration structure for Programmable (PROG) PPU (PPU_PR) struct initialization */
typedef struct
{
uint32_t* address; /**< Base address of the memory region (Only applicable to slave) */
cy_en_prot_size_t regionSize; /**< Size of the memory region (Only applicable to slave) */
uint8_t subregions; /**< Mask of the 8 subregions to disable (Only applicable to slave) */
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
uint16_t pcMask; /**< Mask of allowed protection context(s) */
} cy_stc_ppu_prog_cfg_t;
/** Configuration structure for Fixed Group (GR) PPU (PPU_GR) struct initialization */
typedef struct
{
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
uint16_t pcMask; /**< Mask of allowed protection context(s) */
} cy_stc_ppu_gr_cfg_t;
/** Configuration structure for Fixed Slave (SL) PPU (PPU_SL) struct initialization */
typedef struct
{
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
uint16_t pcMask; /**< Mask of allowed protection context(s) */
} cy_stc_ppu_sl_cfg_t;
/** Configuration structure for Fixed Region (RG) PPU (PPU_RG) struct initialization */
typedef struct
{
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
uint16_t pcMask; /**< Mask of allowed protection context(s) */
} cy_stc_ppu_rg_cfg_t;
/** \} group_prot_data_structures */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_prot_functions
* \{
*/
/**
* \addtogroup group_prot_functions_busmaster
* \{
*/
cy_en_prot_status_t Cy_Prot_ConfigBusMaster(en_prot_master_t busMaster, bool privileged, bool secure, uint32_t pcMask);
cy_en_prot_status_t Cy_Prot_SetActivePC(en_prot_master_t busMaster, uint32_t pc);
uint32_t Cy_Prot_GetActivePC(en_prot_master_t busMaster);
/** \} group_prot_functions_busmaster */
/**
* \addtogroup group_prot_functions_mpu
* \{
*/
cy_en_prot_status_t Cy_Prot_ConfigMpuStruct(PROT_MPU_MPU_STRUCT_Type* base, const cy_stc_mpu_cfg_t* config);
cy_en_prot_status_t Cy_Prot_EnableMpuStruct(PROT_MPU_MPU_STRUCT_Type* base);
cy_en_prot_status_t Cy_Prot_DisableMpuStruct(PROT_MPU_MPU_STRUCT_Type* base);
/** \} group_prot_functions_mpu */
/**
* \addtogroup group_prot_functions_smpu
* \{
*/
cy_en_prot_status_t Cy_Prot_ConfigSmpuMasterStruct(PROT_SMPU_SMPU_STRUCT_Type* base, const cy_stc_smpu_cfg_t* config);
cy_en_prot_status_t Cy_Prot_ConfigSmpuSlaveStruct(PROT_SMPU_SMPU_STRUCT_Type* base, const cy_stc_smpu_cfg_t* config);
cy_en_prot_status_t Cy_Prot_EnableSmpuMasterStruct(PROT_SMPU_SMPU_STRUCT_Type* base);
cy_en_prot_status_t Cy_Prot_DisableSmpuMasterStruct(PROT_SMPU_SMPU_STRUCT_Type* base);
cy_en_prot_status_t Cy_Prot_EnableSmpuSlaveStruct(PROT_SMPU_SMPU_STRUCT_Type* base);
cy_en_prot_status_t Cy_Prot_DisableSmpuSlaveStruct(PROT_SMPU_SMPU_STRUCT_Type* base);
/** \} group_prot_functions_smpu */
/**
* \addtogroup group_prot_functions_ppu_prog
* \{
*/
cy_en_prot_status_t Cy_Prot_ConfigPpuProgMasterStruct(PERI_PPU_PR_Type* base, const cy_stc_ppu_prog_cfg_t* config);
cy_en_prot_status_t Cy_Prot_ConfigPpuProgSlaveStruct(PERI_PPU_PR_Type* base, const cy_stc_ppu_prog_cfg_t* config);
cy_en_prot_status_t Cy_Prot_EnablePpuProgMasterStruct(PERI_PPU_PR_Type* base);
cy_en_prot_status_t Cy_Prot_DisablePpuProgMasterStruct(PERI_PPU_PR_Type* base);
cy_en_prot_status_t Cy_Prot_EnablePpuProgSlaveStruct(PERI_PPU_PR_Type* base);
cy_en_prot_status_t Cy_Prot_DisablePpuProgSlaveStruct(PERI_PPU_PR_Type* base);
/** \} group_prot_functions_ppu_prog */
/**
* \addtogroup group_prot_functions_ppu_gr
* \{
*/
cy_en_prot_status_t Cy_Prot_ConfigPpuFixedGrMasterStruct(PERI_PPU_GR_Type* base, const cy_stc_ppu_gr_cfg_t* config);
cy_en_prot_status_t Cy_Prot_ConfigPpuFixedGrSlaveStruct(PERI_PPU_GR_Type* base, const cy_stc_ppu_gr_cfg_t* config);
cy_en_prot_status_t Cy_Prot_EnablePpuFixedGrMasterStruct(PERI_PPU_GR_Type* base);
cy_en_prot_status_t Cy_Prot_DisablePpuFixedGrMasterStruct(PERI_PPU_GR_Type* base);
cy_en_prot_status_t Cy_Prot_EnablePpuFixedGrSlaveStruct(PERI_PPU_GR_Type* base);
cy_en_prot_status_t Cy_Prot_DisablePpuFixedGrSlaveStruct(PERI_PPU_GR_Type* base);
/** \} group_prot_functions_ppu_gr */
/**
* \addtogroup group_prot_functions_ppu_sl
* \{
*/
cy_en_prot_status_t Cy_Prot_ConfigPpuFixedSlMasterStruct(PERI_GR_PPU_SL_Type* base, const cy_stc_ppu_sl_cfg_t* config);
cy_en_prot_status_t Cy_Prot_ConfigPpuFixedSlSlaveStruct(PERI_GR_PPU_SL_Type* base, const cy_stc_ppu_sl_cfg_t* config);
cy_en_prot_status_t Cy_Prot_EnablePpuFixedSlMasterStruct(PERI_GR_PPU_SL_Type* base);
cy_en_prot_status_t Cy_Prot_DisablePpuFixedSlMasterStruct(PERI_GR_PPU_SL_Type* base);
cy_en_prot_status_t Cy_Prot_EnablePpuFixedSlSlaveStruct(PERI_GR_PPU_SL_Type* base);
cy_en_prot_status_t Cy_Prot_DisablePpuFixedSlSlaveStruct(PERI_GR_PPU_SL_Type* base);
/** \} group_prot_functions_ppu_sl */
/**
* \addtogroup group_prot_functions_ppu_rg
* \{
*/
cy_en_prot_status_t Cy_Prot_ConfigPpuFixedRgMasterStruct(PERI_GR_PPU_RG_Type* base, const cy_stc_ppu_rg_cfg_t* config);
cy_en_prot_status_t Cy_Prot_ConfigPpuFixedRgSlaveStruct(PERI_GR_PPU_RG_Type* base, const cy_stc_ppu_rg_cfg_t* config);
cy_en_prot_status_t Cy_Prot_EnablePpuFixedRgMasterStruct(PERI_GR_PPU_RG_Type* base);
cy_en_prot_status_t Cy_Prot_DisablePpuFixedRgMasterStruct(PERI_GR_PPU_RG_Type* base);
cy_en_prot_status_t Cy_Prot_EnablePpuFixedRgSlaveStruct(PERI_GR_PPU_RG_Type* base);
cy_en_prot_status_t Cy_Prot_DisablePpuFixedRgSlaveStruct(PERI_GR_PPU_RG_Type* base);
/** \} group_prot_functions_ppu_rg */
/** \} group_prot_functions */
/** \} group_prot */
#if defined(__cplusplus)
}
#endif
#endif /* CY_PROT_H */

View File

@ -0,0 +1,412 @@
/***************************************************************************//**
* \file cy_scb_common.c
* \version 1.0
*
* Provides common API implementation of the SCB driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_scb_common.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_SCB_ReadArrayNoCheck
****************************************************************************//**
*
* Reads an array of data out of the SCB receive FIFO without checking if the
* receive FIFO has enough data elements.
* Before calling this function, make sure that the receive FIFO has enough data
* elements to be read.
*
* \param base
* The pointer to the SCB instance.
*
* \param rxBuf
* The pointer to location to place data read from the receive FIFO.
* The size of the data element defined by the configured data width.
*
* \param size
* The number of data elements read from the receive FIFO.
*
*******************************************************************************/
void Cy_SCB_ReadArrayNoCheck(CySCB_Type const *base, void *rxBuf, uint32_t size)
{
uint32_t idx;
if (Cy_SCB_IsRxDataWidthByte(base))
{
uint8_t *buf = (uint8_t *) rxBuf;
/* Get data available in RX FIFO */
for (idx = 0UL; idx < size; ++idx)
{
buf[idx] = (uint8_t) Cy_SCB_ReadRxFifo(base);
}
}
else
{
uint16_t *buf = (uint16_t *) rxBuf;
/* Get data available in RX FIFO */
for (idx = 0UL; idx < size; ++idx)
{
buf[idx] = (uint16_t) Cy_SCB_ReadRxFifo(base);
}
}
}
/*******************************************************************************
* Function Name: Cy_SCB_ReadArray
****************************************************************************//**
*
* Reads an array of data out of the SCB receive FIFO.
* This function does not block, it returns how many data elements were
* read from the receive FIFO.
*
* \param base
* The pointer to the SCB instance.
*
* \param rxBuf
* The pointer to location to place data read from receive FIFO.
* The item size is defined by the data type which depends on the configured
* data width.
*
* \param size
* The number of data elements to read from the receive FIFO.
*
* \return
* The number of data elements read from the receive FIFO.
*
*******************************************************************************/
uint32_t Cy_SCB_ReadArray(CySCB_Type const *base, void *rxBuf, uint32_t size)
{
/* Get available items in RX FIFO */
uint32_t numToCopy = Cy_SCB_GetNumInRxFifo(base);
/* Adjust items which will be read */
if (numToCopy > size)
{
numToCopy = size;
}
/* Get data available in RX FIFO */
Cy_SCB_ReadArrayNoCheck(base, rxBuf, numToCopy);
return (numToCopy);
}
/*******************************************************************************
* Function Name: Cy_SCB_ReadArrayBlocking
****************************************************************************//**
*
* Reads an array of data out of the SCB receive FIFO.
* This function blocks until the number of data elements specified by the
* size has been read from the receive FIFO.
*
* \param base
* The pointer to the SCB instance.
*
* \param rxBuf
* The pointer to location to place data read from receive FIFO.
* The item size is defined by the data type which depends on the configured
* data width.
*
* \param size
* The number of data elements to read from receive FIFO.
*
*******************************************************************************/
void Cy_SCB_ReadArrayBlocking(CySCB_Type const *base, void *rxBuf, uint32_t size)
{
uint32_t numCopied;
uint8_t *buf = (uint8_t *) rxBuf;
/* Get data from RX FIFO. Stop when the requested size is read. */
while (size > 0UL)
{
numCopied = Cy_SCB_ReadArray(base, (void *) buf, size);
buf = &buf[(Cy_SCB_IsRxDataWidthByte(base) ? (numCopied) : (2UL * numCopied))];
size -= numCopied;
}
}
/*******************************************************************************
* Function Name: Cy_SCB_Write
****************************************************************************//**
*
* Places a single data element in the SCB transmit FIFO.
* This function does not block and returns how many data elements were placed
* in the transmit FIFO.
*
* \param base
* The pointer to the SCB instance.
*
* \param data
* Data to put in the transmit FIFO.
* The item size is defined by the data type which depends on the configured
* data width.
*
* \return
* The number of data elements placed in the transmit FIFO: 0 or 1.
*
*******************************************************************************/
uint32_t Cy_SCB_Write(CySCB_Type *base, uint32_t data)
{
uint32_t numCopied = 0UL;
if (Cy_SCB_GetFifoSize(base) != Cy_SCB_GetNumInTxFifo(base))
{
Cy_SCB_WriteTxFifo(base, data);
numCopied = 1UL;
}
return (numCopied);
}
/*******************************************************************************
* Function Name: Cy_SCB_WriteArrayNoCheck
****************************************************************************//**
*
* Places an array of data in the SCB transmit FIFO without checking if the
* transmit FIFO has enough space.
* Before calling this function, make sure that the transmit FIFO has enough
* space to put all requested data elements.
*
* \param base
* The pointer to the SCB instance.
*
* \param txBuf
* The pointer to data to place in the transmit FIFO.
* The item size is defined by the data type which depends on the configured
* TX data width.
*
* \param size
* The number of data elements to transmit.
*
* \return
* The number of data elements placed in the transmit FIFO.
*
*******************************************************************************/
void Cy_SCB_WriteArrayNoCheck(CySCB_Type *base, void *txBuf, uint32_t size)
{
uint32_t idx;
if (Cy_SCB_IsTxDataWidthByte(base))
{
uint8_t *buf = (uint8_t *) txBuf;
/* Put data into TX FIFO */
for (idx = 0UL; idx < size; ++idx)
{
Cy_SCB_WriteTxFifo(base, (uint32_t) buf[idx]);
}
}
else
{
uint16_t *buf = (uint16_t *) txBuf;
/* Put data into TX FIFO */
for (idx = 0UL; idx < size; ++idx)
{
Cy_SCB_WriteTxFifo(base, (uint32_t) buf[idx]);
}
}
}
/*******************************************************************************
* Function Name: Cy_SCB_WriteArray
****************************************************************************//**
*
* Places an array of data in the SCB transmit FIFO.
* This function does not block and it returns how many data elements were
* placed in the transmit FIFO.
*
* \param base
* The pointer to the SCB instance.
*
* \param txBuf
* The pointer to data to place in the transmit FIFO.
* The item size is defined by the data type which depends on the configured
* TX data width.
*
* \param size
* The number of data elements to transmit.
*
* \return
* The number of data elements placed in the transmit FIFO.
*
*******************************************************************************/
uint32_t Cy_SCB_WriteArray(CySCB_Type *base, void *txBuf, uint32_t size)
{
/* Get free entries in TX FIFO */
uint32_t numToCopy = Cy_SCB_GetFifoSize(base) - Cy_SCB_GetNumInTxFifo(base);
/* Adjust the data elements to write */
if (numToCopy > size)
{
numToCopy = size;
}
Cy_SCB_WriteArrayNoCheck(base, txBuf, numToCopy);
return (numToCopy);
}
/*******************************************************************************
* Function Name: Cy_SCB_WriteArrayBlocking
****************************************************************************//**
*
* Places an array of data in the transmit FIFO.
* This function blocks until the number of data elements specified by the size
* is placed in the transmit FIFO.
*
* \param base
* The pointer to the SCB instance.
*
* \param txBuf
* The pointer to data to place in transmit FIFO.
* The item size is defined by the data type which depends on the configured
* data width.
*
* \param size
* The number of data elements to write into the transmit FIFO.
*
*******************************************************************************/
void Cy_SCB_WriteArrayBlocking(CySCB_Type *base, void *txBuf, uint32_t size)
{
uint32_t numCopied;
uint8_t *buf = (uint8_t *) txBuf;
/* Get data from RX FIFO. Stop when the requested size is read. */
while (size > 0UL)
{
numCopied = Cy_SCB_WriteArray(base, (void *) buf, size);
buf = &buf[(Cy_SCB_IsTxDataWidthByte(base) ? (numCopied) : (2UL * numCopied))];
size -= numCopied;
}
}
/*******************************************************************************
* Function Name: Cy_SCB_WriteString
****************************************************************************//**
*
* Places a NULL terminated string in the transmit FIFO.
* This function blocks until the entire string is placed in the transmit FIFO.
*
* \param base
* The pointer to the SCB instance.
*
* \param string
* The pointer to the null terminated string array.
*
*******************************************************************************/
void Cy_SCB_WriteString(CySCB_Type *base, char_t const string[])
{
uint32_t idx = 0UL;
uint32_t fifoSize = Cy_SCB_GetFifoSize(base);
/* Put data from TX FIFO. Stop when string is terminated */
while (((char_t) 0) != string[idx])
{
/* Wait for free space to be available */
while (fifoSize == Cy_SCB_GetNumInTxFifo(base))
{
}
Cy_SCB_WriteTxFifo(base, (uint32_t) string[idx]);
++idx;
}
}
/*******************************************************************************
* Function Name: Cy_SCB_WriteDefaultArrayNoCheck
****************************************************************************//**
*
* Places a number of the same data elements in the SCB transmit FIFO without
* checking if the transmit FIFO has enough space. The data elements is equal
* to txData parameter.
* Before calling this function make sure that transmit FIFO has enough space
* to put all requested data elements.
*
* \param base
* The pointer to the SCB instance.
*
* \param txData
* The data element to transmit repeatedly.
*
* \param size
* The number of data elements to transmit.
*
*******************************************************************************/
void Cy_SCB_WriteDefaultArrayNoCheck(CySCB_Type *base, uint32_t txData, uint32_t size)
{
while (size > 0UL)
{
Cy_SCB_WriteTxFifo(base, txData);
--size;
}
}
/*******************************************************************************
* Function Name: Cy_SCB_WriteDefaultArray
****************************************************************************//**
*
* Places a number of the same data elements in the SCB transmit FIFO.
* The data elements is equal to the txData parameter.
*
* \param base
* The pointer to the SCB instance.
*
* \param txData
* The data element to transmit repeatedly.
*
* \param size
* The number of data elements to transmit.
*
* \return
* The number of data elements placed in the transmit FIFO.
*
*******************************************************************************/
uint32_t Cy_SCB_WriteDefaultArray(CySCB_Type *base, uint32_t txData, uint32_t size)
{
/* Get free entries in TX FIFO */
uint32_t numToCopy = Cy_SCB_GetFifoSize(base) - Cy_SCB_GetNumInTxFifo(base);
/* Adjust data elements to write */
if (numToCopy > size)
{
numToCopy = size;
}
Cy_SCB_WriteDefaultArrayNoCheck(base, txData, numToCopy);
return (numToCopy);
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,424 @@
/***************************************************************************//**
* \file cy_scb_ezi2c.h
* \version 1.0
*
* Provides EZI2C API declarations of the SCB driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \addtogroup group_scb_ezi2c
* \{
* Driver API for EZI2C slave Peripheral
*
* \warning The EZI2C slave driver state is a prototype and it is not
* recommended for use.
*
* I2C - The Inter-Integrated Circuit (I2C) bus is an industry-standard.
* The two-wire hardware interface was developed by Philips Semiconductors
* (now NXP Semiconductors).
*
* The EZI2C slave peripheral driver provides an API to implement I2C slave
* device based on the SCB hardware block. This slave device emulates common
* I2C EEPROM interface that acts like a dual port memory between the external
* master and your code. I2C devices based on SCB hardware are compatible with
* I2C Standard mode, Fast mode, and Fast mode Plus specifications as defined in
* the I2C bus specification.
*
* Features:
* * An industry-standard I2C bus interface
* * Supports standard data rates of 100/400/1000 kbps
* * Emulates a common I2C EEPROM Interface
* * Acts like a dual port memory between the external master and your code
* * Supports Hardware Address Match
* * Supports two hardware addresses with separate buffers
* * Supports Wake from Deep Sleep on address match
* * Simple to set up and use. Once set up, there is no need to call EZI2C API
* at run time.
*
* \section group_scb_ezi2c_configuration Configuration Considerations
*
* To set up the EZI2C slave driver provide the configuration parameters in the
* \ref cy_stc_scb_ezi2c_config_t structure. For the slave the primary slave
* address slaveAddress1 must be provided. The other parameters are optional
* for operation.
* To initialize the driver, call the \ref Cy_SCB_EZI2C_Init function providing
* a pointer to the filled \ref cy_stc_scb_ezi2c_config_t structure and
* allocated \ref cy_stc_scb_ezi2c_context_t. The \ref Cy_SCB_EZI2C_Interrupt
* function must be called in the interrupt handler for selected the
* SCB instance and this interrupt must be enabled in the NVIC. Set up
* EZI2C slave buffers before calling \ref Cy_SCB_EZI2C_Enable using
* \ref Cy_SCB_EZI2C_SetBuffer1 or/and \ref Cy_SCB_EZI2C_SetBuffer2. Finally,
* enable EZI2C slave operation calling \ref Cy_SCB_EZI2C_Enable.
*
* The following operation might not require any EZI2C slave function calls
* because the I2C master is able to access the slave buffer and the application
* can directly access it as well. Note that this is an application level task
* to ensure buffer content integrity.
*
* The master can access buffer access:
* * The master write operations - A base address is always provided and is one
* or two bytes depending on the sub-address size configuration. This base
* address is retained and will be used for later read operations. Following
* the base address is a sequence of bytes that are written into the buffer
* starting from the base address location. The buffer index is incremented
* for each written byte, but this does not affect the base address, which is
* retained. The length of a write operation is limited by the maximum buffer
* read/write region size.\n
* When a master attempts to write outside the read/write region or past the
* end of the buffer, the last byte is NACKed.
* * A read operation always starts from the base address set by the most
* recent write operation. The buffer index is incremented for each read byte.
* Two sequential read operations start from the same base address no matter
* how many bytes were read. The length of a read operation is not limited by
* the maximum size of the data buffer. The EZI2C slave returns 0xFF bytes
* if the read operation passes the end of the buffer.\n
* Typically, a read operation requires the base address to be updated before
* starting the read. In this case, the write and read operations must be
* combined together. The I2C master may use ReStart or Stop/Start conditions
* to combine the operations. The write operation only sets only the base
* address and the following read operation will start from the new base
* address. In cases where the base address remains the same, there is no need
* for a write operation to be performed.
*
* \section group_scb_ezi2c_more_information More Information
*
* For more information on the SCB peripheral, refer to the technical reference
* manual (TRM).
*
* \section group_scb_ezi2c_MISRA MISRA-C Compliance
* <table class="doxtable">
* <tr>
* <th>MISRA Rule</th>
* <th>Rule Class (Required / Advisory)</th>
* <th>Rule Description</th>
* <th>Description of Deviation(s)</th>
* </tr>
* <tr>
* <td>14.2</td>
* <td>R</td>
* <td>All non-null statements shall either: a) have at least one side-effect
* however executed, or b) cause control flow to change.</td>
* <td>The unused function parameters are cast to void. This statement
* has no side-effect and is used to suppress a compiler warning.</td>
* </tr>
* </table>
*
* \section group_scb_ezi2c_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_scb_ezi2c_macro Macro
* \defgroup group_scb_ezi2c_functions Functions
* \defgroup group_scb_ezi2c_data_structures Data Structures
* \defgroup group_scb_ezi2c_enums Enumerated Types
*/
#if !defined(CY_SCB_EZI2C_H)
#define CY_SCB_EZI2C_H
#include "cy_scb_common.h"
#if defined(__cplusplus)
extern "C" {
#endif
/***************************************
* Enumerated Types
***************************************/
/**
* \addtogroup group_scb_ezi2c_enums
* \{
*/
/** EZI2C status codes */
typedef enum
{
/** Operation completed successfully */
CY_SCB_EZI2C_SUCCESS = 0x00U,
/** One or more of input parameters are invalid */
CY_SCB_EZI2C_BAD_PARAM = CY_SCB_ID | CY_PDL_STATUS_ERROR | CY_SCB_EZI2C_ID | 1UL,
} cy_en_scb_ezi2c_status_t;
/** \cond INTERNAL */
/** EZI2C slave FSM states */
typedef enum
{
CY_SCB_EZI2C_STATE_IDLE,
CY_SCB_EZI2C_STATE_RX_OFFSET_MSB,
CY_SCB_EZI2C_STATE_RX_OFFSET_LSB,
CY_SCB_EZI2C_STATE_RX_DATA0,
CY_SCB_EZI2C_STATE_RX_DATA1,
CY_SCB_EZI2C_STATE_TX_DATA
} cy_en_scb_ezi2c_state_t;
/** \endcond */
/** \} group_scb_ezi2c_enums */
/***************************************
* Type Definitions
***************************************/
/**
* \addtogroup group_scb_ezi2c_data_structures
* \{
*/
/** EZI2C Configuration Structure */
typedef struct cy_stc_scb_ezi2c_config
{
/**
* Number of supported addresses either (See
* \ref group_scb_ezi2c_macro_num_of_addr for the set of constants)
*/
uint32_t numberOfAddresses;
/** The 7-bit right justified primary slave address */
uint8_t slaveAddress1;
/** The 7-bit right justified secondary slave address */
uint8_t slaveAddress2;
/** Size of sub-address, can either be 8 or 16 bits (See
* \ref group_scb_ezi2c_macro_sub_addr_size for the set of constants)
*/
uint32_t subAddressSize;
/**
* When set, the slave will wake the device from deep sleep on an address
* match (The device datasheet must be consulted to determine which SCBs
* support this mode)
*/
bool enableWakeFromSleep;
/** Nominal Bus data rate */
uint32_t dataRateHz;
} cy_stc_scb_ezi2c_config_t;
/** EZI2C Internal structure, holds data used by EZI2C functions */
typedef struct cy_stc_scb_ezi2c_context
{
cy_en_scb_ezi2c_state_t state; /**< Driver state */
uint32_t status; /**< Communication status */
uint8_t address1; /**< Primary slave address (7-bits right justified) */
uint8_t address2; /**< Secondary slave address (7-bits right justified) */
uint32_t subAddrSize; /**< Sub-address size */
uint32_t idx; /**< Index within buffer during operation */
uint32_t baseAddr1; /**< Valid base address for primary slave address */
uint32_t baseAddr2; /**< Valid base address for secondary slave address */
bool addr1Active; /**< Defines whether request is intended to primary slave address */
uint8_t *curBuf; /**< Pointer to the current location in buffer (while it is accessed) */
uint32_t bufSize; /**< Specifies how many bytes in current buffer left in the buffer */
uint8_t *buf1; /**< Pointer to the buffer that exposed on request intended to primary slave address */
uint32_t buf1Size; /**< Buffer size assigned to the primary slave address */
uint32_t buf1rwBondary; /**< Read/Write boundary within the buffer assigned to the primary slave address */
uint8_t *buf2; /**< Pointer to the buffer that exposed on request intended to secondary slave address */
uint32_t buf2Size; /**< Buffer size assigned to the secondary slave address */
uint32_t buf2rwBondary; /**< Read/Write boundary within the buffer assigned to the secondary slave address */
} cy_stc_scb_ezi2c_context_t;
/** \} group_scb_ezi2c_data_structures */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_scb_ezi2c_functions
* \{
*/
/* Basic functions */
cy_en_scb_ezi2c_status_t Cy_SCB_EZI2C_Init(CySCB_Type *base, cy_stc_scb_ezi2c_config_t const *config,
cy_stc_scb_ezi2c_context_t *context);
void Cy_SCB_EZI2C_DeInit(CySCB_Type *base);
__STATIC_INLINE void Cy_SCB_EZI2C_Enable(CySCB_Type *base);
void Cy_SCB_EZI2C_Disable(CySCB_Type *base, cy_stc_scb_ezi2c_context_t *context);
/* Low power functions */
void Cy_SCB_EZI2C_DeepSleep(CySCB_Type *base);
void Cy_SCB_EZI2C_Wakeup (CySCB_Type *base);
uint32_t Cy_SCB_EZI2C_GetActivity(CySCB_Type const *base, cy_stc_scb_ezi2c_context_t *context);
/* Configuration functions for address 1 */
void Cy_SCB_EZI2C_SetAddress1(CySCB_Type *base, uint8_t addr, cy_stc_scb_ezi2c_context_t *context);
uint32_t Cy_SCB_EZI2C_GetAddress1(CySCB_Type const *base, cy_stc_scb_ezi2c_context_t const *context);
void Cy_SCB_EZI2C_SetBuffer1 (CySCB_Type const *base, uint8_t *buf, uint32_t bufSize, uint32_t rwBoundary,
cy_stc_scb_ezi2c_context_t *context);
/* Configuration functions for address 2 */
void Cy_SCB_EZI2C_SetAddress2(CySCB_Type *base, uint8_t addr, cy_stc_scb_ezi2c_context_t *context);
uint32_t Cy_SCB_EZI2C_GetAddress2(CySCB_Type const *base, cy_stc_scb_ezi2c_context_t const *context);
void Cy_SCB_EZI2C_SetBuffer2 (CySCB_Type const *base, uint8_t *buf, uint32_t bufSize, uint32_t rwBoundary,
cy_stc_scb_ezi2c_context_t *context);
/* Interrupt handler */
void Cy_SCB_EZI2C_Interrupt(CySCB_Type *base, cy_stc_scb_ezi2c_context_t *context);
/** \} group_scb_ezi2c_functions */
/***************************************
* API Constants
***************************************/
/**
* \addtogroup group_scb_ezi2c_macro
* \{
*/
/**
* \defgroup group_scb_ezi2c_macro_num_of_addr Number of Addresses
* \{
*/
#define CY_SCB_EZI2C_ONE_ADDRESS (0UL) /**< Only one address */
#define CY_SCB_EZI2C_TWO_ADDRESSES (1UL) /**< Two addresses */
/** \} group_scb_ezi2c_macro_num_of_addr */
/**
* \defgroup group_scb_ezi2c_macro_sub_addr_size Size of Sub-Address
* \{
*/
#define CY_SCB_EZI2C_SUB_ADDR8_BITS (0UL) /**< Sub-address is 8 bits */
#define CY_SCB_EZI2C_SUB_ADDR16_BITS (1UL) /**< Sub-address is 16 bits */
/** \} group_scb_ezi2c_macro_sub_addr_size */
/**
* \defgroup group_scb_ezi2c_macro_get_activity EZI2C Activity Status
* Each EZI2C slave status is encoded in a separate bit, therefore multiple bits
* may be set to indicate the current status.
* \{
*/
/** Read transfer complete. The transfer intended for the primary slave address.
* The error condition status bit must be checked to ensure that read
* transfer was completed successfully.
*/
#define CY_SCB_EZI2C_STATUS_READ1 (0x01UL)
/**
* Write transfer complete. The buffer content was modified. The transfer
* intended for the primary slave address.
* The error condition status bit must be checked to ensure that write transfer
* was completed successfully.
*/
#define CY_SCB_EZI2C_STATUS_WRITE1 (0x02UL)
/** Read transfer complete. The transfer intended for the secondary slave
* address.
* The error condition status bit must be checked to ensure that read
* transfer was completed successfully.
*/
#define CY_SCB_EZI2C_STATUS_READ2 (0x04UL)
/** Write transfer complete. The buffer content was modified. The transfer
* intended for the primary slave address.
* The error condition status bit must be checked to ensure that write transfer
* was completed successfully.
*/
#define CY_SCB_EZI2C_STATUS_WRITE2 (0x08UL)
/** A transfer intended for the primary address or secondary address is in
* progress. The status bit is set after an address match and cleared
* on a Stop or ReStart condition.
*/
#define CY_SCB_EZI2C_STATUS_BUSY (0x10UL)
/** An error occurred during a transfer intended for the primary or secondary
* slave address. The sources of error are: misplaced Start or Stop condition or
* lost arbitration while slave drives SDA. When CY_SCB_EZI2C_STATUS_ERR is
* set the slave buffer may contain invalid byte. It is recommended to
* discard buffer content in this case.
*/
#define CY_SCB_EZI2C_STATUS_ERR (0x20UL)
/** \} group_scb_ezi2c_macro_get_activity */
/** This value is returned by the slave when the buffer is not configured or
* the master requests more byte than available in the buffer.
*/
#define CY_SCB_EZI2C_DEFAULT_TX (0xFFUL)
/***************************************
* Internal Constants
***************************************/
/** \cond INTERNAL */
/* Default registers values */
#define CY_SCB_EZI2C_I2C_CTRL (SCB_I2C_CTRL_S_GENERAL_IGNORE_Msk | SCB_I2C_CTRL_SLAVE_MODE_Msk)
#define CY_SCB_EZI2C_DATA_WIDTH (7UL)
#define CY_SCB_EZI2C_RX_CTRL (_VAL2FLD(SCB_RX_CTRL_DATA_WIDTH, CY_SCB_EZI2C_DATA_WIDTH) | \
SCB_RX_CTRL_MSB_FIRST_Msk)
#define CY_SCB_EZI2C_TX_CTRL (CY_SCB_EZI2C_RX_CTRL)
#define CY_SCB_EZI2C_SLAVE_INTR (CY_SCB_SLAVE_INTR_I2C_ADDR_MATCH | CY_SCB_SLAVE_INTR_I2C_STOP | \
CY_SCB_SLAVE_INTR_I2C_BUS_ERROR | CY_SCB_SLAVE_INTR_I2C_ARB_LOST)
/* Error interrupt sources */
#define CY_SCB_EZI2C_SLAVE_INTR_ERROR (CY_SCB_SLAVE_INTR_I2C_BUS_ERROR | CY_SCB_SLAVE_INTR_I2C_ARB_LOST)
/* Disables Stop interrupt source */
#define CY_SCB_EZI2C_SLAVE_INTR_NO_STOP (CY_SCB_EZI2C_SLAVE_INTR & ((uint32_t) ~CY_SCB_SLAVE_INTR_I2C_STOP))
/* FIFO size */
#define CY_SCB_EZI2C_FIFO_SIZE (128UL)
#define CY_SCB_EZI2C_HALF_FIFO_SIZE (CY_SCB_EZI2C_FIFO_SIZE / 2UL)
#define CY_SCB_EZI2C_ONE_ADDRESS_MASK (0xFFUL)
/** \endcond */
/** \} group_scb_ezi2c_macro */
/***************************************
* Inline Function Implementation
***************************************/
/**
* \addtogroup group_scb_ezi2c_functions
* \{
*/
/*******************************************************************************
* Function Name: Cy_SCB_EZI2C_Enable
****************************************************************************//**
*
* Enables the SCB block for the EZI2C operation
*
* \param base
* The pointer to the EZI2C SCB instance.
*
*******************************************************************************/
__STATIC_INLINE void Cy_SCB_EZI2C_Enable(CySCB_Type *base)
{
base->CTRL |= SCB_CTRL_ENABLED_Msk;
}
/** \} group_scb_ezi2c_functions */
#if defined(__cplusplus)
}
#endif
/** \} group_scb_ezi2c */
#endif /* (CY_SCB_EZI2C_H) */
/* [] END OF FILE */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,766 @@
/***************************************************************************//**
* \file cy_scb_spi.c
* \version 1.0
*
* Provides SPI API implementation of the SCB driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_scb_spi.h"
#if defined(__cplusplus)
extern "C" {
#endif
/* Static functions */
static void HandleTransmit(CySCB_Type *base, cy_stc_scb_spi_context_t *context);
static void HandleReceive (CySCB_Type *base, cy_stc_scb_spi_context_t *context);
static void DiscardArrayNoCheck(CySCB_Type const *base, uint32_t size);
/*******************************************************************************
* Function Name: Cy_SCB_SPI_Init
****************************************************************************//**
*
* Initializes the SCB for SPI operation.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param config
* The pointer to the configuration structure \ref cy_stc_scb_spi_config_t.
*
* \param context
* The pointer to the context structure \ref cy_stc_scb_spi_context_t allocated
* by the user. The structure is used during the SPI operation for internal
* configuration and data keeping. The user should not modify anything
* in this structure.
* If only SPI functions which do not require context will be used pass NULL
* as pointer to context.
*
* \return
* \ref cy_en_scb_spi_status_t
*
* \note
* Ensure that the SCB block is disabled before calling this function.
*
*******************************************************************************/
cy_en_scb_spi_status_t Cy_SCB_SPI_Init(CySCB_Type *base, cy_stc_scb_spi_config_t const *config, cy_stc_scb_spi_context_t *context)
{
cy_en_scb_spi_status_t retStatus = CY_SCB_SPI_BAD_PARAM;
if ((NULL != base) && (NULL != config))
{
/* Set SCLK mode for TI - CY_SCB_SPI_CPHA1_CPOL0, NS - CY_SCB_SPI_CPHA0_CPOL0, Motorola - take from config */
uint32_t locSclkMode = (CY_SCB_SPI_MOTOROLA == config->subMode) ? config->sclkMode :
((CY_SCB_SPI_NATIONAL == config->subMode) ? CY_SCB_SPI_CPHA0_CPOL0 : CY_SCB_SPI_CPHA1_CPOL0);
/* Configure an SPI interface */
base->CTRL = (((config->rxDataWidth <= CY_SCB_BYTE_WIDTH) && (config->txDataWidth <= CY_SCB_BYTE_WIDTH)) ?
SCB_CTRL_BYTE_MODE_Msk : 0UL) |
(config->enableWakeFromSleep ? SCB_CTRL_EC_AM_MODE_Msk : 0UL) |
_VAL2FLD(SCB_CTRL_OVS, (config->oversample - 1UL)) |
_VAL2FLD(SCB_CTRL_MODE, CY_SCB_CTRL_MODE_SPI);
base->SPI_CTRL = (config->enableTransferSeperation ? 0UL : SCB_SPI_CTRL_SSEL_CONTINUOUS_Msk) |
((0UL != (CY_SCB_SPI_TI_PRECEDE & config->subMode)) ? SCB_SPI_CTRL_SELECT_PRECEDE_Msk : 0UL) |
(config->enableMisoLateSample ? SCB_SPI_CTRL_LATE_MISO_SAMPLE_Msk : 0UL) |
(config->enableFreeRunSclk ? SCB_SPI_CTRL_SCLK_CONTINUOUS_Msk : 0UL) |
((CY_SCB_SPI_MASTER == config->spiMode) ? SCB_SPI_CTRL_MASTER_MODE_Msk : 0UL) |
_VAL2FLD(CY_SCB_SPI_CTRL_CLK_MODE, locSclkMode) |
_VAL2FLD(CY_SCB_SPI_CTRL_SSEL_POLARITY, config->ssPolarity) |
_VAL2FLD(SCB_SPI_CTRL_MODE, config->subMode);
/* Configure the RX direction */
base->RX_CTRL = (config->enableMsbFirst ? SCB_RX_CTRL_MSB_FIRST_Msk : 0UL) |
(config->enableInputFilter ? SCB_RX_CTRL_MEDIAN_Msk : 0UL) |
_VAL2FLD(SCB_RX_CTRL_DATA_WIDTH, (config->rxDataWidth - 1UL));
base->RX_FIFO_CTRL = _VAL2FLD(SCB_RX_FIFO_CTRL_TRIGGER_LEVEL, config->rxFifoTriggerLevel);
/* Configure the TX direction */
base->TX_CTRL = (config->enableMsbFirst ? SCB_RX_CTRL_MSB_FIRST_Msk : 0UL) |
_VAL2FLD(SCB_TX_CTRL_DATA_WIDTH, (config->txDataWidth - 1UL));
base->TX_FIFO_CTRL = _VAL2FLD(SCB_TX_FIFO_CTRL_TRIGGER_LEVEL, config->txFifoTriggerLevel);
/* Set up interrupt sources */
base->INTR_TX_MASK = config->txFifoIntEnableMask;
base->INTR_RX_MASK = config->rxFifoIntEnableMask;
base->INTR_M = (config->masterSlaveIntEnableMask & SCB_INTR_M_MASK_SPI_DONE_Msk);
base->INTR_S = (config->masterSlaveIntEnableMask & SCB_INTR_S_MASK_SPI_BUS_ERROR_Msk);
base->INTR_SPI_EC_MASK = 0UL;
/* Initialize the context */
if (NULL != context)
{
context->status = 0UL;
context->txBufIdx = 0UL;
context->rxBufIdx = 0UL;
context->cbEvents = NULL;
#if !defined(NDEBUG)
/* Put an initialization key into the initKey variable to verify
* context initialization in the transfer API.
*/
context->initKey = CY_SCB_SPI_INIT_KEY;
#endif /* !(NDEBUG) */
}
retStatus = CY_SCB_SPI_SUCCESS;
}
return (retStatus);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_DeInit
****************************************************************************//**
*
* De-initializes the SCB block, returns the register values to default.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \note
* Ensure that the SCB block is disabled before calling this function.
*
*******************************************************************************/
void Cy_SCB_SPI_DeInit(CySCB_Type *base)
{
/* SPI interface */
base->CTRL = CY_SCB_CTRL_DEF_VAL;
base->SPI_CTRL = CY_SCB_SPI_CTRL_DEF_VAL;
/* RX direction */
base->RX_CTRL = CY_SCB_RX_CTRL_DEF_VAL;
base->RX_FIFO_CTRL = 0UL;
/* TX direction */
base->TX_CTRL = CY_SCB_TX_CTRL_DEF_VAL;
base->TX_FIFO_CTRL = 0UL;
/* Disable all interrupt sources */
base->INTR_SPI_EC_MASK = 0UL;
base->INTR_I2C_EC_MASK = 0UL;
base->INTR_RX_MASK = 0UL;
base->INTR_TX_MASK = 0UL;
base->INTR_M_MASK = 0UL;
base->INTR_S_MASK = 0UL;
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_Disable
****************************************************************************//**
*
* Disables the SCB block, clears context statuses and disables
* TX and RX interrupt sources.
* Note that after the block is disabled the TX and RX FIFOs and
* hardware statuses are cleared. Also, the hardware stops driving the output
* and ignores the input.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param context
* The pointer to the context structure \ref cy_stc_scb_spi_context_t allocated
* by the user. The structure is used during the SPI operation for internal
* configuration and data keeping. The user should not modify anything
* in this structure.
* If only SPI functions which do not require context will be used pass NULL
* as pointer to context.
*
* \note
* Calling this function when the SPI is busy (master preforms data transfer or
* slave communicates with the master) may cause transfer corruption because the
* hardware stops driving the output and ignores the input.
* It is recommenced to ensure that the SPI is not busy before calling this
* function.
*
*******************************************************************************/
void Cy_SCB_SPI_Disable(CySCB_Type *base, cy_stc_scb_spi_context_t *context)
{
base->CTRL &= (uint32_t) ~SCB_CTRL_ENABLED_Msk;
if (NULL != context)
{
context->status = 0UL;
context->rxBufIdx = 0UL;
context->txBufIdx = 0UL;
}
/* Disable RX and TX interrupt sources for the slave because
* RX overflow and TX underflow are kept enabled after the 1st call of
* Cy_SCB_SPI_Transfer().
*/
if (!_FLD2BOOL(SCB_SPI_CTRL_MASTER_MODE, base->SPI_CTRL))
{
Cy_SCB_SetRxInterruptMask(base, CY_SCB_CLEAR_ALL_INTR_SRC);
Cy_SCB_SetTxInterruptMask(base, CY_SCB_CLEAR_ALL_INTR_SRC);
}
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_DeepSleep
****************************************************************************//**
*
* Prepares the SPI for deep sleep operation: clears the SPI wake up interrupt
* history and enables it. The wake-up event is the activation of the
* slave select line.
* This function does nothing if the deep sleep option has not been enabled.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \note
* Not all SCBs support the deep sleep operation, consult the device
* datasheet to determine which SCBs support deep sleep operation.
*
*******************************************************************************/
void Cy_SCB_SPI_DeepSleep(CySCB_Type *base)
{
if (_FLD2BOOL(SCB_CTRL_EC_AM_MODE, base->CTRL))
{
/* Clear and enable the SPI wakeup source */
Cy_SCB_ClearSpiInterrupt (base, CY_SCB_SPI_INTR_WAKEUP);
Cy_SCB_SetSpiInterruptMask(base, CY_SCB_SPI_INTR_WAKEUP);
}
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_Wakeup
****************************************************************************//**
*
* Disables the wakeup interrupt.
* This function does nothing if the deep sleep option has not been enabled.
*
* \param base
* The pointer to the SPI SCB instance.
*
*******************************************************************************/
void Cy_SCB_SPI_Wakeup(CySCB_Type *base)
{
if (_FLD2BOOL(SCB_CTRL_EC_AM_MODE, base->CTRL))
{
/* Disable the SPI wakeup source */
Cy_SCB_SetSpiInterruptMask(base, CY_SCB_CLEAR_ALL_INTR_SRC);
}
}
/************************* High-Level Functions ********************************
* The following functions are considered high-level. They provide the layer of
* intelligence to the SCB. These functions require interrupts.
* Low-level and high-level functions should not be mixed because low-level API
* can adversely affect the operation of high-level functions.
*******************************************************************************/
/*******************************************************************************
* Function Name: Cy_SCB_SPI_Transfer
****************************************************************************//**
*
* This function starts an SPI transfer operation.
* It configures transmit and receive buffers for an SPI transfer.
* If the data that will be received is not important, pass NULL as rxBuf.
* If the data that will be transmitted is not important, pass NULL as txBuf
* and then the \ref CY_SCB_SPI_DEFAULT_TX is sent out as each data element.
*
* After the function configures TX and RX interrupt sources, it returns and
* \ref Cy_SCB_SPI_Interrupt manages further data transfer.
*
* * In the master mode, the transfer operation is started after calling this
* function
* * In the slave mode, the transfer is registered and will be started when
* the master request arrives.
*
* When the transfer operation is completed (requested number of data elements
* sent and received), the \ref CY_SCB_SPI_TRANSFER_ACTIVE status is cleared
* and the \ref CY_SCB_SPI_TRANSFER_CMPLT_EVENT event is generated.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param txBuf
* The pointer of the buffer with data to transmit.
* The item size is defined by the data type which depends on the configured
* TX data width.
*
* \param rxBuf
* The pointer to the buffer to store received data.
* The item size is defined by the data type which depends on the configured
* RX data width.
*
* \param size
* The number of data elements to transmit and receive.
*
* \param context
* The pointer to the context structure \ref cy_stc_scb_spi_context_t allocated
* by the user. The structure is used during the SPI operation for internal
* configuration and data keeping. The user should not modify anything
* in this structure.
*
* \return
* \ref cy_en_scb_spi_status_t
*
* \note
* * The buffers must not be modified and stay allocated until the end of the
* transfer.
* * This function overrides all RX and TX FIFO interrupt sources and changes
* the RX and TX FIFO level.
*
*******************************************************************************/
cy_en_scb_spi_status_t Cy_SCB_SPI_Transfer(CySCB_Type *base, void *txBuf, void *rxBuf, uint32_t size, cy_stc_scb_spi_context_t *context)
{
cy_en_scb_spi_status_t retStatus = CY_SCB_SPI_TRANSFER_BUSY;
#if !defined(NDEBUG)
/* Check that the initialization key was set before using the context */
CY_ASSERT(NULL != context);
CY_ASSERT(CY_SCB_SPI_INIT_KEY == context->initKey);
#endif /* !(NDEBUG) */
/* Check if there are no active transfer requests */
if (0UL == (CY_SCB_SPI_TRANSFER_ACTIVE & context->status))
{
uint32_t fifoSize = Cy_SCB_GetFifoSize(base);
/* Set up the context */
context->status = CY_SCB_SPI_TRANSFER_ACTIVE;
context->txBuf = txBuf;
context->txBufSize = size;
context->txBufIdx = 0UL;
context->rxBuf = rxBuf;
context->rxBufSize = size;
context->rxBufIdx = 0UL;
/* Set the TX interrupt when half of FIFO was transmitted */
Cy_SCB_SetTxFifoLevel(base, fifoSize / 2UL);
if (_FLD2BOOL(SCB_SPI_CTRL_MASTER_MODE, base->SPI_CTRL))
{
/* Trigger an RX interrupt:
* - If the transfer size is equal to or less than FIFO, trigger at the end of the transfer.
* - If the transfer size is greater than FIFO, trigger 1 byte earlier than the TX interrupt.
*/
Cy_SCB_SetRxFifoLevel(base, (size > fifoSize) ? ((fifoSize / 2UL) - 2UL) : (size - 1UL));
Cy_SCB_SetMasterInterruptMask(base, CY_SCB_CLEAR_ALL_INTR_SRC);
/* Enable interrupt sources to perform a transfer */
Cy_SCB_SetRxInterruptMask(base, CY_SCB_RX_INTR_LEVEL);
Cy_SCB_SetTxInterruptMask(base, CY_SCB_TX_INTR_LEVEL);
}
else
{
/* Trigger an RX interrupt:
* - If the transfer size is equal to or less than half of FIFO, trigger ??at the end of the transfer.
* - If the transfer size is greater than half of FIFO, trigger 1 byte earlier than a TX interrupt.
*/
Cy_SCB_SetRxFifoLevel(base, (size > (fifoSize / 2UL)) ? ((fifoSize / 2UL) - 2UL) : (size - 1UL));
Cy_SCB_SetSlaveInterruptMask(base, CY_SCB_SLAVE_INTR_SPI_BUS_ERROR);
/* Enable interrupt sources to perform a transfer */
Cy_SCB_SetRxInterruptMask(base, CY_SCB_RX_INTR_LEVEL | CY_SCB_RX_INTR_OVERFLOW);
Cy_SCB_SetTxInterruptMask(base, CY_SCB_TX_INTR_LEVEL | CY_SCB_TX_INTR_UNDERFLOW);
}
retStatus = CY_SCB_SPI_SUCCESS;
}
return (retStatus);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_AbortTransfer
****************************************************************************//**
*
* Aborts the current SPI transfer.
* It disables the transmit and RX interrupt sources, clears the TX
* and RX FIFOs and the status.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param context
* The pointer to the context structure \ref cy_stc_scb_spi_context_t allocated
* by the user. The structure is used during the SPI operation for internal
* configuration and data keeping. The user should not modify anything
* in this structure.
*
* \note
* In the slave mode and after abort of transfer operation master continue
* sending data it gets into RX FIFO and TX FIFO is underflow as there is
* nothing to send. To drop this data, RX FIFO has to be cleared when
* the transfer is completed. Otherwise, received data will be kept and
* copied to the buffer when \ref Cy_SCB_SPI_Transfer is called.
*
* \sideeffect
* The transmit FIFO clear operation also clears the shift register, so that
* the shifter could be cleared in the middle of a data element transfer,
* corrupting it. The data element corruption means that all bits which has
* not been transmitted are transmitted as "ones" on the bus.
*
*******************************************************************************/
void Cy_SCB_SPI_AbortTransfer(CySCB_Type *base, cy_stc_scb_spi_context_t *context)
{
/* Disable interrupt sources */
Cy_SCB_SetSlaveInterruptMask(base, CY_SCB_CLEAR_ALL_INTR_SRC);
if (_FLD2BOOL(SCB_SPI_CTRL_MASTER_MODE, base->SPI_CTRL))
{
Cy_SCB_SetRxInterruptMask(base, CY_SCB_CLEAR_ALL_INTR_SRC);
Cy_SCB_SetTxInterruptMask(base, CY_SCB_CLEAR_ALL_INTR_SRC);
}
else
{
Cy_SCB_SetRxInterruptMask(base, CY_SCB_RX_INTR_OVERFLOW);
Cy_SCB_SetTxInterruptMask(base, CY_SCB_TX_INTR_UNDERFLOW);
}
/* Clear FIFOs */
Cy_SCB_SPI_ClearTxFifo(base);
Cy_SCB_SPI_ClearRxFifo(base);
/* Clear the status to allow a new transfer */
context->status = 0UL;
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_GetNumTransfered
****************************************************************************//**
*
* Returns the number of data elements transferred since the last call to \ref
* Cy_SCB_SPI_Transfer.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param context
* The pointer to the context structure \ref cy_stc_scb_spi_context_t allocated
* by the user. The structure is used during the SPI operation for internal
* configuration and data keeping. The user should not modify anything
* in this structure.
*
* \return
* The number of data elements transferred.
*
*******************************************************************************/
uint32_t Cy_SCB_SPI_GetNumTransfered(CySCB_Type const *base, cy_stc_scb_spi_context_t const *context)
{
/* Suppress a compiler warning about unused variables */
(void) base;
return (context->rxBufIdx);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_GetTransferStatus
****************************************************************************//**
*
* Returns the status of the transfer operation started by
* \ref Cy_SCB_SPI_Transfer.
* This status is a bit mask and the value returned may have a multiple-bit set.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param context
* The pointer to the context structure \ref cy_stc_scb_spi_context_t allocated
* by the user. The structure is used during the SPI operation for internal
* configuration and data keeping. The user should not modify anything
* in this structure.
*
* \return
* \ref group_scb_spi_macro_xfer_status.
*
* \note
* The status is cleared by calling \ref Cy_SCB_SPI_Transfer or
* \ref Cy_SCB_SPI_AbortTransfer.
*
*******************************************************************************/
uint32_t Cy_SCB_SPI_GetTransferStatus(CySCB_Type const *base, cy_stc_scb_spi_context_t const *context)
{
/* Suppress a compiler warning about unused variables */
(void) base;
return (context->status);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_Interrupt
****************************************************************************//**
*
* This is the interrupt function for the SCB configured in the SPI mode.
* This function must be called inside the user-defined interrupt service
* routine in order for \ref Cy_SCB_SPI_Transfer to work.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param context
* The pointer to the context structure \ref cy_stc_scb_spi_context_t allocated
* by the user. The structure is used during the SPI operation for internal
* configuration and data keeping. The user should not modify anything
* in this structure.
*
*******************************************************************************/
void Cy_SCB_SPI_Interrupt(CySCB_Type *base, cy_stc_scb_spi_context_t *context)
{
uint32 locXferErr = 0UL;
/* Wake up on the slave select condition */
if (0UL != (CY_SCB_SPI_INTR_WAKEUP & Cy_SCB_GetSpiInterruptStatusMasked(base)))
{
Cy_SCB_ClearSpiInterrupt(base, CY_SCB_SPI_INTR_WAKEUP);
}
/* The slave error condition */
if (0UL != (CY_SCB_SLAVE_INTR_SPI_BUS_ERROR & Cy_SCB_GetSlaveInterruptStatusMasked(base)))
{
locXferErr = CY_SCB_SPI_TRANSFER_ERR;
context->status |= CY_SCB_SPI_SLAVE_TRANSFER_ERR;
Cy_SCB_ClearSlaveInterrupt(base, CY_SCB_SLAVE_INTR_SPI_BUS_ERROR);
}
/* The RX overflow error condition */
if (0UL != (CY_SCB_RX_INTR_OVERFLOW & Cy_SCB_GetRxInterruptStatusMasked(base)))
{
locXferErr = CY_SCB_SPI_TRANSFER_ERR;
context->status |= CY_SCB_SPI_TRANSFER_OVERFLOW;
Cy_SCB_ClearRxInterrupt(base, CY_SCB_RX_INTR_OVERFLOW);
}
/* The TX underflow error condition or slave complete data transfer */
if (0UL != (CY_SCB_TX_INTR_UNDERFLOW & Cy_SCB_GetTxInterruptStatusMasked(base)))
{
locXferErr = CY_SCB_SPI_TRANSFER_ERR;
context->status |= CY_SCB_SPI_TRANSFER_UNDERFLOW;
Cy_SCB_ClearTxInterrupt(base, CY_SCB_TX_INTR_UNDERFLOW);
}
/* Report an error, use a callback */
if (0UL != locXferErr)
{
if (NULL != context->cbEvents)
{
context->cbEvents(CY_SCB_SPI_TRANSFER_ERR);
}
}
/* RX direction */
if (0UL != (CY_SCB_RX_INTR_LEVEL & Cy_SCB_GetRxInterruptStatusMasked(base)))
{
HandleReceive(base, context);
Cy_SCB_ClearRxInterrupt(base, CY_SCB_RX_INTR_LEVEL);
}
/* TX direction */
if (0UL != (CY_SCB_TX_INTR_LEVEL & Cy_SCB_GetTxInterruptStatusMasked(base)))
{
HandleTransmit(base, context);
Cy_SCB_ClearTxInterrupt(base, CY_SCB_TX_INTR_LEVEL);
}
/* The transfer is complete: all data is loaded in the TX FIFO
* and all data is read from the RX FIFO
*/
if ((0UL != (context->status & CY_SCB_SPI_TRANSFER_ACTIVE)) &&
(0UL == context->rxBufSize) && (0UL == context->txBufSize))
{
/* The transfer is complete */
context->status &= (uint32_t) ~CY_SCB_SPI_TRANSFER_ACTIVE;
if (NULL != context->cbEvents)
{
context->cbEvents(CY_SCB_SPI_TRANSFER_CMPLT_EVENT);
}
}
}
/*******************************************************************************
* Function Name: HandleReceive
****************************************************************************//**
*
* Reads data from RX FIFO into the buffer provided by \ref Cy_SCB_SPI_Transfer.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param context
* The pointer to the context structure \ref cy_stc_scb_spi_context_t allocated
* by the user. The structure is used during the SPI operation for internal
* configuration and data keeping. The user should not modify anything
* in this structure.
*
*******************************************************************************/
static void HandleReceive(CySCB_Type *base, cy_stc_scb_spi_context_t *context)
{
/* Get data in RX FIFO */
uint32_t numToCopy = Cy_SCB_GetNumInRxFifo(base);
/* Adjust the number to read */
if (numToCopy > context->rxBufSize)
{
numToCopy = context->rxBufSize;
}
/* Move the buffer */
context->rxBufIdx += numToCopy;
context->rxBufSize -= numToCopy;
/* Read data from RX FIFO */
if (NULL != context->rxBuf)
{
uint8_t *buf = (uint8_t *) context->rxBuf;
Cy_SCB_ReadArrayNoCheck(base, context->rxBuf, numToCopy);
buf = &buf[(Cy_SCB_IsRxDataWidthByte(base) ? (numToCopy) : (2UL * numToCopy))];
context->rxBuf = (void *) buf;
}
else
{
/* Discard read data. */
DiscardArrayNoCheck(base, numToCopy);
}
if (0UL == context->rxBufSize)
{
/* Disable the RX level interrupt */
Cy_SCB_SetRxInterruptMask(base, (Cy_SCB_GetRxInterruptMask(base) & (uint32_t) ~CY_SCB_RX_INTR_LEVEL));
}
else
{
uint32_t level = (_FLD2BOOL(SCB_SPI_CTRL_MASTER_MODE, base->SPI_CTRL)) ?
Cy_SCB_GetFifoSize(base) : (Cy_SCB_GetFifoSize(base) / 2UL);
if (context->rxBufSize < level)
{
Cy_SCB_SetRxFifoLevel(base, (context->rxBufSize - 1UL));
}
}
}
/*******************************************************************************
* Function Name: HandleTransmit
****************************************************************************//**
*
* Loads TX FIFO with data provided by \ref Cy_SCB_SPI_Transfer.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param context
* The pointer to the context structure \ref cy_stc_scb_spi_context_t allocated
* by the user. The structure is used during the SPI operation for internal
* configuration and data keeping. The user should not modify anything
* in this structure.
*
*******************************************************************************/
static void HandleTransmit(CySCB_Type *base, cy_stc_scb_spi_context_t *context)
{
uint32_t numToCopy;
uint32_t fifoSize = Cy_SCB_GetFifoSize(base);
numToCopy = fifoSize - Cy_SCB_GetNumInTxFifo(base);
/* Adjust the number to load */
if (numToCopy > context->txBufSize)
{
numToCopy = context->txBufSize;
}
/* Move the buffer */
context->txBufIdx += numToCopy;
context->txBufSize -= numToCopy;
/* Load TX FIFO with data */
if (NULL != context->txBuf)
{
uint8_t *buf = (uint8_t *) context->txBuf;
Cy_SCB_WriteArrayNoCheck(base, context->txBuf, numToCopy);
buf = &buf[(Cy_SCB_IsTxDataWidthByte(base) ? (numToCopy) : (2UL * numToCopy))];
context->txBuf = (void *) buf;
}
else
{
Cy_SCB_WriteDefaultArrayNoCheck(base, CY_SCB_SPI_DEFAULT_TX, numToCopy);
}
if (0UL == context->txBufSize)
{
/* Data is transferred into TX FIFO */
context->status |= CY_SCB_SPI_TRANSFER_IN_FIFO;
/* Disable the TX level interrupt */
Cy_SCB_SetTxInterruptMask(base, (Cy_SCB_GetTxInterruptMask(base) & (uint32_t) ~CY_SCB_TX_INTR_LEVEL));
if (NULL != context->cbEvents)
{
context->cbEvents(CY_SCB_SPI_TRANSFER_IN_FIFO_EVENT);
}
}
}
/*******************************************************************************
* Function Name: DiscardArrayNoCheck
****************************************************************************//**
*
* Reads the number of data elements from the SPI RX FIFO. The read data is
* discarded. Before calling this function, make sure that RX FIFO has
* enough data elements to read.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param size
* The number of data elements to read.
*
*******************************************************************************/
static void DiscardArrayNoCheck(CySCB_Type const *base, uint32_t size)
{
while (size > 0UL)
{
(void) Cy_SCB_SPI_Read(base);
--size;
}
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,369 @@
/***************************************************************************//**
* \file
* \version 1.0
*
* \brief
* Provides an API implementation of the sysint driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_sysint.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_SysInt_Init
****************************************************************************//**
*
* \brief Initializes the referenced interrupt by setting the priority and the
* interrupt vector. Note that the interrupt vector will only be relocated if the
* vector table was moved to __ramVectors in SRAM. Otherwise it is ignored.
*
* Use the CMSIS core function NVIC_EnableIRQ(config.intrSrc)
* to enable it. For CM0+, this function also configures the interrupt mux
* connected to the NVIC. Use the CMSIS core function
* NVIC_EnableIRQ(config.intrCm0p) to enable it.
*
* \param config
* Interrupt configuration structure
*
* \param userIsr
* Address of the ISR
*
*******************************************************************************/
cy_en_sysint_status_t Cy_SysInt_Init(const cy_stc_sysint_t* config, cy_israddress userIsr)
{
cy_en_sysint_status_t status = CY_SYSINT_SUCCESS;
if(NULL != config)
{
#if (CY_CPU_CORTEX_M0P)
if (config->intrSrc < 0)
{
NVIC_SetPriority(config->intrSrc, config->intrPriority);
}
else
{
/* Configure the interrupt mux */
Cy_SysInt_SetIntSource(config);
NVIC_SetPriority((IRQn_Type)(config->intrCm0p), config->intrPriority);
}
#else
/* Set the priority */
NVIC_SetPriority(config->intrSrc, config->intrPriority);
#endif
/* Only set the new vector if it was moved to __ramVectors */
if (SCB->VTOR == (uint32_t)&__ramVectors)
{
(void)Cy_SysInt_SetVector(config, userIsr);
}
}
else
{
status = CY_SYSINT_BAD_PARAM;
}
return(status);
}
#if CY_CPU_CORTEX_M0P || defined (CY_DOXYGEN)
/*******************************************************************************
* Function Name: Cy_SysInt_SetIntSource
****************************************************************************//**
*
* \brief Configures the interrupt mux for the specified CM0+ NVIC channel.
*
* Setting this value to 240 disconnects the interrupt source and will
* effectively deactivate the interrupt.
*
* \param config
* Interrupt configuration structure. This must be a positive number.
*
*******************************************************************************/
void Cy_SysInt_SetIntSource(const cy_stc_sysint_t* config)
{
/* Calculation of variables and masks */
uint8_t intrMux = config->intrCm0p;
uint8_t regPos = intrMux >> CY_SYSINT_CM0P_MUX_SHIFT;
uint8_t bitPos = (intrMux - (regPos << CY_SYSINT_CM0P_MUX_SHIFT)) << CY_SYSINT_CM0P_MUX_SCALE;
uint32_t bitMask = (uint32_t)(CY_SYSINT_CM0P_MUX_MASK << bitPos);
uint32_t bitMaskClr = (uint32_t)(~bitMask);
uint32_t bitMaskSet = ((config->intrSrc << bitPos) & bitMask);
uint32_t tempReg;
switch(regPos)
{
case CY_SYSINT_CM0P_MUX0:
tempReg = CPUSS->CM0_INT_CTL0 & bitMaskClr;
CPUSS->CM0_INT_CTL0 = tempReg | bitMaskSet;
break;
case CY_SYSINT_CM0P_MUX1:
tempReg = CPUSS->CM0_INT_CTL1 & bitMaskClr;
CPUSS->CM0_INT_CTL1 = tempReg | bitMaskSet;
break;
case CY_SYSINT_CM0P_MUX2:
tempReg = CPUSS->CM0_INT_CTL2 & bitMaskClr;
CPUSS->CM0_INT_CTL2 = tempReg | bitMaskSet;
break;
case CY_SYSINT_CM0P_MUX3:
tempReg = CPUSS->CM0_INT_CTL3 & bitMaskClr;
CPUSS->CM0_INT_CTL3 = tempReg | bitMaskSet;
break;
case CY_SYSINT_CM0P_MUX4:
tempReg = CPUSS->CM0_INT_CTL4 & bitMaskClr;
CPUSS->CM0_INT_CTL4 = tempReg | bitMaskSet;
break;
case CY_SYSINT_CM0P_MUX5:
tempReg = CPUSS->CM0_INT_CTL5 & bitMaskClr;
CPUSS->CM0_INT_CTL5 = tempReg | bitMaskSet;
break;
case CY_SYSINT_CM0P_MUX6:
tempReg = CPUSS->CM0_INT_CTL6 & bitMaskClr;
CPUSS->CM0_INT_CTL6 = tempReg | bitMaskSet;
break;
case CY_SYSINT_CM0P_MUX7:
tempReg = CPUSS->CM0_INT_CTL7 & bitMaskClr;
CPUSS->CM0_INT_CTL7 = tempReg | bitMaskSet;
break;
default:
break;
}
}
/*******************************************************************************
* Function Name: Cy_SysInt_GetIntSource
****************************************************************************//**
*
* \brief Gets the interrupt source of CM0+ NVIC channel.
*
* \return
* Interrupt source. A returned value of 240 denotes that the interrupt source
* is disconnected.
*
*******************************************************************************/
uint32_t Cy_SysInt_GetIntSource(IRQn_CM0P_Type muxSel)
{
/* Calculation of variables */
uint8_t regPos = muxSel >> CY_SYSINT_CM0P_MUX_SHIFT;
uint8_t bitPos = (muxSel - (regPos << CY_SYSINT_CM0P_MUX_SHIFT)) << CY_SYSINT_CM0P_MUX_SCALE;
uint32_t bitMask = (uint32_t)(CY_SYSINT_CM0P_MUX_MASK << bitPos);
uint32_t tempReg;
switch(regPos)
{
case CY_SYSINT_CM0P_MUX0:
tempReg = (uint32_t)((CPUSS->CM0_INT_CTL0 & bitMask) >> bitPos);
break;
case CY_SYSINT_CM0P_MUX1:
tempReg = (uint32_t)((CPUSS->CM0_INT_CTL1 & bitMask) >> bitPos);
break;
case CY_SYSINT_CM0P_MUX2:
tempReg = (uint32_t)((CPUSS->CM0_INT_CTL2 & bitMask) >> bitPos);
break;
case CY_SYSINT_CM0P_MUX3:
tempReg = (uint32_t)((CPUSS->CM0_INT_CTL3 & bitMask) >> bitPos);
break;
case CY_SYSINT_CM0P_MUX4:
tempReg = (uint32_t)((CPUSS->CM0_INT_CTL4 & bitMask) >> bitPos);
break;
case CY_SYSINT_CM0P_MUX5:
tempReg = (uint32_t)((CPUSS->CM0_INT_CTL5 & bitMask) >> bitPos);
break;
case CY_SYSINT_CM0P_MUX6:
tempReg = (uint32_t)((CPUSS->CM0_INT_CTL6 & bitMask) >> bitPos);
break;
case CY_SYSINT_CM0P_MUX7:
tempReg = (uint32_t)((CPUSS->CM0_INT_CTL7 & bitMask) >> bitPos);
break;
default:
tempReg = CY_SYSINT_CM0P_MUX_ERROR;
break;
}
return tempReg;
}
#endif
/*******************************************************************************
* Function Name: Cy_SysInt_GetState
****************************************************************************//**
*
* \brief Gets the enabled/disabled state of the Interrupt.
*
* For CM0+, this function returns the state of the CM0+ interrupt mux output
* feeding into the NVIC.
*
* \param config
* Interrupt configuration structure
*
* \return
* 1 if enabled, 0 if disabled
*
*******************************************************************************/
uint32_t Cy_SysInt_GetState(const cy_stc_sysint_t* config)
{
#if CY_CPU_CORTEX_M0P
if (config->intrSrc < 0)
{
return (*(NVIC->ISER) >> config->intrSrc) & CY_SYSINT_STATE_MASK;
}
else
{
return (*(NVIC->ISER) >> config->intrCm0p) & CY_SYSINT_STATE_MASK;
}
#else
return (*(NVIC->ISER) >> config->intrSrc) & CY_SYSINT_STATE_MASK;
#endif
}
/*******************************************************************************
* Function Name: Cy_SysInt_SetVector
****************************************************************************//**
*
* \brief Changes the ISR vector for the Interrupt.
*
* For CM0+, this function sets the interrupt vector for the interrupt mux
* output feeding into the NVIC.
*
* Note that this function relies on the assumption that the vector table is
* relocated to __ramVectors[RAM_VECTORS_SIZE] in SRAM. Otherwise it will
* return the address of the default ISR location in Flash vector table.
*
* \param config
* Interrrupt configuration structure
*
* \param userIsr
* Address of the ISR to set in the interrupt vector table
*
* \return
* Previous address of the ISR in the interrupt vector table, before the
* function call
*
*******************************************************************************/
cy_israddress Cy_SysInt_SetVector(const cy_stc_sysint_t* config, cy_israddress userIsr)
{
cy_israddress prevIsr;
#if CY_CPU_CORTEX_M0P
/* Only set the new vector if it was moved to __ramVectors */
if (SCB->VTOR == (uint32_t)&__ramVectors)
{
if (config->intrSrc < 0)
{
prevIsr = __ramVectors[CY_INT_IRQ_BASE + config->intrSrc];
__ramVectors[CY_INT_IRQ_BASE + config->intrSrc] = userIsr;
}
else
{
prevIsr = __ramVectors[CY_INT_IRQ_BASE + config->intrCm0p];
__ramVectors[CY_INT_IRQ_BASE + config->intrCm0p] = userIsr;
}
}
else
{
if (config->intrSrc < 0)
{
prevIsr = __Vectors[CY_INT_IRQ_BASE + config->intrSrc];
}
else
{
prevIsr = __Vectors[CY_INT_IRQ_BASE + config->intrCm0p];
}
}
#else
/* Only set the new vector if it was moved to __ramVectors */
if (SCB->VTOR == (uint32_t)&__ramVectors)
{
prevIsr = __ramVectors[CY_INT_IRQ_BASE + config->intrSrc];
__ramVectors[CY_INT_IRQ_BASE + config->intrSrc] = userIsr;
}
else
{
prevIsr = __Vectors[CY_INT_IRQ_BASE + config->intrSrc];
}
#endif
return prevIsr;
}
/*******************************************************************************
* Function Name: Cy_SysInt_GetVector
****************************************************************************//**
*
* \brief Gets the address of the current ISR vector for the Interrupt.
*
* For CM0+, this function returns the interrupt vector for the interrupt mux
* output feeding into the NVIC.
*
* Note that this function relies on the assumption that the vector table is
* relocated to __ramVectors[RAM_VECTORS_SIZE] in SRAM.
*
* \param config
* Interrupt configuration structure
*
* \return
* Address of the ISR in the interrupt vector table
*
*******************************************************************************/
cy_israddress Cy_SysInt_GetVector(const cy_stc_sysint_t* config)
{
#if CY_CPU_CORTEX_M0P
/* Only return the SRAM ISR address if it was moved to __ramVectors */
if (SCB->VTOR == (uint32_t)&__ramVectors)
{
if (config->intrSrc < 0)
{
return __ramVectors[CY_INT_IRQ_BASE + config->intrSrc];
}
else
{
return __ramVectors[CY_INT_IRQ_BASE + config->intrCm0p];
}
}
else
{
if (config->intrSrc < 0)
{
return __Vectors[CY_INT_IRQ_BASE + config->intrSrc];
}
else
{
return __Vectors[CY_INT_IRQ_BASE + config->intrCm0p];
}
}
#else
/* Only return the SRAM ISR address if it was moved to __ramVectors */
if (SCB->VTOR == (uint32_t)&__ramVectors)
{
return __ramVectors[CY_INT_IRQ_BASE + config->intrSrc];
}
else
{
return __Vectors[CY_INT_IRQ_BASE + config->intrSrc];
}
#endif
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */

View File

@ -0,0 +1,343 @@
/***************************************************************************//**
* \file cy_sysint.h
* \version 1.0
*
* \brief
* Provides an API declaration of the sysint driver
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_sysint System Interrupt (SysInt)
* \{
* The SysInt driver provides an API to configure the device peripheral interrupts.
* It provides a lightweight interface to complement the CMSIS core NVIC API.
* The provided functions are applicable for all cores in a device and they can
* be used to configure and connect device peripheral interrupts to one or more
* cores.
*
* \n
* <b> Initialization </b>
*
* To configure an interrupt, call Cy_SysInt_Init().
* Populate the configuration structure (cy_stc_sysint_t) and pass it as a parameter
* along with the ISR address. This initializes the interrupt and
* instructs the CPU to jump to the specified ISR vector upon a valid trigger.
*
* Populating the interrupt configuration structure differs slightly for the CM0+ core.
* This core supports only up to 32 peripheral interrupt channels. To allow all device
* interrupts to be routable to the NVIC of this core, there exists a 240:1 multiplexer
* at each of the 32 NVIC channels. Hence the configuration structure (cy_stc_sysint_t)
* must specify the device interrupt source (intSrc) and the CM0+ NVIC mux (intrCm0p).
*
* \n
* <b> Enable </b>
*
* After initializing an interrupt, use the CMSIS Core NVIC_EnableIRQ() function to
* enable it. The parameter used in this function call differs between the CM0+ cores
* and non-CM0+ cores due to the previously mentioned architectural differences.
* Given an initialization structure named config, the function should be called as
* follows:
*
* - Non-CM0+ : NVIC_EnableIRQ(config.intrSrc)
* - CM0+ : NVIC_EnableIRQ(config.intrCm0p)
*
* \section group_sysint_section_configuration_considerations Configuration Considerations
*
* For the Cortex-M0+ core, NVIC mux positions 28, 29, 30, and 31 are reserved for
* internal use by Cypress. These should not be used by the application code.
*
* \section group_sysint_more_information More Information
*
* Refer to the technical reference manual (TRM) and the device datasheet.
*
*
* \section group_sysint_MISRA MISRA-C Compliance
*
* The sysint driver does not have any specific deviations.
*
* \section group_sysint_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_sysint_macro Macro
* \defgroup group_sysint_globals Global variables
* \defgroup group_sysint_functions Functions
* \defgroup group_sysint_data_structures Data structures
* \defgroup group_sysint_enums Enumerated Types
*/
#if !defined(CY_SYSINT_H)
#define CY_SYSINT_H
#include <stddef.h>
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
#if defined(__cplusplus)
extern "C" {
#endif
/***************************************
* Global Variable
***************************************/
/**
* \addtogroup group_sysint_globals
* \{
*/
extern const cy_israddress __Vectors[]; /**< Vector table in Flash */
extern cy_israddress __ramVectors[]; /**< Relocated vector table in SRAM */
/** \} group_sysint_globals */
/***************************************
* Global Interrupt
***************************************/
/**
* \addtogroup group_sysint_macro
* \{
*/
/** Driver major version */
#define CY_SYSINT_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_SYSINT_DRV_VERSION_MINOR 0
/** SysInt driver ID */
#define CY_SYSINT_ID CY_PDL_DRV_ID(0x15u)
/** \} group_sysint_macro */
/***************************************
* Enumeration
***************************************/
/**
* \addtogroup group_sysint_enums
* \{
*/
/**
* SysInt Driver error codes
*/
typedef enum
{
CY_SYSINT_SUCCESS = 0x00u, /**< Returned successful */
CY_SYSINT_BAD_PARAM = CY_SYSINT_ID | CY_PDL_STATUS_ERROR | 0x01u, /**< Bad parameter was passed */
} cy_en_sysint_status_t;
/**
* Enumeration values for Cortex-M0+ NVIC multiplexer selection.
* Deep-sleep wakeup-capability is determined by the CPUSS_CM0_DPSLP_IRQ_NR
* parameter, where the first N number of muxes have the capability to trigger
* deep-sleep interrupts. A deep-sleep capable interrupt source must be
* connected to one of these muxes to be able to trigger in deep-sleep.
*/
typedef enum {
NvicMux0 = 0, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 0 */
NvicMux1 = 1, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 1 */
NvicMux2 = 2, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 2 */
NvicMux3 = 3, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 3 */
NvicMux4 = 4, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 4 */
NvicMux5 = 5, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 5 */
NvicMux6 = 6, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 6 */
NvicMux7 = 7, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 7 */
NvicMux8 = 8, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 8 */
NvicMux9 = 9, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 9 */
NvicMux10 = 10, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 10 */
NvicMux11 = 11, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 11 */
NvicMux12 = 12, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 12 */
NvicMux13 = 13, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 13 */
NvicMux14 = 14, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 14 */
NvicMux15 = 15, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 15 */
NvicMux16 = 16, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 16 */
NvicMux17 = 17, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 17 */
NvicMux18 = 18, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 18 */
NvicMux19 = 19, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 19 */
NvicMux20 = 20, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 20 */
NvicMux21 = 21, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 21 */
NvicMux22 = 22, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 22 */
NvicMux23 = 23, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 23 */
NvicMux24 = 24, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 24 */
NvicMux25 = 25, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 25 */
NvicMux26 = 26, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 26 */
NvicMux27 = 27, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 27 */
NvicMux28 = 28, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 28 */
NvicMux29 = 29, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 29 */
NvicMux30 = 30, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 30 */
NvicMux31 = 31, /**< NVIC Mux for mapping intrSrc to CM0+ NVIC input 31 */
} IRQn_CM0P_Type;
/** \} group_sysint_enums */
/***************************************
* Configuration Structure
***************************************/
/**
* \addtogroup group_sysint_data_structures
* \{
*/
/**
* Initialization configuration structure for a single interrupt channel
*/
typedef struct {
IRQn_Type intrSrc; /**< Interrupt source */
IRQn_CM0P_Type intrCm0p; /**< (CM0+ only) Maps intrSrc to 32 available CM0+ NVIC inputs */
uint32_t intrPriority; /**< Interrupt priority number (Refer to __NVIC_PRIO_BITS) */
} cy_stc_sysint_t;
/** \} group_sysint_data_structures */
/***************************************
* Constants
***************************************/
/** \cond INTERNAL */
#define CY_INT_IRQ_BASE (16u) /**< Start location of interrupts in the vector table */
#define CY_SYSINT_STATE_MASK (1ul) /**< Mask for interrupt state */
#define CY_SYSINT_STIR_MASK (0xfful) /**< Mask for software trigger interrupt register */
#define CY_SYSINT_CM0P_MUX_MASK (0xfful) /**< CM0+ NVIC multiplexer mask */
#define CY_SYSINT_CM0P_MUX_SHIFT (2u) /**< CM0+ NVIC multiplexer shift */
#define CY_SYSINT_CM0P_MUX_SCALE (3u) /**< CM0+ NVIC multiplexer scaling value */
#define CY_SYSINT_CM0P_MUX0 (0u) /**< CM0+ NVIC multiplexer register 0 */
#define CY_SYSINT_CM0P_MUX1 (1u) /**< CM0+ NVIC multiplexer register 1 */
#define CY_SYSINT_CM0P_MUX2 (2u) /**< CM0+ NVIC multiplexer register 2 */
#define CY_SYSINT_CM0P_MUX3 (3u) /**< CM0+ NVIC multiplexer register 3 */
#define CY_SYSINT_CM0P_MUX4 (4u) /**< CM0+ NVIC multiplexer register 4 */
#define CY_SYSINT_CM0P_MUX5 (5u) /**< CM0+ NVIC multiplexer register 5 */
#define CY_SYSINT_CM0P_MUX6 (6u) /**< CM0+ NVIC multiplexer register 6 */
#define CY_SYSINT_CM0P_MUX7 (7u) /**< CM0+ NVIC multiplexer register 7 */
#define CY_SYSINT_CM0P_MUX_ERROR (0xfffffffful) /**< Invalid CM0+ NVIC multiplexer error code */
/** \endcond */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_sysint_functions
* \{
*/
cy_en_sysint_status_t Cy_SysInt_Init(const cy_stc_sysint_t* config, cy_israddress userIsr);
uint32_t Cy_SysInt_GetState(const cy_stc_sysint_t* config);
cy_israddress Cy_SysInt_SetVector(const cy_stc_sysint_t* config, cy_israddress userIsr);
cy_israddress Cy_SysInt_GetVector(const cy_stc_sysint_t* config);
__STATIC_INLINE void Cy_SysInt_SetIntSourceNMI(const cy_stc_sysint_t* config);
__STATIC_INLINE uint32_t Cy_SysInt_GetIntSourceNMI(void);
#if (CY_CPU_CORTEX_M0P)
void Cy_SysInt_SetIntSource(const cy_stc_sysint_t* config);
uint32_t Cy_SysInt_GetIntSource(IRQn_CM0P_Type muxSel);
#else
__STATIC_INLINE void Cy_SysInt_SoftwareTrig(const cy_stc_sysint_t* config);
#endif
/*******************************************************************************
* Function Name: Cy_SysInt_SetIntSourceNMI
****************************************************************************//**
*
* \brief Sets the interrupt source of NMI.
*
* Setting this value to 240 disconnects the interrupt source from the NMI. The
* interrupt source must be a positive number.
*
* For CM0+, this function sets the interrupt mux output feeding into the
* NVIC as the source for NMI.
*
* \param config
* Interrupt configuration structure
*
*******************************************************************************/
__STATIC_INLINE void Cy_SysInt_SetIntSourceNMI(const cy_stc_sysint_t* config)
{
#if CY_CPU_CORTEX_M0P
CPUSS->CM0_NMI_CTL = config->intrCm0p;
#else
CPUSS->CM4_NMI_CTL = config->intrSrc;
#endif
}
/*******************************************************************************
* Function Name: Cy_SysInt_GetIntSourceNMI
****************************************************************************//**
*
* \brief Gets the interrupt source of the NMI.
*
* \return
* Interrupt Source. A value of 240 means that there is no interrupt source
* for the NMI, and an interrupt can be triggered only through software.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_SysInt_GetIntSourceNMI(void)
{
#if CY_CPU_CORTEX_M0P
return (CPUSS->CM0_NMI_CTL);
#else
return (CPUSS->CM4_NMI_CTL);
#endif
}
#if (!CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN)
/*******************************************************************************
* Function Name: Cy_SysInt_SoftwareTrig
****************************************************************************//**
*
* \brief Triggers an interrupt using software (Not applicable for CM0+).
*
* <b>Note</b> Only privileged software can enable unprivileged access to the
* Software Trigger Interrupt Register (STIR).
*
* \param config
* Interrupt configuration structure
*
*******************************************************************************/
__STATIC_INLINE void Cy_SysInt_SoftwareTrig(const cy_stc_sysint_t* config)
{
NVIC->STIR = config->intrSrc & CY_SYSINT_STIR_MASK;
}
#endif
/** \} group_sysint_functions */
#if defined(__cplusplus)
}
#endif
#endif /* CY_SYSINT_H */
/** \} group_sysint */
/* [] END OF FILE */

View File

@ -0,0 +1,654 @@
/***************************************************************************//**
* \file cy_syslib.c
* \version 1.0
*
* Description:
* Provides system API implementation for the Cypress PDL 3.0 syslib driver.
*
********************************************************************************
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_syslib.h"
#include "ipc/cy_ipc_drv.h"
/* Flash wait states (LP mode at 1.1v) */
#define CY_SYSLIB_FLASH_LP_WS_0_FREQ_MAX ( 24UL)
#define CY_SYSLIB_FLASH_LP_WS_1_FREQ_MAX ( 48UL)
#define CY_SYSLIB_FLASH_LP_WS_2_FREQ_MAX ( 72UL)
#define CY_SYSLIB_FLASH_LP_WS_3_FREQ_MAX ( 96UL)
#define CY_SYSLIB_FLASH_LP_WS_4_FREQ_MAX (120UL)
/* Flash wait states (ULP mode at 0.9v) */
#define CY_SYSLIB_FLASH_ULP_WS_0_FREQ_MAX ( 16UL)
#define CY_SYSLIB_FLASH_ULP_WS_1_FREQ_MAX ( 33UL)
#define CY_SYSLIB_FLASH_ULP_WS_2_FREQ_MAX ( 50UL)
/* ROM wait states for the slow clock domain (LP mode at 1.1v) */
#define CY_SYSLIB_ROM_LP_SLOW_WS_0_FREQ_MAX (100UL)
#define CY_SYSLIB_ROM_LP_SLOW_WS_1_FREQ_MAX (120UL)
/* ROM wait states for the slow clock domain (ULP mode at 0.9v) */
#define CY_SYSLIB_ROM_ULP_SLOW_WS_0_FREQ_MAX ( 25UL)
#define CY_SYSLIB_ROM_ULP_SLOW_WS_1_FREQ_MAX ( 50UL)
/* ROM wait states for the fast clock domain (LP mode at 1.1v) */
#define CY_SYSLIB_ROM_LP_FAST_WS_0_FREQ_MAX (120UL)
/* ROM wait states for the slow clock domain (ULP mode at 0.9v) */
#define CY_SYSLIB_ROM_ULP_FAST_WS_0_FREQ_MAX ( 50UL)
/* SRAM wait states for the slow clock domain (LP mode at 1.1v) */
#define CY_SYSLIB_RAM_LP_SLOW_WS_0_FREQ_MAX (100UL)
#define CY_SYSLIB_RAM_LP_SLOW_WS_1_FREQ_MAX (120UL)
/* SRAM wait states for the slow clock domain (ULP mode at 0.9v) */
#define CY_SYSLIB_RAM_ULP_SLOW_WS_0_FREQ_MAX ( 25UL)
#define CY_SYSLIB_RAM_ULP_SLOW_WS_1_FREQ_MAX ( 50UL)
/* SRAM wait states for the fast clock domain (LP mode at 1.1v) */
#define CY_SYSLIB_RAM_LP_FAST_WS_0_FREQ_MAX (120UL)
/* SRAM wait states for the fast clock domain (ULP mode at 0.9v) */
#define CY_SYSLIB_RAM_ULP_FAST_WS_0_FREQ_MAX ( 50UL)
#if !defined(NDEBUG)
char_t cy_assertFileName[CY_MAX_FILE_NAME_SIZE];
uint32_t cy_assertLine;
#endif /* NDEBUG */
#if (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED)
cy_stc_fault_frame_t cy_faultFrame;
#endif /* (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) */
static void Cy_SysLib_SetWaitStates_ULP(uint32_t clkHfMHz);
static void Cy_SysLib_SetWaitStates_LP(uint32_t clkHfMHz);
/*******************************************************************************
* Function Name: Cy_SysLib_Delay
****************************************************************************//**
*
* The function delays by the specified number of milliseconds.
* By default, the number of cycles to delay is calculated based on the
* SystemCoreClock.
* If the parameter is bigger than CY_DELAY_MS_OVERFLOW(32kHz delay), run an
* additional loop to prevent an overflow.
*
* \param milliseconds The number of milliseconds to delay.
*
*******************************************************************************/
void Cy_SysLib_Delay(uint32_t milliseconds)
{
while (milliseconds > CY_DELAY_MS_OVERFLOW)
{
/* This loop prevents overflow.
* At 100MHz, milliseconds * cy_delayFreqKhz it overflows at about 42 seconds
*/
Cy_SysLib_DelayCycles(cy_delay32kMs);
milliseconds -= CY_DELAY_MS_OVERFLOW;
}
Cy_SysLib_DelayCycles(milliseconds * cy_delayFreqKhz);
}
/*******************************************************************************
* Function Name: Cy_SysLib_DelayUs
****************************************************************************//**
*
* The function delays by the specified number of microseconds.
* By default, the number of cycles to delay is calculated based on the
* SystemCoreClock.
*
* \param microseconds The number of microseconds to delay.
*
*******************************************************************************/
void Cy_SysLib_DelayUs(uint16_t microseconds)
{
Cy_SysLib_DelayCycles((uint32_t) microseconds * cy_delayFreqMhz);
}
/*******************************************************************************
* Function Name: Cy_SysLib_Halt
****************************************************************************//**
*
* This function halts the CPU but only the CPU which calls the function.
* It doesn't affect other CPUs.
*
* \param reason The value to be used during debugging.
*
* \note The function executes the BKPT instruction for halting CPU and is
* intended to be used for debug purposes. A regular use case requires
* Debugger attachment before the function call.
* The BKPT instruction causes the CPU to enter the Debug state. Debug
* tools can use this to investigate the system state, when the
* instruction at a particular address is reached.
*
* \note Execution of a BKPT instruction without a debugger attached produces
* a fault. The fault results in the HardFault exception being taken
* or causes Lockup state if it occurs in the NMI or HardFault handler.
* The default HardFault handler make a software reset if the build option
* is release mode (NDEBUG). If the build option is debug mode, the system
* will stay in the infinite loop of the Cy_SysLib_ProcessingFault()
* function.
*
*******************************************************************************/
__NO_RETURN void Cy_SysLib_Halt(uint32_t reason)
{
if(0u != reason)
{
/* To remove an unreferenced local variable warning */
}
#if defined (__ARMCC_VERSION)
__breakpoint(0x0);
while(1u) {}
#elif defined(__GNUC__)
__asm(" bkpt 1");
__builtin_unreachable();
#elif defined (__ICCARM__)
__asm(" bkpt 1");
#else
#error "Unsupported toolchain"
#endif /* (__ARMCC_VERSION) */
}
/*******************************************************************************
* Function Name: Cy_SysLib_ClearFlashCacheAndBuffer
****************************************************************************//**
*
* This function invalidates the flash cache and buffer. It ensures the valid
* data is read from flash instead of using outdated data from the cache.
* The caches' LRU structure is also reset to their default state.
*
* \note The operation takes a maximum of three clock cycles on the slowest of
* the clk_slow and clk_fast clocks.
*
*******************************************************************************/
void Cy_SysLib_ClearFlashCacheAndBuffer(void)
{
FLASHC->FLASH_CMD = FLASHC_FLASH_CMD_INV_Msk;
}
/*******************************************************************************
* Function Name: Cy_SysLib_GetResetReason
****************************************************************************//**
*
* The function returns the cause for the latest reset(s) that occurred in
* the system. The reset causes in the registers are two separated parts which
* are HFCLK error and system faults.
* The return results are consolidated reset causes for both parts by
* reading both RES_CAUSE and RES_CAUSE2 registers.
*
* \return The cause of a system reset.
*
* | Name | Value
* |-------------------------------|---------------------
* | CY_SYSLIB_RESET_HWWDT | 0x00001 (bit0)
* | CY_SYSLIB_RESET_ACT_FAULT | 0x00002 (bit1)
* | CY_SYSLIB_RESET_DPSLP_FAULT | 0x00004 (bit2)
* | CY_SYSLIB_RESET_CSV_WCO_LOSS | 0x00008 (bit3)
* | CY_SYSLIB_RESET_SOFT | 0x00010 (bit4)
* | CY_SYSLIB_RESET_SWWDT0 | 0x00020 (bit5)
* | CY_SYSLIB_RESET_SWWDT1 | 0x00040 (bit6)
* | CY_SYSLIB_RESET_SWWDT2 | 0x00080 (bit7)
* | CY_SYSLIB_RESET_SWWDT3 | 0x00100 (bit8)
* | CY_SYSLIB_RESET_HFCLK_LOSS | 0x10000 (bit16)
* | CY_SYSLIB_RESET_HFCLK_ERR | 0x20000 (bit17)
*
*******************************************************************************/
uint32_t Cy_SysLib_GetResetReason(void)
{
uint32_t retVal;
retVal = SRSS->RES_CAUSE |
((CY_LO16(SRSS->RES_CAUSE2) > 0u) ? CY_SYSLIB_RESET_HFCLK_LOSS : 0u) |
((CY_HI16(SRSS->RES_CAUSE2) > 0u) ? CY_SYSLIB_RESET_HFCLK_ERR : 0u);
return (retVal);
}
/*******************************************************************************
* Function Name: Cy_SysLib_GetNumHfclkResetCause
****************************************************************************//**
*
* This function returns the number of HF_CLK which is a reset cause (RES_CAUSE2)
* by a loss or an error of the high frequency clock.
*
* The Clock supervisors (CSV) can make a reset as CSV_FREQ_ACTION setting
* when a CSV frequency anomaly is detected. The function returns the index
* of HF_CLK, if a reset occurred due to an anomaly HF_CLK. There are two
* different options for monitoring on HF_CLK which are a frequency loss
* and a frequency error.
*
* \return
* - The number HF_CLK from Clock Supervisor High Frequency Loss: Bits[15:0]
* - The number HF_CLK from Clock Supervisor High Frequency error: Bits[31:16]
*
*******************************************************************************/
uint32_t Cy_SysLib_GetNumHfclkResetCause(void)
{
return (SRSS->RES_CAUSE2);
}
/*******************************************************************************
* Function Name: Cy_SysLib_ClearResetReason
****************************************************************************//**
*
* This function clears the values of RES_CAUSE and RES_CAUSE2.
*
*******************************************************************************/
void Cy_SysLib_ClearResetReason(void)
{
SRSS->RES_CAUSE = SRSS->RES_CAUSE;
SRSS->RES_CAUSE2 = SRSS->RES_CAUSE2;
}
#if (CY_CPU_CORTEX_M0P) || defined(CY_DOXYGEN)
/*******************************************************************************
* Function Name: Cy_SysLib_SoftResetCM4
****************************************************************************//**
*
* This function performs a CM4 Core software reset using the CM4_PWR_CTL
* register.
*
* \note This function should be called only when the CM4 core is in Deep
* Sleep mode.
* \note This function will not reset CM0+ Core.
*
*******************************************************************************/
void Cy_SysLib_SoftResetCM4(void)
{
volatile uint32_t msg = CY_IPC_DATA_FOR_CM4_SOFT_RESET;
/* Tries to acquire the IPC structure and pass the arguments to SROM API.
* SROM API parameters:
* ipcPtr: IPC_STRUCT0 - IPC Structure 0 reserved for M0+ Secure Access.
* notifyEvent_Intr: 1u - IPC Interrupt Structure 1 is used for Releasing IPC 0 (M0+ NMI Handler).
* msgPtr: &msg - The address of SRAM with the API's parameters.
*/
if(CY_IPC_DRV_SUCCESS != Cy_IPC_DRV_SendMsgPtr(IPC_STRUCT0, 1u, (void *) &msg))
{
CY_ASSERT(0u != 0u);
}
}
#endif /* CY_CPU_CORTEX_M0P || defined(CY_DOXYGEN) */
/*******************************************************************************
* Function Name: Cy_SysLib_GetUniqueId
****************************************************************************//**
*
* This function returns the silicon unique ID.
* The ID includes Die lot[3]#, Die Wafer#, Die X, Die Y, DIE Sort# and
* Die Minor#
*
* \return
* A combined 64-bit unique ID.
* [63:56] - DIE_MINOR
* [55:48] - DIE_SORT
* [47:40] - DIE_Y
* [39:32] - DIE_X
* [31:24] - DIE_WAFER
* [23:16] - DIE_LOT[2]
* [15: 8] - DIE_LOT[1]
* [ 7: 0] - DIE_LOT[0]
*
*******************************************************************************/
uint64_t Cy_SysLib_GetUniqueId(void)
{
uint64_t uniqueId;
uniqueId = ((uint64_t)SFLASH->DIE_MINOR << CY_UNIQUE_ID_DIE_MINOR_Pos) |
((uint64_t)SFLASH->DIE_SORT << CY_UNIQUE_ID_DIE_SORT_Pos) |
((uint64_t)SFLASH->DIE_Y << CY_UNIQUE_ID_DIE_Y_Pos) |
((uint64_t)SFLASH->DIE_X << CY_UNIQUE_ID_DIE_X_Pos) |
((uint64_t)SFLASH->DIE_WAFER << CY_UNIQUE_ID_DIE_WAFER_Pos) |
((uint64_t)SFLASH->DIE_LOT[2u] << CY_UNIQUE_ID_DIE_LOT_2_Pos) |
((uint64_t)SFLASH->DIE_LOT[1u] << CY_UNIQUE_ID_DIE_LOT_1_Pos) |
((uint64_t)SFLASH->DIE_LOT[0u] << CY_UNIQUE_ID_DIE_LOT_0_Pos);
return (uniqueId);
}
#if (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) || defined(CY_DOXYGEN)
/*******************************************************************************
* Function Name: Cy_SysLib_FaultHandler
****************************************************************************//**
*
* This function stores the ARM Cortex registers into a non-zero init area for
* debugging. This function calls Cy_SysLib_ProcessingFault() after storing all
* the information.
*
* \param faultStackAddr The address of the stack pointer, indicates the lowest
* address in the fault stack frame to be stored.
* \note This function stores the fault stack frame only for the first occurred
* fault.
* \note This function sets two flags into the fault structure: one checks
* which core cause fault, another checks the type of fault for CM4 core.
* The flags should be cleared after analysis of the stored
* register values, to have possibility to distinguish the next fault.
* \note The PDL doesn't provide an API which can analyse the stored register
* values. A user has to add additional functions for the analysis,
* if necessary.
* \note The CY_ARM_FAULT_DEBUG macro defines if the Fault Handler is enabled.
* By default it is set to CY_ARM_FAULT_DEBUG_ENABLED and enables the
* Fault Handler.
* If there is a necessity to save memory or have some specific custom
* handler, etc. then CY_ARM_FAULT_DEBUG should be redefined as
* CY_ARM_FAULT_DEBUG_DISABLED. To do this the following definition should
* be added to the compiler Command Line (through the project Build
* Settings): "-D CY_ARM_FAULT_DEBUG=0".
*
*******************************************************************************/
void Cy_SysLib_FaultHandler(uint32_t const *faultStackAddr)
{
#if (CY_CPU_CORTEX_M0P)
if(CY_CM0P_FAULT_TYPE != cy_faultFrame.fault)
{
cy_faultFrame.fault = CY_CM0P_FAULT_TYPE; /* CM0P fault occurred. */
#elif (CY_CPU_CORTEX_M4)
if(CY_CM4_FAULT_TYPE != cy_faultFrame.fault)
{
cy_faultFrame.fault = CY_CM4_FAULT_TYPE; /* CM4 fault occurred. */
/* Stores the Configurable Fault Status Register state with the fault cause */
cy_faultFrame.cfsr = SCB->CFSR;
cy_faultFrame.faultType = CY_NON_FPU_FAULT_TYPE;
#endif /* CY_CPU_CORTEX_M0P */
/* Stores general registers */
cy_faultFrame.r0 = faultStackAddr[CY_R0_Pos];
cy_faultFrame.r1 = faultStackAddr[CY_R1_Pos];
cy_faultFrame.r2 = faultStackAddr[CY_R2_Pos];
cy_faultFrame.r3 = faultStackAddr[CY_R3_Pos];
cy_faultFrame.r12 = faultStackAddr[CY_R12_Pos];
cy_faultFrame.lr = faultStackAddr[CY_LR_Pos];
cy_faultFrame.pc = faultStackAddr[CY_PC_Pos];
cy_faultFrame.psr = faultStackAddr[CY_PSR_Pos];
#if (CY_CPU_CORTEX_M4) && ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)))
/* Checks cumulative exception bits for floating-point exceptions */
if(0U != (__get_FPSCR() & (CY_FPSCR_IXC_Msk | CY_FPSCR_IDC_Msk)))
{
cy_faultFrame.faultType = CY_FPU_FAULT_TYPE;
cy_faultFrame.s0 = faultStackAddr[CY_S0_Pos];
cy_faultFrame.s1 = faultStackAddr[CY_S1_Pos];
cy_faultFrame.s2 = faultStackAddr[CY_S2_Pos];
cy_faultFrame.s3 = faultStackAddr[CY_S3_Pos];
cy_faultFrame.s4 = faultStackAddr[CY_S4_Pos];
cy_faultFrame.s5 = faultStackAddr[CY_S5_Pos];
cy_faultFrame.s6 = faultStackAddr[CY_S6_Pos];
cy_faultFrame.s7 = faultStackAddr[CY_S7_Pos];
cy_faultFrame.s8 = faultStackAddr[CY_S8_Pos];
cy_faultFrame.s9 = faultStackAddr[CY_S9_Pos];
cy_faultFrame.s10 = faultStackAddr[CY_S10_Pos];
cy_faultFrame.s11 = faultStackAddr[CY_S11_Pos];
cy_faultFrame.s12 = faultStackAddr[CY_S12_Pos];
cy_faultFrame.s13 = faultStackAddr[CY_S13_Pos];
cy_faultFrame.s14 = faultStackAddr[CY_S14_Pos];
cy_faultFrame.s15 = faultStackAddr[CY_S15_Pos];
cy_faultFrame.fpscr = faultStackAddr[CY_FPSCR_Pos];
}
#endif /* CY_CPU_CORTEX_M4 && __FPU_PRESENT */
}
Cy_SysLib_ProcessingFault();
}
/*******************************************************************************
* Function Name: Cy_SysLib_ProcessingFault
****************************************************************************//**
*
* This function determines how to process the current fault state. By default
* in case of exception the system will stay in the infinite loop of this
* function.
*
* \note This function has WEAK option, so the user can redefine the function
* for a custom processing.
* For example the function redefinition could be constructed from fault
* stack processing and NVIC_SystemReset() function call.
*
*******************************************************************************/
CY_WEAK void Cy_SysLib_ProcessingFault(void)
{
while(1u) {}
}
#endif /* (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) || defined(CY_DOXYGEN) */
/*******************************************************************************
* Function Name: Cy_SysLib_SetWaitStates
****************************************************************************//**
*
* Sets the number of clock cycles the cache will wait for, before it samples
* data coming back from ROM, SRAM, and Flash.
*
* Call this function before increasing the HFClk0 High Frequency clock.
* Call this function optionally after lowering the HFClk0 High Frequency clock
* in order to improve the CPU performance.
*
* Also, call this function before switching core supply regulator voltage (LDO
* or SIMO Buck) from 1.1V to 0.9V.
* Call this function optionally after switching core supply regulator voltage
* from 0.9V to 1.1V in order to improve the CPU performance.
*
* \param ulpMode The device power mode.
* true, if the device should be switched to the ULP mode (nominal voltage of
* the core supply regulator should be switched to 0.9V);
* false, if the device should be switched to the LP mode (nominal voltage of
* the core supply regulator should be switched to 1.1V).
*
* \note Refer to the device TRM for low power modes description.
*
* \param clkHfMHz The HFClk0 clock frequency in MHz.
*
*******************************************************************************/
void Cy_SysLib_SetWaitStates(bool ulpMode, uint32_t clkHfMHz)
{
if (ulpMode)
{
Cy_SysLib_SetWaitStates_ULP(clkHfMHz);
}
else
{
Cy_SysLib_SetWaitStates_LP(clkHfMHz);
}
}
/*******************************************************************************
* Function Name: Cy_SysLib_SetWaitStates_LP
****************************************************************************//**
*
* Sets the ROM, SRAM, and Flash wait states for the low power mode.
* This function is called by Cy_SysLib_SetWaitStates().
*
*******************************************************************************/
static void Cy_SysLib_SetWaitStates_LP(uint32_t clkHfMHz)
{
uint32_t waitStates;
/* ROM */
if (clkHfMHz < CY_SYSLIB_ROM_LP_SLOW_WS_0_FREQ_MAX)
{
waitStates = 0UL;
} else if (clkHfMHz <= CY_SYSLIB_ROM_LP_SLOW_WS_1_FREQ_MAX)
{
waitStates = 1UL;
} else
{
waitStates = 3UL;
}
CPUSS->ROM_CTL = _CLR_SET_FLD32U(CPUSS->ROM_CTL, CPUSS_ROM_CTL_SLOW_WS, waitStates);
if (clkHfMHz <= CY_SYSLIB_ROM_LP_FAST_WS_0_FREQ_MAX)
{
waitStates = 0UL;
} else
{
waitStates = 3UL;
}
CPUSS->ROM_CTL = _CLR_SET_FLD32U(CPUSS->ROM_CTL, CPUSS_ROM_CTL_FAST_WS, waitStates);
/* SRAM */
if (clkHfMHz < CY_SYSLIB_RAM_LP_SLOW_WS_0_FREQ_MAX)
{
waitStates = 0UL;
} else if (clkHfMHz <= CY_SYSLIB_RAM_LP_SLOW_WS_1_FREQ_MAX)
{
waitStates = 1UL;
} else
{
waitStates = 3UL;
}
CPUSS->RAM0_CTL0 = _CLR_SET_FLD32U(CPUSS->RAM0_CTL0, CPUSS_RAM0_CTL0_SLOW_WS, waitStates);
#if defined (RAMC1_PRESENT) && (RAMC1_PRESENT == 1UL)
CPUSS->RAM1_CTL0 = _CLR_SET_FLD32U(CPUSS->RAM1_CTL0, CPUSS_RAM1_CTL0_SLOW_WS, waitStates);
#endif /* defined (RAMC1_PRESENT) && (RAMC1_PRESENT == 1UL) */
#if defined (RAMC2_PRESENT) && (RAMC2_PRESENT == 1UL)
CPUSS->RAM2_CTL0 = _CLR_SET_FLD32U(CPUSS->RAM2_CTL0, CPUSS_RAM2_CTL0_SLOW_WS, waitStates);
#endif /* defined (RAMC2_PRESENT) && (RAMC2_PRESENT == 1UL) */
if (clkHfMHz <= CY_SYSLIB_RAM_LP_FAST_WS_0_FREQ_MAX)
{
waitStates = 0UL;
} else
{
waitStates = 3UL;
}
CPUSS->RAM0_CTL0 = _CLR_SET_FLD32U(CPUSS->RAM0_CTL0, CPUSS_RAM0_CTL0_FAST_WS, waitStates);
#if defined (RAMC1_PRESENT) && (RAMC1_PRESENT == 1UL)
CPUSS->RAM1_CTL0 = _CLR_SET_FLD32U(CPUSS->RAM1_CTL0, CPUSS_RAM1_CTL0_SLOW_WS, waitStates);
#endif /* defined (RAMC1_PRESENT) && (RAMC1_PRESENT == 1UL) */
#if defined (RAMC2_PRESENT) && (RAMC2_PRESENT == 1UL)
CPUSS->RAM2_CTL0 = _CLR_SET_FLD32U(CPUSS->RAM2_CTL0, CPUSS_RAM2_CTL0_SLOW_WS, waitStates);
#endif /* defined (RAMC2_PRESENT) && (RAMC2_PRESENT == 1UL) */
/* Flash */
if (clkHfMHz <= CY_SYSLIB_FLASH_LP_WS_0_FREQ_MAX)
{
waitStates = 0UL;
} else if (clkHfMHz <= CY_SYSLIB_FLASH_LP_WS_1_FREQ_MAX)
{
waitStates = 1UL;
} else if (clkHfMHz <= CY_SYSLIB_FLASH_LP_WS_2_FREQ_MAX)
{
waitStates = 2UL;
} else if (clkHfMHz <= CY_SYSLIB_FLASH_LP_WS_3_FREQ_MAX)
{
waitStates = 3UL;
} else if (clkHfMHz <= CY_SYSLIB_FLASH_LP_WS_4_FREQ_MAX)
{
waitStates = 4UL;
} else
{
waitStates = 5UL;
}
FLASHC->FLASH_CTL = _CLR_SET_FLD32U(FLASHC->FLASH_CTL, FLASHC_FLASH_CTL_MAIN_WS, waitStates);
}
/*******************************************************************************
* Function Name: Cy_SysLib_SetWaitStates_ULP
****************************************************************************//**
*
* Sets the ROM, SRAM, and Flash wait states for the ultra-low power mode.
* This function is called by Cy_SysLib_SetWaitStates().
*
*******************************************************************************/
#if (SRSS_SIMOBUCK_PRESENT == 1UL)
static void Cy_SysLib_SetWaitStates_ULP(uint32_t clkHfMHz)
{
uint32_t waitStates;
/* ROM */
if (clkHfMHz < CY_SYSLIB_ROM_ULP_SLOW_WS_0_FREQ_MAX)
{
waitStates = 0UL;
} else if (clkHfMHz <= CY_SYSLIB_ROM_ULP_SLOW_WS_1_FREQ_MAX)
{
waitStates = 1UL;
} else
{
waitStates = 3UL;
}
CPUSS->ROM_CTL = _CLR_SET_FLD32U(CPUSS->ROM_CTL, CPUSS_ROM_CTL_SLOW_WS, waitStates);
if (clkHfMHz <= CY_SYSLIB_ROM_ULP_FAST_WS_0_FREQ_MAX)
{
waitStates = 0UL;
} else
{
waitStates = 2UL;
}
CPUSS->ROM_CTL = _CLR_SET_FLD32U(CPUSS->ROM_CTL, CPUSS_ROM_CTL_FAST_WS, waitStates);
/* SRAM */
if (clkHfMHz < CY_SYSLIB_RAM_ULP_SLOW_WS_0_FREQ_MAX)
{
waitStates = 0UL;
} else if (clkHfMHz <= CY_SYSLIB_RAM_ULP_SLOW_WS_1_FREQ_MAX)
{
waitStates = 1UL;
} else
{
waitStates = 3UL;
}
CPUSS->RAM0_CTL0 = _CLR_SET_FLD32U(CPUSS->RAM0_CTL0, CPUSS_RAM0_CTL0_SLOW_WS, waitStates);
#if defined (RAMC1_PRESENT) && (RAMC1_PRESENT == 1UL)
CPUSS->RAM1_CTL0 = _CLR_SET_FLD32U(CPUSS->RAM1_CTL0, CPUSS_RAM1_CTL0_SLOW_WS, waitStates);
#endif /* defined (RAMC1_PRESENT) && (RAMC1_PRESENT == 1UL) */
#if defined (RAMC2_PRESENT) && (RAMC2_PRESENT == 1UL)
CPUSS->RAM2_CTL0 = _CLR_SET_FLD32U(CPUSS->RAM2_CTL0, CPUSS_RAM2_CTL0_SLOW_WS, waitStates);
#endif /* defined (RAMC2_PRESENT) && (RAMC2_PRESENT == 1UL) */
if (clkHfMHz <= CY_SYSLIB_RAM_ULP_FAST_WS_0_FREQ_MAX)
{
waitStates = 0UL;
} else
{
waitStates = 2UL;
}
CPUSS->RAM0_CTL0 = _CLR_SET_FLD32U(CPUSS->RAM0_CTL0, CPUSS_RAM0_CTL0_FAST_WS, waitStates);
#if defined (RAMC1_PRESENT) && (RAMC1_PRESENT == 1UL)
CPUSS->RAM1_CTL0 = _CLR_SET_FLD32U(CPUSS->RAM1_CTL0, CPUSS_RAM1_CTL0_SLOW_WS, waitStates);
#endif /* defined (RAMC1_PRESENT) && (RAMC1_PRESENT == 1UL) */
#if defined (RAMC2_PRESENT) && (RAMC2_PRESENT == 1UL)
CPUSS->RAM2_CTL0 = _CLR_SET_FLD32U(CPUSS->RAM2_CTL0, CPUSS_RAM2_CTL0_SLOW_WS, waitStates);
#endif /* defined (RAMC2_PRESENT) && (RAMC2_PRESENT == 1UL) */
/* Flash */
if (clkHfMHz <= CY_SYSLIB_FLASH_ULP_WS_0_FREQ_MAX)
{
waitStates = 0UL;
} else if (clkHfMHz <= CY_SYSLIB_FLASH_ULP_WS_1_FREQ_MAX)
{
waitStates = 1UL;
} else if (clkHfMHz <= CY_SYSLIB_FLASH_ULP_WS_2_FREQ_MAX)
{
waitStates = 2UL;
} else
{
waitStates = 4UL;
}
FLASHC->FLASH_CTL = _CLR_SET_FLD32U(FLASHC->FLASH_CTL, FLASHC_FLASH_CTL_MAIN_WS, waitStates);
}
#endif /* (SRSS_SIMOBUCK_PRESENT == 1UL) */
/* [] END OF FILE */

View File

@ -0,0 +1,800 @@
/***************************************************************************//**
* \file cy_syslib.h
* \version 1.0
*
* Provides an API declaration of the syslib driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_syslib System Library (SysLib)
* \{
* The system libraries provide APIs that can be called in the user application
* to handle the timing, logical checking or register.
*
* SysLib driver contains a set of different system functions. These functions
* can be called in the application routine. Some features of the system library:
* * Delay functions
* * Register read/write macro
* * Assert and Halt
* * Software reset
* * Reading a reset cause
* * API to invalidate the flash cache and buffer
* * Data manipulation
* * A variable type definition from MISRA-C specifying signedness
* * Cross compiler compatible attributes
* * Get silicon unique ID API
*
* \section group_syslib_configuration Configuration Considerations
* There are no general SysLib configuration concerns.
*
* \section group_syslib_more_information More Information
* Refer to the technical reference manual (TRM).
*
* \section group_syslib_MISRA MISRA Compliance
* The SysLib driver does not have any specific deviations.
*
* \section group_syslib_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_syslib_macro Macro
* \defgroup group_syslib_functions Functions
* \defgroup group_syslib_data_structures Data Structures
*
*/
#if !defined(_CY_SYSLIB_H_)
#define _CY_SYSLIB_H_
#if !defined(NDEBUG)
#include <string.h>
#endif /* NDEBUG */
#include <stdint.h>
#include <stdbool.h>
#include "cy_device_headers.h"
#if defined(__cplusplus)
extern "C" {
#endif /* defined(__cplusplus) */
#if defined( __ICCARM__ )
/* Suppress the warning for multiple volatile variables in an expression. */
/* This is common for drivers code and the usage is not order-dependent. */
#pragma diag_suppress=Pa082
#endif /* defined( __ICCARM__ ) */
/**
* \addtogroup group_syslib_data_structures
* \{
* <p>The base types. Acceptable types from MISRA-C specifying signedness and size.
* These types must not be used. The default types should be used instead.
* These types are left for backward compatibility only.</p>
*/
typedef uint8_t uint8; /**< Alias to uint8_t for backward compatibility */
typedef uint16_t uint16; /**< Alias to uint16_t for backward compatibility */
typedef uint32_t uint32; /**< Alias to uint32_t for backward compatibility */
typedef int8_t int8; /**< Alias to int8_t for backward compatibility */
typedef int16_t int16; /**< Alias to int16_t for backward compatibility */
typedef int32_t int32; /**< Alias to int32_t for backward compatibility */
typedef float float32; /**< Alias to float for backward compatibility */
typedef double float64; /**< Alias to double for backward compatibility */
typedef int64_t int64; /**< Alias to int64_t for backward compatibility */
typedef uint64_t uint64; /**< Alias to uint64_t for backward compatibility */
/* Signed or unsigned depending on the compiler selection */
typedef char char8; /**< Alias to char for backward compatibility */
/* MISRA rule 6.3 recommends use specific-length typedef for the basic
* numerical types of signed and unsigned variants of char, float, and double.
*/
typedef char char_t; /**< Specific-length typedef for the basic numerical types of char */
typedef float float32_t; /**< Specific-length typedef for the basic numerical types of float */
typedef double float64_t; /**< Specific-length typedef for the basic numerical types of double */
/*******************************************************************************
* Hardware Register Types
*******************************************************************************/
typedef volatile uint8_t reg8; /**< Alias to uint8_t for backward compatibility */
typedef volatile uint16_t reg16; /**< Alias to uint16_t for backward compatibility */
typedef volatile uint32_t reg32; /**< Alias to uint32_t for backward compatibility */
/*******************************************************************************
* General cytypes
*******************************************************************************/
/** ARM 32-bit status value */
typedef uint32_t cy_status;
/** \cond INTERNAL */
/** ARM 32-bit status value for backward compatibility with the UDB components. Do not use it in your code. */
typedef uint32_t cystatus;
/** \endcond */
/** \} group_syslib_data_structures */
/**
* \addtogroup group_syslib_macro
* \{
*/
/******************************************************************************
* Macros
*****************************************************************************/
#define CY_CPU_CORTEX_M0P (__CORTEX_M == 0) /**< CM0+ core CPU Code */
#define CY_CPU_CORTEX_M4 (__CORTEX_M == 4) /**< CM4 core CPU Code */
/** Macro to disable the Fault Handler */
#define CY_ARM_FAULT_DEBUG_DISABLED (0u)
/** Macro to enable the Fault Handler */
#define CY_ARM_FAULT_DEBUG_ENABLED (1u)
#if !defined(CY_ARM_FAULT_DEBUG)
/** Macro defines if the Fault Handler is enabled. Enabled by default. */
#define CY_ARM_FAULT_DEBUG (CY_ARM_FAULT_DEBUG_ENABLED)
#endif /* CY_ARM_FAULT_DEBUG */
/**
* \defgroup group_syslib_macro_status_codes Status codes
* \{
* Function status type codes
*/
#define CY_PDL_STATUS_CODE_Pos (0u) /**< The module status code position in the status code */
#define CY_PDL_STATUS_TYPE_Pos (16u) /**< The status type position in the status code */
#define CY_PDL_MODULE_ID_Pos (18u) /**< The software module ID position in the status code */
#define CY_PDL_STATUS_INFO (0UL << CY_PDL_STATUS_TYPE_Pos) /**< Information status type */
#define CY_PDL_STATUS_WARNING (1UL << CY_PDL_STATUS_TYPE_Pos) /**< Warning status type */
#define CY_PDL_STATUS_ERROR (2UL << CY_PDL_STATUS_TYPE_Pos) /**< Error status type */
#define CY_PDL_MODULE_ID_Msk (0x3FFFu) /**< The software module ID mask */
/* Get the software PDL module ID */
#define CY_PDL_DRV_ID(id) ((uint32_t)((uint32_t)((id) & CY_PDL_MODULE_ID_Msk) << CY_PDL_MODULE_ID_Pos))
#define CY_SYSLIB_ID CY_PDL_DRV_ID(0x11u) /**< SYSLIB PDL ID */
/** \} group_syslib_macro_status_codes */
/** \} group_syslib_macro */
/**
* \addtogroup group_syslib_data_structures
* \{
*/
/** The SysLib status code structure. */
typedef enum
{
CY_SYSLIB_SUCCESS = 0x00UL, /**< Success status code */
CY_SYSLIB_BAD_PARAM = CY_SYSLIB_ID | CY_PDL_STATUS_ERROR | 0x01UL, /**< Bad parameter status code */
CY_SYSLIB_TIMEOUT = CY_SYSLIB_ID | CY_PDL_STATUS_ERROR | 0x02UL, /**< Time out status code */
CY_SYSLIB_INVALID_STATE = CY_SYSLIB_ID | CY_PDL_STATUS_ERROR | 0x03UL, /**< Invalid state status code */
CY_SYSLIB_UNKNOWN = CY_SYSLIB_ID | CY_PDL_STATUS_ERROR | 0xFFUL /**< Unknown status code */
} cy_en_syslib_status_t;
#if (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED)
/** The Fault configuration structure. */
typedef struct
{
uint32_t fault; /**< Indicates if the fault occurred */
uint32_t r0; /**< R0 register content */
uint32_t r1; /**< R1 register content */
uint32_t r2; /**< R2 register content */
uint32_t r3; /**< R3 register content */
uint32_t r12; /**< R12 register content */
uint32_t lr; /**< LR register content */
uint32_t pc; /**< PC register content */
uint32_t psr; /**< PSR register content */
#if (CY_CPU_CORTEX_M4)
uint32_t cfsr; /**< CFSR register content */
uint32_t faultType; /**< FPU or regular fault type */
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)))
uint32_t s0; /**< FPU S0 register content */
uint32_t s1; /**< FPU S1 register content */
uint32_t s2; /**< FPU S2 register content */
uint32_t s3; /**< FPU S3 register content */
uint32_t s4; /**< FPU S4 register content */
uint32_t s5; /**< FPU S5 register content */
uint32_t s6; /**< FPU S6 register content */
uint32_t s7; /**< FPU S7 register content */
uint32_t s8; /**< FPU S8 register content */
uint32_t s9; /**< FPU S9 register content */
uint32_t s10; /**< FPU S10 register content */
uint32_t s11; /**< FPU S11 register content */
uint32_t s12; /**< FPU S12 register content */
uint32_t s13; /**< FPU S13 register content */
uint32_t s14; /**< FPU S14 register content */
uint32_t s15; /**< FPU S15 register content */
uint32_t fpscr; /**< FPU FPSCR register content */
#endif /* __FPU_PRESENT */
#endif /* CY_CPU_CORTEX_M4 */
} cy_stc_fault_frame_t;
#endif /* (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) */
/** \} group_syslib_data_structures */
/**
* \addtogroup group_syslib_macro
* \{
*/
/** Driver major version */
#define CY_SYSLIB_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_SYSLIB_DRV_VERSION_MINOR 0
/** \cond INTERNAL */
/** ARM 32-bit Return error / status codes for backward compatibility.
* Do not use them in your code.
*/
#define CY_RET_SUCCESS (0x00u) /* Successful */
#define CY_RET_BAD_PARAM (0x01u) /* One or more invalid parameters */
#define CY_RET_INVALID_OBJECT (0x02u) /* Invalid object specified */
#define CY_RET_MEMORY (0x03u) /* Memory related failure */
#define CY_RET_LOCKED (0x04u) /* Resource lock failure */
#define CY_RET_EMPTY (0x05u) /* No more objects available */
#define CY_RET_BAD_DATA (0x06u) /* Bad data received (CRC or other error check) */
#define CY_RET_STARTED (0x07u) /* Operation started, but not necessarily completed yet */
#define CY_RET_FINISHED (0x08u) /* Operation completed */
#define CY_RET_CANCELED (0x09u) /* Operation canceled */
#define CY_RET_TIMEOUT (0x10u) /* Operation timed out */
#define CY_RET_INVALID_STATE (0x11u) /* Operation not setup or is in an improper state */
#define CY_RET_UNKNOWN ((cy_status) 0xFFFFFFFFu) /* Unknown failure */
/** ARM 32-bit Return error / status codes for backward compatibility with the UDB components.
* Do not use them in your code.
*/
#define CYRET_SUCCESS (0x00u) /* Successful */
#define CYRET_BAD_PARAM (0x01u) /* One or more invalid parameters */
#define CYRET_INVALID_OBJECT (0x02u) /* Invalid object specified */
#define CYRET_MEMORY (0x03u) /* Memory related failure */
#define CYRET_LOCKED (0x04u) /* Resource lock failure */
#define CYRET_EMPTY (0x05u) /* No more objects available */
#define CYRET_BAD_DATA (0x06u) /* Bad data received (CRC or other error check) */
#define CYRET_STARTED (0x07u) /* Operation started, but not necessarily completed yet */
#define CYRET_FINISHED (0x08u) /* Operation completed */
#define CYRET_CANCELED (0x09u) /* Operation canceled */
#define CYRET_TIMEOUT (0x10u) /* Operation timed out */
#define CYRET_INVALID_STATE (0x11u) /* Operation not setup or is in an improper state */
#define CYRET_UNKNOWN ((cystatus) 0xFFFFFFFFu) /* Unknown failure */
/** \endcond */
/*******************************************************************************
* Data manipulation defines
*******************************************************************************/
/** Get the lower 8 bits of a 16-bit value. */
#define CY_LO8(x) ((uint8_t) ((x) & 0xFFu))
/** Get the upper 8 bits of a 16-bit value. */
#define CY_HI8(x) ((uint8_t) ((uint16_t)(x) >> 8u))
/** Get the lower 16 bits of a 32-bit value. */
#define CY_LO16(x) ((uint16_t) ((x) & 0xFFFFu))
/** Get the upper 16 bits of a 32-bit value. */
#define CY_HI16(x) ((uint16_t) ((uint32_t)(x) >> 16u))
/** Swap the byte ordering of a 16-bit value */
#define CY_SWAP_ENDIAN16(x) ((uint16_t)(((x) << 8u) | (((x) >> 8u) & 0x00FFu)))
/** Swap the byte ordering of a 32-bit value */
#define CY_SWAP_ENDIAN32(x) ((uint32_t)((((x) >> 24u) & 0x000000FFu) | (((x) & 0x00FF0000u) >> 8u) | \
(((x) & 0x0000FF00u) << 8u) | ((x) << 24u)))
/** Swap the byte ordering of a 64-bit value */
#define CY_SWAP_ENDIAN64(x) ((uint64_t) (((uint64_t) CY_SWAP_ENDIAN32((uint32_t)(x)) << 32u) | \
CY_SWAP_ENDIAN32((uint32_t)((x) >> 32u))))
/*******************************************************************************
* Memory model definitions
*******************************************************************************/
#if defined(__ARMCC_VERSION)
/** To create cross compiler compatible code, use the CY_NOINIT, CY_SECTION, CY_UNUSED, CY_ALIGN
* attributes at the first place of declaration/definition.
* For example: CY_NOINIT uint32_t noinitVar;
*/
#define CY_NOINIT __attribute__ ((section(".noinit"), zero_init))
#define CY_SECTION(name) __attribute__ ((section(name)))
#define CY_UNUSED __attribute__ ((unused))
/* Specifies the minimum alignment (in bytes) for variables of the specified type. */
#define CY_ALIGN(align) __ALIGNED(align)
#define CY_WEAK __weak
#elif defined (__GNUC__)
#define CY_NOINIT __attribute__ ((section(".noinit")))
#define CY_SECTION(name) __attribute__ ((section(name)))
#define CY_UNUSED __attribute__ ((unused))
#define CY_ALIGN(align) __ALIGNED(align)
#define CY_WEAK __attribute__ ((weak))
#elif defined (__ICCARM__)
#define CY_PRAGMA(x) _Pragma(#x)
#define CY_NOINIT __no_init
#define CY_SECTION(name) CY_PRAGMA(section = name)
#define CY_UNUSED
#define CY_ALIGN(align) CY_PRAGMA(data_alignment = align)
#define CY_WEAK __weak
#else
#error "Unsupported toolchain"
#endif /* (__ARMCC_VERSION) */
typedef void (* cy_israddress)(void); /**< Type of ISR callbacks */
/** \cond INTERNAL */
/** Type of ISR callbacks for backward compatibility with the UDB components. Do not use it in your code. */
typedef void (* cyisraddress)(void);
/** \endcond */
#if defined (__ICCARM__)
typedef union { cy_israddress __fun; void * __ptr; } cy_intvec_elem;
/** \cond INTERNAL */
/** Type of ISR callbacks for backward compatibility with the UDB components. Do not use it in your code. */
typedef union { cyisraddress __fun; void * __ptr; } intvec_elem;
/** \endcond */
#endif /* defined (__ICCARM__) */
#if !defined(NDEBUG)
/** Max size of file name which stores the ASSERT location */
#define CY_MAX_FILE_NAME_SIZE (24u)
extern char_t cy_assertFileName[CY_MAX_FILE_NAME_SIZE]; /**< Assert buffer */
extern uint32_t cy_assertLine; /**< Assert line value */
#endif /* NDEBUG */
#if (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED)
#define CY_R0_Pos (0u) /**< Position of R0 content in fault structure */
#define CY_R1_Pos (1u) /**< Position of R1 content in fault structure */
#define CY_R2_Pos (2u) /**< Position of R2 content in fault structure */
#define CY_R3_Pos (3u) /**< Position of R3 content in fault structure */
#define CY_R12_Pos (4u) /**< Position of R12 content in fault structure */
#define CY_LR_Pos (5u) /**< Position of LR content in fault structure */
#define CY_PC_Pos (6u) /**< Position of PC content in fault structure */
#define CY_PSR_Pos (7u) /**< Position of PSR content in fault structure */
#if (CY_CPU_CORTEX_M0P)
#define CY_CM0P_FAULT_TYPE (0xF0F1F2F3u) /**< Flag for indication CM0P core fault */
#elif (CY_CPU_CORTEX_M4)
#define CY_CM4_FAULT_TYPE (0xF4F5F6F7u) /**< Flag for indication CM4 core fault */
#define CY_NON_FPU_FAULT_TYPE (0xA1A2A3A4u) /**< Flag for indication CM4 non floating point fault type */
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)))
#define CY_FPU_FAULT_TYPE (0xA8A9AAABu) /**< Flag for indication CM4 core floating point fault type */
#define CY_FPSCR_IXC_Msk (0x00000010u) /**< Cumulative exception bit for floating-point exceptions */
#define CY_FPSCR_IDC_Msk (0x00000080u) /**< Cumulative exception bit for floating-point exceptions */
#define CY_S0_Pos (8u) /**< Position of FPU S0 content in fault structure */
#define CY_S1_Pos (9u) /**< Position of FPU S1 content in fault structure */
#define CY_S2_Pos (10u) /**< Position of FPU S2 content in fault structure */
#define CY_S3_Pos (11u) /**< Position of FPU S3 content in fault structure */
#define CY_S4_Pos (12u) /**< Position of FPU S4 content in fault structure */
#define CY_S5_Pos (13u) /**< Position of FPU S5 content in fault structure */
#define CY_S6_Pos (14u) /**< Position of FPU S6 content in fault structure */
#define CY_S7_Pos (15u) /**< Position of FPU S7 content in fault structure */
#define CY_S8_Pos (16u) /**< Position of FPU S8 content in fault structure */
#define CY_S9_Pos (17u) /**< Position of FPU S9 content in fault structure */
#define CY_S10_Pos (18u) /**< Position of FPU S10 content in fault structure */
#define CY_S11_Pos (19u) /**< Position of FPU S11 content in fault structure */
#define CY_S12_Pos (20u) /**< Position of FPU S12 content in fault structure */
#define CY_S13_Pos (21u) /**< Position of FPU S13 content in fault structure */
#define CY_S14_Pos (22u) /**< Position of FPU S14 content in fault structure */
#define CY_S15_Pos (23u) /**< Position of FPU S15 content in fault structure */
#define CY_FPSCR_Pos (24u) /**< Position of FPU FPSCR content in fault structure */
#endif /* __FPU_PRESENT */
#endif /* CY_CPU_CORTEX_M0P */
extern cy_stc_fault_frame_t cy_faultFrame; /**< Fault frame structure */
#endif /* (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) */
/*******************************************************************************
* Macro Name: CY_GET_REG8(addr)
****************************************************************************//**
*
* Reads the 8-bit value from the specified address. This function can't be
* used to access the Core register, otherwise a fault occurs.
*
* \param addr The register address.
*
* \return The read value.
*
*******************************************************************************/
#define CY_GET_REG8(addr) (*((const volatile uint8_t *)(addr)))
/*******************************************************************************
* Macro Name: CY_SET_REG8(addr, value)
****************************************************************************//**
*
* Writes an 8-bit value to the specified address. This function can't be
* used to access the Core register, otherwise a fault occurs.
*
* \param addr The register address.
*
* \param value The value to write.
*
*******************************************************************************/
#define CY_SET_REG8(addr, value) (*((volatile uint8_t *)(addr)) = (uint8_t)(value))
/*******************************************************************************
* Macro Name: CY_GET_REG16(addr)
****************************************************************************//**
*
* Reads the 16-bit value from the specified address.
*
* \param addr The register address.
*
* \return The read value.
*
*******************************************************************************/
#define CY_GET_REG16(addr) (*((const volatile uint16_t *)(addr)))
/*******************************************************************************
* Macro Name: CY_SET_REG16(addr, value)
****************************************************************************//**
*
* Writes an 16-bit value to the specified address.
*
* \param addr The register address.
*
* \param value The value to write.
*
*******************************************************************************/
#define CY_SET_REG16(addr, value) (*((volatile uint16_t *)(addr)) = (uint16_t)(value))
/*******************************************************************************
* Macro Name: CY_GET_REG24(addr)
****************************************************************************//**
*
* Reads the 24-bit value from the specified address.
*
* \param addr The register address.
*
* \return The read value.
*
*******************************************************************************/
#define CY_GET_REG24(addr) (uint32_t) ((*((const volatile uint8_t *)(addr))) | \
(uint32_t) ((*((const volatile uint8_t *)(addr) + 1)) << 8u) | \
(uint32_t) ((*((const volatile uint8_t *)(addr) + 2)) << 16u))
/*******************************************************************************
* Macro Name: CY_SET_REG24(addr, value)
****************************************************************************//**
*
* Writes an 24-bit value to the specified address.
*
* \param addr The register address.
*
* \param value The value to write.
*
*******************************************************************************/
#define CY_SET_REG24(addr, value) do \
{ \
(*((volatile uint8_t *) (addr))) = (uint8_t)(value); \
(*((volatile uint8_t *) (addr) + 1)) = (uint8_t)((value) >> 8u); \
(*((volatile uint8_t *) (addr) + 2)) = (uint8_t)((value) >> 16u); \
} \
while(0u);
/*******************************************************************************
* Macro Name: CY_GET_REG32(addr)
****************************************************************************//**
*
* Reads the 32-bit value from the specified register. The address is the little
* endian order (LSB in lowest address)
*
* \param addr The register address.
*
* \return The read value.
*
*******************************************************************************/
#define CY_GET_REG32(addr) (*((const volatile uint32_t *)(addr)))
/*******************************************************************************
* Macro Name: CY_SET_REG32(addr, value)
****************************************************************************//**
*
* Writes a 32-bit value to the specified register. The address is the little
* endian order (LSB in lowest address)
*
* \param addr The register address.
*
* \param value The value to write.
*
*******************************************************************************/
#define CY_SET_REG32(addr, value) (*((volatile uint32_t *)(addr)) = (uint32_t)(value))
/*******************************************************************************
* Macro Name: CY_ASSERT
****************************************************************************//**
*
* The macro that evaluates the expression and, if it is false (evaluates to 0),
* the processor is halted. Cy_Halt() is called when the logical expression is
* false to halt the processor.
* The ASSERT location of the file name (including path to file) and line number
* will be stored in a non-zero init area for debugging. They can be accessed
* by cy_assertFileName and assertLine global variables.
*
* \note This macro is evaluated unless NDEBUG is not defined.
* If NDEBUG is defined, just empty do while cycle is generated for this macro
* for the sake of consistency and to avoid MISRA violation.
* NDEBUG is defined by default for a Release build setting and not defined for
* a Debug build setting.
*
* \param x The logical expression. Asserts if false.
*
*******************************************************************************/
#if !defined(NDEBUG)
#define CY_ASSERT(x) do \
{ \
if(0u == (uint32_t)(x)) \
{ \
(void) strncpy(cy_assertFileName, __FILE__, CY_MAX_FILE_NAME_SIZE); \
cy_assertLine = (uint32_t)(__LINE__); \
Cy_Halt((uint32_t)0u); \
} \
} \
while(0u)
#else
#define CY_ASSERT(x) do \
{ \
} \
while(0u)
#endif /* !defined(NDEBUG) */
/*******************************************************************************
* Macro Name: _CLR_SET_FLD32U
****************************************************************************//**
*
* The macro for setting a register with a name field and value for providing
* get-clear-modify-write operations.
*
*******************************************************************************/
#define _CLR_SET_FLD32U(reg, field, value) (((reg) & ((uint32_t)(~(field ## _Msk)))) | (_VAL2FLD(field, value)))
/*******************************************************************************
* Macro Name: _BOOL2FLD
****************************************************************************//**
*
* Returns a field mask if the value is not false.
* Returns 0, if the value is false.
*
*******************************************************************************/
#define _BOOL2FLD(field, value) ((value != false) ? field ## _Msk : 0UL)
/*******************************************************************************
* Macro Name: _FLD2BOOL
****************************************************************************//**
*
* Returns true, if the value includes the field mask.
* Returns false, if the value doesn't include the field mask.
*
*******************************************************************************/
#define _FLD2BOOL(field, value) ((value & field ## _Msk) != 0UL)
/******************************************************************************
* Constants
*****************************************************************************/
/** Defines a 32-kHz clock delay */
#define CY_DELAY_MS_OVERFLOW (0x8000u)
/**
* \defgroup group_syslib_macro_reset_cause Reset cause
* \{
* Define RESET_CAUSE mask values
*/
/** A basic WatchDog Timer (WDT) reset has occurred since the last power cycle. */
#define CY_SYSLIB_RESET_HWWDT (0x0001u)
/** The fault logging system requested a reset from its Active logic. */
#define CY_SYSLIB_RESET_ACT_FAULT (0x0002u)
/** The fault logging system requested a reset from its DeepSleep logic. */
#define CY_SYSLIB_RESET_DPSLP_FAULT (0x0004u)
/** The clock supervision logic requested a reset due to loss of a watch-crystal clock. */
#define CY_SYSLIB_RESET_CSV_WCO_LOSS (0x0008u)
/** The CPU requested a system reset through it's SYSRESETREQ. This can be done via a debugger probe or in firmware. */
#define CY_SYSLIB_RESET_SOFT (0x0010u)
/** The Multi-Counter Watchdog timer #0 reset has occurred since last power cycle. */
#define CY_SYSLIB_RESET_SWWDT0 (0x0020u)
/** The Multi-Counter Watchdog timer #1 reset has occurred since last power cycle. */
#define CY_SYSLIB_RESET_SWWDT1 (0x0040u)
/** The Multi-Counter Watchdog timer #2 reset has occurred since last power cycle. */
#define CY_SYSLIB_RESET_SWWDT2 (0x0080u)
/** The Multi-Counter Watchdog timer #3 reset has occurred since last power cycle. */
#define CY_SYSLIB_RESET_SWWDT3 (0x0100u)
/** The clock supervision logic requested a reset due to loss of a high-frequency clock. */
#define CY_SYSLIB_RESET_HFCLK_LOSS (0x10000UL)
/** The clock supervision logic requested a reset due to frequency error of a high-frequency clock. */
#define CY_SYSLIB_RESET_HFCLK_ERR (0x20000UL)
/** \} group_syslib_macro_reset_cause */
/** Bit[31:24] Opcode = 0x1B (SoftReset)
* Bit[7:1] Type = 1 (Only CM4 reset)
*/
#define CY_IPC_DATA_FOR_CM4_SOFT_RESET (0x1B000002UL)
/**
* \defgroup group_syslib_macro_unique_id Unique ID
* \{
* Unique ID fields positions
*/
#define CY_UNIQUE_ID_DIE_MINOR_Pos (56u) /**< Position of DIE_MINOR field in the silicon Unique ID */
#define CY_UNIQUE_ID_DIE_SORT_Pos (48u) /**< Position of DIE_SORT field in the silicon Unique ID */
#define CY_UNIQUE_ID_DIE_Y_Pos (40u) /**< Position of DIE_Y field in the silicon Unique ID */
#define CY_UNIQUE_ID_DIE_X_Pos (32u) /**< Position of DIE_X field in the silicon Unique ID */
#define CY_UNIQUE_ID_DIE_WAFER_Pos (24u) /**< Position of DIE_WAFER field in the silicon Unique ID */
#define CY_UNIQUE_ID_DIE_LOT_2_Pos (16u) /**< Position of DIE_LOT_2 field in the silicon Unique ID */
#define CY_UNIQUE_ID_DIE_LOT_1_Pos (8u) /**< Position of DIE_LOT_1 field in the silicon Unique ID */
#define CY_UNIQUE_ID_DIE_LOT_0_Pos (0u) /**< Position of DIE_LOT_0 field in the silicon Unique ID */
/** \} group_syslib_macro_unique_id */
/** \} group_syslib_macro */
/******************************************************************************
* Function prototypes
******************************************************************************/
/**
* \addtogroup group_syslib_functions
* \{
*/
void Cy_SysLib_Delay(uint32_t milliseconds);
void Cy_SysLib_DelayUs(uint16_t microseconds);
/** Delays for the specified number of cycles.
* The function is implemented in assembler for each supported compiler.
* \param cycles The number of cycles to delay.
*/
void Cy_SysLib_DelayCycles(uint32_t cycles);
__NO_RETURN void Cy_SysLib_Halt(uint32_t reason);
void Cy_SysLib_ClearFlashCacheAndBuffer(void);
uint32_t Cy_SysLib_GetResetReason(void);
uint32_t Cy_SysLib_GetNumHfclkResetCause(void);
void Cy_SysLib_ClearResetReason(void);
uint64_t Cy_SysLib_GetUniqueId(void);
#if (CY_CPU_CORTEX_M0P)
void Cy_SysLib_SoftResetCM4(void);
#endif /* CY_CPU_CORTEX_M0P */
#if (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) || defined(CY_DOXYGEN)
void Cy_SysLib_FaultHandler(uint32_t const *faultStackAddr);
CY_WEAK void Cy_SysLib_ProcessingFault(void);
#endif /* (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) */
void Cy_SysLib_SetWaitStates(bool ulpMode, uint32_t clkHfMHz);
/*******************************************************************************
* Function Name: Cy_SysLib_EnterCriticalSection
****************************************************************************//**
*
* Cy_SysLib_EnterCriticalSection disables interrupts and returns a value
* indicating whether interrupts were previously enabled.
*
* \note Implementation of Cy_SysLib_EnterCriticalSection manipulates the IRQ
* enable bit with interrupts still enabled.
*
* \return
* Returns the current interrupt status. Returns 0 if interrupts were
* previously enabled or 1 if interrupts were previously disabled.
*
*******************************************************************************/
uint32_t Cy_SysLib_EnterCriticalSection(void);
/*******************************************************************************
* Function Name: Cy_SysLib_ExitCriticalSection
****************************************************************************//**
*
* Re-enables interrupts if they were enabled before
* Cy_SysLib_EnterCriticalSection() was called. The argument should be the value
* returned from \ref Cy_SysLib_EnterCriticalSection().
*
* \param savedIntrStatus
* Puts the saved interrupts status returned by
* the \ref Cy_SysLib_EnterCriticalSection().
*
*******************************************************************************/
void Cy_SysLib_ExitCriticalSection(uint32_t savedIntrStatus);
/** \cond INTERNAL */
/** Backward compatibility define for the CyDelay() API for the UDB components.
* Do not use it in your code.
*/
#define CyDelay (Cy_SysLib_Delay)
/** Backward compatibility define for the CyDelayUs() API for the UDB components.
* Do not use it in your code.
*/
#define CyDelayUs (Cy_SysLib_DelayUs)
/** Backward compatibility define for the CyDelayCycles() API for the UDB components.
* Do not use it in your code.
*/
#define CyDelayCycles (Cy_SysLib_DelayCycles)
/** Backward compatibility define for the Cy_Halt() API.
* Do not use it in your code.
*/
#define Cy_Halt (Cy_SysLib_Halt)
/** Backward compatibility define for the Cy_ClearFlashCacheAndBuffer() API.
* Do not use it in your code.
*/
#define Cy_ClearFlashCacheAndBuffer (Cy_SysLib_ClearFlashCacheAndBuffer)
/** Backward compatibility define for the Cy_SYSLIB_GetResetReason() API.
* Do not use it in your code.
*/
#define Cy_SYSLIB_GetResetReason (Cy_SysLib_GetResetReason)
/** Backward compatibility define for the Cy_SYSLIB_GetNumHFCLKResetCause() API.
* Do not use it in your code.
*/
#define Cy_SYSLIB_GetNumHFCLKResetCause (Cy_SysLib_GetNumHfclkResetCause)
/** Backward compatibility define for the Cy_SYSLIB_ClearResetReason() API.
* Do not use it in your code.
*/
#define Cy_SYSLIB_ClearResetReason (Cy_SysLib_ClearResetReason)
/** Backward compatibility define for the Cy_SYSLIB_GetUniqueId() API.
* Do not use it in your code.
*/
#define Cy_SYSLIB_GetUniqueId (Cy_SysLib_GetUniqueId)
/** Backward compatibility define for the Cy_SYSLIB_SoftResetCM4() API.
* Do not use it in your code.
*/
#define Cy_SYSLIB_SoftResetCM4 (Cy_SysLib_SoftResetCM4)
#if (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) || defined(CY_DOXYGEN)
/** Backward compatibility define for the Cy_SYSLIB_FaultHandler() API.
* Do not use it in your code.
*/
#define Cy_SYSLIB_FaultHandler (Cy_SysLib_FaultHandler)
/** Backward compatibility define for the Cy_SYSLIB_ProcessingFault() API.
* Do not use it in your code.
*/
#define Cy_SYSLIB_ProcessingFault (Cy_SysLib_ProcessingFault)
#endif /* (CY_ARM_FAULT_DEBUG == CY_ARM_FAULT_DEBUG_ENABLED) */
/** Backward compatibility define for the Cy_SYSLIB_SetWaitStates() API.
* Do not use it in your code.
*/
#define Cy_SYSLIB_SetWaitStates (Cy_SysLib_SetWaitStates)
/** Backward compatibility define for the CyEnterCriticalSection() API for the UDB components.
* Do not use it in your code.
*/
#define CyEnterCriticalSection (Cy_SysLib_EnterCriticalSection)
/** Backward compatibility define for the CyExitCriticalSection() API for the UDB components.
* Do not use it in your code.
*/
#define CyExitCriticalSection (Cy_SysLib_ExitCriticalSection)
/** \endcond */
/** \} group_syslib_functions */
#if defined(__cplusplus)
}
#endif /* defined(__cplusplus) */
#endif /* _CY_SYSLIB_H_ */
/** \} group_syslib */
/* [] END OF FILE */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,820 @@
/***************************************************************************//**
* \file cy_syspm.h
* \version 1.0
*
* Provides the function definitions for the power management API.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*
*******************************************************************************/
/**
* \defgroup group_syspm System Power Management (SysPm)
* \{
* Power Modes
*
* Devices support the following power modes (in the order of
* high-to-low power consumption): Active, Sleep, Low Power (LP) Active,
* LP Sleep, DeepSleep, and Hibernate.
* Active and Sleep are the standard ARM-defined power modes, supported by the
* ARM CPUs.
* DeepSleep is a lower-power mode where high-frequency clocks are disabled.
* Most of the register state is retained and the platform supports saving a
* configurable amount of the SRAM state.
* Hibernate is an even lower power mode that is entered from firmware,
* just like DeepSleep. However, on a wakeup the CPU and all peripherals go
* through a full reset.
*
* The power mode library is used to enter low-power states to reduce system
* power consumption in power sensitive designs. This library allows the user to
* individually power down each CPU into Sleep or DeepSleep.
*
* <table class="doxtable">
* <tr><th>CM0+ Mode</th><th>CM4 Mode</th><th>Power Mode (SRSS)</th>
* <th>Mode Description</th></tr>
* <tr>
* <td>Active</td>
* <td>Active</td>
* <td>Normal</td>
* <td>All Clocks and peripherals may operate or optionally can
* be disabled. Current load limitation is set as for
* active power mode(*1).</td>
* </tr>
* <tr>
* <td>Sleep</td>
* <td>Active</td>
* <td>Normal</td>
* <td>All Clocks and peripherals may operate or optionally can
* be disabled. Current load limitation is set as for
* active power mode(*1).</td>
* </tr>
* <tr>
* <td>DeepSleep</td>
* <td>Active</td>
* <td>Normal</td>
* <td>All Clocks and peripherals may operate or optionally can
* be disabled. Current load limitation is set as for
* active power mode(*1).</td>
* </tr>
* <tr>
* <td>Sleep</td>
* <td>Sleep</td>
* <td>Normal</td>
* <td>All Clocks and peripherals may operate, CPUs Off. Current load
* limitation is set as for active power mode(*1).</td>
* </tr>
* <tr>
* <td>DeepSleep</td>
* <td>Sleep</td>
* <td>Normal</td>
* <td>All Clocks and peripherals may operate, CPUs Off. Current load
* limitation is set as for active power mode(*1).</td>
* </tr>
* <tr>
* <td>Active</td>
* <td>DeepSleep</td>
* <td>Normal</td>
* <td>All Clocks and peripherals may operate or optionally can
* be disabled. Current load limitation is set as for
* active power mode(*1).</td>
* </tr>
* <tr>
* <td>Sleep</td>
* <td>DeepSleep</td>
* <td>Normal</td>
* <td>All Clocks and peripherals may operate, CPUs Off. Current load
* limitation is set as for active power mode(*1).</td>
* </tr>
* <tr>
* <td>DeepSleep</td>
* <td>DeepSleep</td>
* <td>DeepSleep</td>
* <td>All the MHz clocks are off, but so is the DSI routing, and most Analog
* and voltage references are off by default. Only ILO/WCO may operate,
* limited peripherals.</td>
* </tr>
* <tr>
* <td>Active (LPActive)</td>
* <td>Active (LPActive)</td>
* <td>Low power</td>
* <td>All the MHz clocks frequencies are decreased to meet current load
* limitations (*1). Peripherals are also slowed and optionally disabled
* to meet current load limitations in LPActive power mode.</td>
* </tr>
* <tr>
* <td>Sleep (LPSleep)</td>
* <td>Active (LPActive)</td>
* <td>Low power</td>
* <td>All the MHz clocks frequencies are decreased to meet current load
* limitations (*1). Peripherals are also slowed and optionally disabled
* to meet current load limitations in LPActive power mode.</td>
* </tr>
* <tr>
* <td>DeepSleep</td>
* <td>Active (LPActive)</td>
* <td>Low power</td>
* <td>All the MHz clocks frequencies are decreased to meet current load
* limitations (*1). Peripherals are also slowed and optionally disabled
* to meet current load limitations in LPActive power mode.</td>
* </tr>
* <tr>
* <td>Active (LPActive)</td>
* <td>Sleep (LPSleep)</td>
* <td>Low power</td>
* <td>All the MHz clocks frequencies are decreased to meet current load
* limitations (*1). Peripherals are also slowed and optionally disabled
* to meet current load limitations in LPActive power mode.</td>
* </tr>
* <tr>
* <td>Sleep (LPSleep)</td>
* <td>Sleep (LPSleep)</td>
* <td>Low power</td>
* <td>All the MHz clocks frequencies are decreased to meet current load
* limitations (*1). Peripherals are also slowed and optionally disabled
* to meet current load limitations in LPActive power mode.
* CPUs are off.</td>
* </tr>
* <tr>
* <td>DeepSleep</td>
* <td>Sleep (LPSleep)</td>
* <td>Low power</td>
* <td>All the MHz clocks frequencies are decreased to meet current load
* limitations (*1). Peripherals are also slowed and optionally disabled
* to meet current load limitations in LPActive power mode.
* CPUs are off</td>
* </tr>
* <tr>
* <td>Active (LPActive)</td>
* <td>DeepSleep</td>
* <td>Low power</td>
* <td>All the MHz clocks frequencies are decreased to meet current load
* limitations (*1). Peripherals are also slowed and optionally disabled
* to meet current load limitations in LPActive power mode.</td>
* </tr>
* <tr>
* <td>DeepSleep</td>
* <td>DeepSleep</td>
* <td>DeepSleep</td>
* <td>The entire chip is in a DeepSleep mode, since it forces the MHz
* clocks, DSI, UDBs, most peripherals, analog, etc., to be shut down.
* Only ILO/WCO may operate, limited peripherals</td>
* </tr>
* <tr>
* <td>-</td>
* <td>-</td>
* <td>Hibernate</td>
* <td>Once Hibernate mode is set, everything goes into Hibernate mode.
* Only ILO may operate to assert wake-up device using WDT or RTC.</td>
* </tr>
* </table>
*
* (*1) For more details about power modes and current load limitations refer to
* the device Technical Reference Manual (TRM).
*
* Power modes:
* * Active - In this mode the CPU executes code, and all logic and memories
* are powered. Firmware may decide to disable clocks for specific peripherals
* and to power down specific analog power domains. The chip enters Active upon
* initial reset. For internally-generated resets, the chip enters the most
* recently used power mode among Active and LPActive.
*
* * Sleep - In this mode the CPU does not execute code and its clock is
* stopped. It is identical to ACTIVE from a peripheral point of view.
*
* * LPActive - LPActive (Low Power Active) is similar to Active, with clock
* restrictions and limited/slowed peripheral to achieve a lower system current.
*
* * LPSleep - LPSleep (Low Power Sleep) mode operates the same as Sleep mode
* with the clocking limitations of LPActive mode to further reduce system power.
*
* * DeepSleep - In DeepSleep mode the main system clock is off for CPU, Flash,
* and high-speed logic. Optionally, the low frequency (32.768 kHz) clock
* remains on, and low-frequency peripherals continue operating.
* Peripherals that do not need a clock or receive a clock from their external
* interface (e.g., I2C/SPI) continue operating, and all circuits that draw
* current from the Vccdpslp supply are subject to the current sourcing
* limitations of the DeepSleep Regulator (if the core is supplied by the
* Linear core regulator). If the core is supplied by the SIMO Buck regulator all
* deepsleep peripherals are supplied by Vbuck1.
* A normal wakeup from DeepSleep returns to either LPActive, LPSleep, Active, or
* Sleep, depending on the previous state and programmed behavior for the
* configured wakeup interrupt.
* Likewise, a debug wakeup from DeepSleep returns to LPSleep or Sleep, depending
* on which mode was used to enter DeepSleep.
*
* * Hibernate - Is the lowest power mode available when external supplies are
* present. It is intended for applications in a dormant state.
* Hibernate is implemented using high voltage logic and switches off all
* internal regulators. The Backup domain continues functioning normally.
* The I/O's state is frozen so that the output driver state is held.
* Note in this mode the CPU and all peripherals lose state, so the system and
* firmware reboot on a wakeup event.
* Wakeup is supported from device specific pin(s) with programmable
* polarity. Additionally, unregulated peripherals can wake the device under
* some conditions. For example, a low-power comparator can wake the device by
* comparing two external voltages but may not support comparison to an
* internally-generated voltage. The Backup domain remains functional, and if
* present it can schedule an alarm to wake the device from Hibernate using RTC.
* The combination of Hibernate and Backup alarms can yield low current duty
* cycling for applications, such as waking once per second for a CapSense
* scan. Alternatively, the Watchdog Timer (WDT) can be configured to wake-up the device by
* WDT interrupt.
* Backup memory (BMEM) can be used to store system state for use on the
* next reboot.
*
* The system can wakeup from Hibernate power mode by configuring:
* * Wakeup pins
* * WDT interrupt
* * LPComparator
* * WDT reset - this can be configured without using the syspm driver. Just
* configure and enable the WDT before entering Hibernate power mode. All
* other events require use of the API from the syspm driver.
*
* * XRES - is the state of the part when XRES is applied. This is obviously a
* reset condition, but it is also considered a power mode because some low-power
* applications, such as remote controls, expect very low current consumption
* when XRES is asserted.
*
* * OFF - The OFF state simply represents the state of the part with no power
* applied to it (except perhaps the Backup domain). In some applications, power
* to the device will be switched on and off by another device in the system to
* make the product implement the lowest power consumption level.
*
* Wakeup time after a reset is device-dependent because of the boot run-time.
* The wakeup time varies depending on the number and type of trim parameters and
* the size of device Flash.
*
* For ARM-based devices, an interrupt is required for the CPU to
* wake up.
*
* * All pending interrupts should be cleared before the device is put into a
* low-power mode, even if they are masked.
*
* \section group_syspm_section_configuration Configuration Considerations
* After initial device boot the device goes into Active power mode. After some
* code execution the device could be sent into low power modes. The
* Cy_SysPm_Sleep() and Cy_SysPm_DeepSleep() functions only switch the core that
* calls the function into Sleep or DeepSleep. To set the whole device into Sleep
* or DeepSleep device, ensure that each core calls the sleep functions.
*
* There are situations when the device does not switch into DeepSleep power
* mode immediately after the second core calls Cy_SysPm_DeepSleep(). The device
* will switch into DeepSleep mode automatically a little bit later, after the
* low-power circuits are ready to switch into DeepSleep.
* Refer to the Cy_SysPm_DeepSleep() description for more details.
*
* If you call Cy_SysPm_Hibernate() the device will be switched
* into Hibernate power mode directly, as there is no handshake between cores.
*
* Before switching into LPActive power mode ensure that the device meets the
* current load limitation by decreasing the Mhz clocks, and slowing or disabling
* peripherals.
* Refer to the device TRM for more details about current load limitations in
* different low-power modes.
*
* The syspm driver implements a syspm callbacks mechanism. Using a
* syspm callback, you can perform actions right before entering
* low-power mode, and directly after switching out of low-power mode. With the
* callback mechanism you can prevent switching into low power mode if, for
* example, some required peripheral is not ready to enter into requested
* low-power mode.
*
* Fill in the cy_stc_syspm_callback_t structure for each callback function.
* Each callback function is of the type cy_SysPMCallback. You assign
* the mode for each callback function. Refer to cy_en_syspm_callback_mode_t.
* Also refer to Cy_SysPm_Sleep(), Cy_SysPm_DeepSleep(), Cy_SysPm_EnterLpMode(),
* Cy_SysPm_ExitLpMode(), Cy_SysPm_Hibernate() for more details.
*
* Refer to Cy_SysPm_RegisterCallback() description for more details
* about registering a callback. You may have up to 32 callback functions.
*
* \section group_syspm_section_more_information More Information
*
* For more information on the Power Modes (syspm) driver,
* refer to the Technical Reference Manual (TRM).
*
* \section group_syspm_MISRA MISRA-C Compliance
* The syspm driver does not have any specific deviations.
*
* \section group_syspm_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_syspm_macro Macro
* \defgroup group_syspm_functions Functions
* \defgroup group_syspm_data_structures Data Structures
* \defgroup group_syspm_data_enumerates Enumerated types
*/
#ifndef _CY_SYSPM_H_
#define _CY_SYSPM_H_
#include <stdbool.h>
#include <stddef.h>
#include "cy_device_headers.h"
#include "syslib/cy_syslib.h"
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Register Constants
*******************************************************************************/
/**
* \addtogroup group_syspm_macro
* \{
*/
/** Driver major version */
#define CY_SYSPM_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_SYSPM_DRV_VERSION_MINOR 0
/** \cond INTERNAL */
/** Internal define for SysPm_DeepSleep() function */
#define CY_SYSPM_PWR_TRIM_WAKE_CNTS (0x8Bu)
/** Internal define for Cy_SysPm_ExitLpMode() function */
#define CY_SYSPM_WAIT_DELAY_TRYES (100u)
/** Internal define for SysPm_SwitchToSimoBuck() function */
#define CY_SYSPM_1M_THRESHOLD (1000000u)
/** Internal define for SysPm_WakeupPinLevel() function */
#define CY_SYSPM_PWR_MASK_HIBPIN_PIN_MASK (0x03u)
/** Internal define for SysPm_WakeupPinLevel() function */
#define CY_SYSPM_WAKEUP_PIN_BIT (1ul)
/* Internal define for Cy_SysPm_WakeupLpCompLevel() function */
#define CY_SYSPM_LPCOMPARATOR_BIT (4ul)
/* Define for mask for LPComs in Cy_SysPm_WakeupLpCompLevel() function */
#define CY_SYSPM_LPCOMPARATOR_MASK (12u)
/** \endcond */
/** syspm driver identifier */
#define CY_SYSPM_ID (CY_PDL_DRV_ID(0x10u))
/**
* \defgroup group_syspm_return_status Power Mode Status
* \{
* Current power mode status defines
*/
/** CM4 is Active */
#define CY_SYSPM_STATUS_CM4_ACTIVE (0x01u)
/** CM4 is in Sleep */
#define CY_SYSPM_STATUS_CM4_SLEEP (0x02u)
/** CM4 is in DeepSleep */
#define CY_SYSPM_STATUS_CM4_DEEPSLEEP (0x04u)
/** CM4 is Lop Power mode */
#define CY_SYSPM_STATUS_CM4_LOWPOWER (0x80u)
/** CM0 is Active */
#define CY_SYSPM_STATUS_CM0_ACTIVE ((uint32_t) ((uint32_t)0x01u << 8u))
/** CM0 is in Sleep */
#define CY_SYSPM_STATUS_CM0_SLEEP ((uint32_t) ((uint32_t)0x02u << 8u))
/** CM0 is in DeepSleep */
#define CY_SYSPM_STATUS_CM0_DEEPSLEEP ((uint32_t) ((uint32_t)0x04u << 8u))
/** CM4 is in Low Power mode */
#define CY_SYSPM_STATUS_CM0_LOWPOWER ((uint32_t) ((uint32_t)0x80u << 8u))
/** Device is in Low Power mode*/
#define CY_SYSPM_STATUS_SYSTEM_LOWPOWER ((uint32_t) (CY_SYSPM_STATUS_CM0_LOWPOWER | (CY_SYSPM_STATUS_CM4_LOWPOWER)))
/** \} group_syspm_return_status */
/** Define to update token to indicate Hibernate mode transition */
#define CY_SYSPM_PWR_HIBERNATE_TOKEN_HIBERNATE (0xf1u)
/** Wait time for transition device from Active into the LPActive */
#define CY_SYSPM_PWR_ACTIVE_TO_LP_WAIT_US (1u)
/** Wait time for transition device from Active into the LPActive before Active
* reference is settled
*/
#define CY_SYSPM_PWR_LP_TO_ACTIVE_WAIT_BEFORE_US (8u)
/** Wait time for transition device from Active into the LPActive after Active
* reference is settled
*/
#define CY_SYSPM_PWR_LP_TO_ACTIVE_WAIT_AFTER_US (1u)
/** Maximum callbacks number */
#define CY_SYSPM_PWR_MAX_CALLBACKS_NUMBER (32u)
/** Mask to unlock Hibernate mode */
#define CY_SYSPM_PWR_HIBERNATE_UNLOCK ((uint32_t) 0x3Au << SRSS_PWR_HIBERNATE_UNLOCK_Pos)
/** Mask to retain Hibernate status */
#define CY_SYSPM_PWR_RETAIN_HIBERNATE_STATUS ((uint32_t) SRSS_PWR_HIBERNATE_TOKEN_Msk |\
SRSS_PWR_HIBERNATE_MASK_HIBALARM_Msk |\
SRSS_PWR_HIBERNATE_MASK_HIBWDT_Msk |\
SRSS_PWR_HIBERNATE_POLARITY_HIBPIN_Msk |\
SRSS_PWR_HIBERNATE_MASK_HIBPIN_Msk)
/** Maximum value of callbacks */
#define CY_SYSPM_PWR_MAX_PLL_NUMBER (16u)
/** Definition for delay of SIMO Buck supply regulator after it is enabled */
#define CY_SYSPM_SIMO_BUCK_CORE_SUPPLY_STABLE_US (900u)
/** Definition for delay of SIMO Buck output 2 */
#define CY_SYSPM_SIMO_BUCK_BLE_SUPPLY_STABLE_US (600u)
/** Definition for delay of Linear Regulator after it output voltage
* is changed
*/
#define CY_SYSPM_LDO_IS_STABLE_US (9u)
/** Definition for delay of core supply regulator after it output voltage
* is changed
*/
#define CY_SYSPM_SIMO_BUCK_IS_STABLE_US (200u)
/** \} group_syspm_macro */
/*******************************************************************************
* Configuration Structures
*******************************************************************************/
/**
* \addtogroup group_syspm_data_enumerates
* \{
*/
/** This enumeration is used to initialize the wakeup pin state */
typedef enum
{
CY_SYSPM_PIN_DISABLED, /**< Disable selected wakeup pin */
CY_SYSPM_PIN_HIGH_LEVEL, /**< Configure high level for selected wakeup-pin */
CY_SYSPM_PIN_LOW_LEVEL /**< Configure low level for selected wakeup-pin */
} cy_en_syspm_pinstate_t;
/** This enumeration is used to initialize the Low-power Comparator
* (LPComp) state
*/
typedef enum
{
CY_SYSPM_LPCOMP_DISABLED, /**< Disable selected LPComp */
CY_SYSPM_LPCOMP_HIGH_LEVEL, /**< Configure high level for selected LPComp */
CY_SYSPM_LPCOMP_LOW_LEVEL /**< Configure low level for selected LPComp */
} cy_en_syspm_lpcomp_state_t;
/**
* This enumeration is used to initialize a wait action - an interrupt or
* event. Refer to the CMSIS for the WFE and WFI instruction explanations.
*/
typedef enum
{
CY_SYSPM_WAIT_FOR_INTERRUPT, /**< Wait for interrupt */
CY_SYSPM_WAIT_FOR_EVENT /**< Wait for event */
} cy_en_syspm_waitfor_t;
/**
* The enumeration for core voltages for both the SIMO Buck and the
* Linear Regulator
*/
typedef enum
{
CY_SYSPM_LDO_VOLTAGE_0_9V = 0x05u, /**< 0.9 V nominal core voltage */
CY_SYSPM_LDO_VOLTAGE_1_1V = 0x17u /**< 1.1 V nominal core voltage */
} cy_en_syspm_ldo_voltage_t;
/**
* The enumeration for core voltages for both the SIMO Buck and the
* Linear Regulator
*/
typedef enum
{
CY_SYSPM_SIMO_BUCK_OUT1_VOLTAGE_0_9V = 0x01u, /**< 0.9 V nominal core voltage */
CY_SYSPM_SIMO_BUCK_OUT1_VOLTAGE_1_1V = 0x05u /**< 1.1 V nominal core voltage */
} cy_en_syspm_simo_buck_voltage1_t;
/**
* The enumeration for core voltages for both the SIMO Buck and the
* Linear Regulator
*/
typedef enum
{
CY_SYSPM_SIMO_BUCK_OUT2_VOLTAGE_0_95V = 0u, /**< 0.95 V nominal core voltage */
CY_SYSPM_SIMO_BUCK_OUT2_VOLTAGE_1_0V, /**< 1.0 V nominal core voltage */
CY_SYSPM_SIMO_BUCK_OUT2_VOLTAGE_1_05V, /**< 1.05 V nominal core voltage */
CY_SYSPM_SIMO_BUCK_OUT2_VOLTAGE_1_1V, /**< 1.1 V nominal core voltage */
CY_SYSPM_SIMO_BUCK_OUT2_VOLTAGE_1_2V, /**< 1.2 V nominal core voltage */
CY_SYSPM_SIMO_BUCK_OUT2_VOLTAGE_1_3V, /**< 1.3 V nominal core voltage */
CY_SYSPM_SIMO_BUCK_OUT2_VOLTAGE_1_4V, /**< 1.4 V nominal core voltage */
CY_SYSPM_SIMO_BUCK_OUT2_VOLTAGE_1_5V, /**< 1.5 V nominal core voltage */
} cy_en_syspm_simo_buck_voltage2_t;
/**
* The enumeration are used to configure SIMO Buck regulator outputs
*/
typedef enum
{
CY_SYSPM_BUCK_VBUCK_1, /**< SIMO Buck output 1 Voltage (Vback1) */
CY_SYSPM_BUCK_VRF /**< SIMO Buck out 2 Voltage (Vbackrf) */
} cy_en_syspm_buck_out_t;
/** SysPm status definitions */
typedef enum
{
CY_SYSPM_SUCCESS = 0x00u, /**< Successful */
CY_SYSPM_BAD_PARAM = CY_SYSPM_ID | CY_PDL_STATUS_ERROR | 0x01u, /**< One or more invalid parameters */
CY_SYSPM_TIMEOUT = CY_SYSPM_ID | CY_PDL_STATUS_ERROR | 0x02u, /**< Time-out occurs */
CY_SYSPM_INVALID_STATE = CY_SYSPM_ID | CY_PDL_STATUS_ERROR | 0x03u, /**< Operation not setup or is in an
improper state */
CY_SYSPM_FAIL = CY_SYSPM_ID | CY_PDL_STATUS_ERROR | 0xFFu /**< Unknown failure */
} cy_en_syspm_status_t;
/**
* This enumeration is used for selecting the low power mode on which the
* appropriate registered callback handler will be executed. For example,
* registered callback with type CY_SYSPM_SLEEP will be executed while
* switching into the Sleep power mode.
*/
typedef enum
{
CY_SYSPM_SLEEP, /**< Sleep enum callback type */
CY_SYSPM_DEEPSLEEP, /**< DeepSleep enum callback type */
CY_SYSPM_HIBERNATE, /**< Hibernate enum callback type */
CY_SYSPM_ENTER_LP_MODE, /**< Enter LPActive mode enum callback type */
CY_SYSPM_EXIT_LP_MODE, /**< Exit LPActive mode enum callback type */
} cy_en_syspm_callback_type_t;
/** Callback mode enumeration. This enum define the callback mode */
typedef enum
{
CY_SYSPM_CHECK_READY, /**< Callbacks with this mode are executed before entering into low-power mode.
It checks if device is ready to enter low-power mode */
CY_SYSPM_CHECK_FAIL, /**< Callbacks with this mode are executed after the previous callbacks execution
with CY_SYSPM_CHECK_READY returned CY_SYSPM_FAIL. Callback with
CY_SYSPM_CHECK_FAIL mode should rollback the actions which were done in
callbacks executed previously with CY_SYSPM_CHECK_READY */
CY_SYSPM_BEFORE_ENTER, /**< Actions that should be done before enter low-power mode */
CY_SYSPM_AFTER_EXIT, /**< Actions that should be done after exit low-power mode */
} cy_en_syspm_callback_mode_t;
/** \} group_syspm_data_enumerates */
/**
* \addtogroup group_syspm_data_structures
* \{
*/
/** Type for syspm callbacks */
typedef cy_en_syspm_status_t (*Cy_SysPmCallback) (void *base, void *content, cy_en_syspm_callback_mode_t mode);
/** The structure which contain the syspm callback configuration elements */
typedef struct cy_stc_syspm_callback
{
Cy_SysPmCallback Callback; /**< Callback handler function */
cy_en_syspm_callback_type_t type; /**< Callback type, see \ref cy_en_syspm_callback_type_t */
void *base; /**< Base address of HW instance, matches with driver name in
the API for base address */
void *content; /**< Content for handler function */
struct cy_stc_syspm_callback *nextItm; /**< Next list item */
} cy_stc_syspm_callback_t;
/** \} group_syspm_data_structures */
/**
* \addtogroup group_syspm_functions
* \{
*/
__STATIC_INLINE bool Cy_SysPm_Cm4IsActive(void);
__STATIC_INLINE bool Cy_SysPm_Cm4IsSleep(void);
__STATIC_INLINE bool Cy_SysPm_Cm4IsDeepSleep(void);
__STATIC_INLINE bool Cy_SysPm_Cm4IsLowPower(void);
__STATIC_INLINE bool Cy_SysPm_Cm0IsActive(void);
__STATIC_INLINE bool Cy_SysPm_Cm0IsSleep(void);
__STATIC_INLINE bool Cy_SysPm_Cm0IsDeepSleep(void);
__STATIC_INLINE bool Cy_SysPm_Cm0IsLowPower(void);
__STATIC_INLINE bool Cy_SysPm_IsLowPower(void);
uint32_t Cy_SysPm_ReadStatus(void);
cy_en_syspm_status_t Cy_SysPm_Sleep(cy_en_syspm_waitfor_t enWaitFor);
cy_en_syspm_status_t Cy_SysPm_DeepSleep(cy_en_syspm_waitfor_t enWaitFor);
cy_en_syspm_status_t Cy_SysPm_Hibernate(void);
cy_en_syspm_status_t Cy_SysPm_EnterLpMode(void);
cy_en_syspm_status_t Cy_SysPm_ExitLpMode(void);
void Cy_SysPm_SleepOnExit(bool enable);
void Cy_SysPm_WakeupPinLevel(uint32_t pinNum, cy_en_syspm_pinstate_t enPinLevel);
void Cy_SysPm_WakeupLpCompLevel(uint32_t lpCompNum, cy_en_syspm_lpcomp_state_t enLpCompLevel);
void Cy_SysPm_WakeupWdt(bool configureWdt);
void Cy_SysPm_WakeupRtc(bool configureRtc);
bool Cy_SysPm_RegisterCallback(cy_stc_syspm_callback_t* handler);
bool Cy_SysPm_UnregisterCallback(cy_stc_syspm_callback_t* handler);
uint32_t Cy_SysPm_ExecuteCallback(cy_en_syspm_callback_type_t type,
cy_en_syspm_callback_mode_t mode,
uint32_t lastCallback);
bool Cy_SysPm_GetIoFreezeStatus(void);
void Cy_SysPm_IoFreeze(void);
void Cy_SysPm_IoUnfreeze(void);
void Cy_SysPm_LdoSetVoltage(cy_en_syspm_ldo_voltage_t voltage);
cy_en_syspm_ldo_voltage_t Cy_SysPm_LdoGetVoltage(void);
bool Cy_SysPm_LdoIsEnabled(void);
#if(0u != SRSS_SIMOBUCK_PRESENT)
void Cy_SysPm_SwitchToSimoBuck(void);
void Cy_SysPm_SimoBuckSetVoltage1(cy_en_syspm_simo_buck_voltage1_t voltage);
cy_en_syspm_simo_buck_voltage1_t Cy_SysPm_SimoBuckGetVoltage1(void);
void Cy_SysPm_EnableVoltage2(void);
void Cy_SysPm_DisableVoltage2(void);
void Cy_SysPm_SimoBuckSetVoltage2(cy_en_syspm_simo_buck_voltage2_t voltage);
cy_en_syspm_simo_buck_voltage2_t Cy_SysPm_SimoBuckGetVoltage2(void);
bool Cy_SysPm_SimoBuckOutputIsEnabled(cy_en_syspm_buck_out_t output);
bool Cy_SysPm_SimoBuckIsEnabled(void);
void Cy_SysPm_SimoBuckSetHwControl(bool hwControl);
bool Cy_SysPm_SimoBuckGetHwControl(void);
#endif /* (0u != SRSS_SIMOBUCK_PRESENT) */
/*******************************************************************************
* Function Name: Cy_SysPm_Cm4IsActive
****************************************************************************//**
*
* Check if CM4 is in Active mode.
*
* \return
* true - if CM4 is in Active mode, false - if CM4 is not in Active mode.
*
*******************************************************************************/
__STATIC_INLINE bool Cy_SysPm_Cm4IsActive(void)
{
return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM4_ACTIVE) != 0u);
}
/*******************************************************************************
* Function Name: Cy_SysPm_Cm4IsSleep
****************************************************************************//**
*
* Check if CM4 is in Sleep mode.
*
* \return
* true - if CM4 is in Sleep mode, false - if CM4 is not in Sleep mode.
*
*******************************************************************************/
__STATIC_INLINE bool Cy_SysPm_Cm4IsSleep(void)
{
return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM4_SLEEP) != 0u);
}
/*******************************************************************************
* Function Name: Cy_SysPm_Cm4IsDeepSleep
****************************************************************************//**
*
* Check if CM4 is in DeepSleep mode.
*
* \return
* true - if CM4 is in DeepSleep mode, false - if CM4 is not in DeepSleep mode.
*
*******************************************************************************/
__STATIC_INLINE bool Cy_SysPm_Cm4IsDeepSleep(void)
{
return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM4_DEEPSLEEP) != 0u);
}
/*******************************************************************************
* Function Name: Cy_SysPm_Cm4IsLowPower
****************************************************************************//**
*
* Check if CM4 is in LowPower mode.
*
* \return
* true - if CM4 is in LowPower mode, false - if CM4 is not in LowPower mode.
*
*******************************************************************************/
__STATIC_INLINE bool Cy_SysPm_Cm4IsLowPower(void)
{
return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM4_LOWPOWER) != 0u);
}
/*******************************************************************************
* Function Name: Cy_SysPm_Cm0IsActive
****************************************************************************//**
*
* Check if CM0+ is in Active mode.
*
* \return
* true - if CM0+ is in Active mode, false - if CM0+ is not in Active mode.
*
*******************************************************************************/
__STATIC_INLINE bool Cy_SysPm_Cm0IsActive(void)
{
return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM0_ACTIVE) != 0u);
}
/*******************************************************************************
* Function Name: Cy_SysPm_Cm0IsSleep
****************************************************************************//**
*
* Check if CM0+ is in Sleep mode.
*
* \return
* true - if CM0+ is in Sleep mode, false - if CM0+ is not in Sleep mode.
*
*******************************************************************************/
__STATIC_INLINE bool Cy_SysPm_Cm0IsSleep(void)
{
return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM0_SLEEP) != 0u);
}
/*******************************************************************************
* Function Name: Cy_SysPm_Cm0IsDeepSleep
****************************************************************************//**
*
* Check if CM0+ is in DeepSleep mode.
*
* \return
* true - if CM0+ is in DeepSleep mode, false - if CM0+ is not in DeepSleep mode.
*
*******************************************************************************/
__STATIC_INLINE bool Cy_SysPm_Cm0IsDeepSleep(void)
{
return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM0_DEEPSLEEP) != 0u);
}
/*******************************************************************************
* Function Name: Cy_SysPm_Cm0IsLowPower
****************************************************************************//**
*
* Check if CM0+ is in LowPower mode.
*
* \return
* true - if CM0+ is in LowPower mode, false - if CM0+ is not in LowPower mode.
*
*******************************************************************************/
__STATIC_INLINE bool Cy_SysPm_Cm0IsLowPower(void)
{
return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM0_LOWPOWER) != 0u);
}
/*******************************************************************************
* Function Name: Cy_SysPm_IsLowPower
****************************************************************************//**
*
* Check if device is in Low Power mode.
*
* \return
* true - system is in Low Power mode,
* false - if system is is not in Low Power mode.
*
*******************************************************************************/
__STATIC_INLINE bool Cy_SysPm_IsLowPower(void)
{
return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_SYSTEM_LOWPOWER) != 0u);
}
#ifdef __cplusplus
}
#endif
#endif /* _CY_SYSPM_H_ */
/** \} group_syspm_functions*/
/** \} group_syspm */
/* [] END OF FILE */

View File

@ -0,0 +1,335 @@
/***************************************************************************//**
* \file cy_systick.c
* \version 1.0
*
* Provides the API definitions of the SisTick driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "cy_systick.h"
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
static Cy_SysTick_Callback Cy_SysTick_Callbacks[CY_SYS_SYST_NUM_OF_CALLBACKS];
static void Cy_SysTick_ServiceCallbacks(void);
/*******************************************************************************
* Function Name: Cy_SysTick_Init
****************************************************************************//**
*
* Initializes the callback addresses with pointers to NULL, associates the
* SysTick system vector with the function responsible for calling
* registered callback functions, configures the SysTick timer to generate an
* interrupt periodically.
*
* \param clockSource The SysTick clock source \ref cy_en_systick_clock_source_t
* \param interval The SysTick reload value.
*
* \sideeffect Clears the SysTick count flag if it was set.
*
*******************************************************************************/
void Cy_SysTick_Init(cy_en_systick_clock_source_t clockSource, uint32_t interval)
{
uint32_t i;
for (i = 0u; i<CY_SYS_SYST_NUM_OF_CALLBACKS; i++)
{
Cy_SysTick_Callbacks[i] = (void *) 0;
}
__ramVectors[CY_SYSTICK_IRQ_NUM] = &Cy_SysTick_ServiceCallbacks;
Cy_SysTick_ServiceCallbacks();
Cy_SysTick_SetClockSource(clockSource);
Cy_SysTick_SetReload(interval);
Cy_SysTick_Clear();
Cy_SysTick_Enable();
}
/*******************************************************************************
* Function Name: Cy_SysTick_Enable
****************************************************************************//**
*
* Enables the SysTick timer and its interrupt.
*
* \sideeffect Clears the SysTick count flag if it was set
*
*******************************************************************************/
void Cy_SysTick_Enable(void)
{
Cy_SysTick_EnableInterrupt();
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
/*******************************************************************************
* Function Name: Cy_SysTick_Disable
****************************************************************************//**
*
* Disables the SysTick timer and its interrupt.
*
* \sideeffect Clears the SysTick count flag if it was set
*
*******************************************************************************/
void Cy_SysTick_Disable(void)
{
Cy_SysTick_DisableInterrupt();
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
/*******************************************************************************
* Function Name: Cy_SysTick_EnableInterrupt
****************************************************************************//**
*
* Enables the SysTick interrupt.
*
* \sideeffect Clears the SysTick count flag if it was set
*
*******************************************************************************/
void Cy_SysTick_EnableInterrupt(void)
{
SysTick->CTRL = SysTick->CTRL | SysTick_CTRL_TICKINT_Msk;
}
/*******************************************************************************
* Function Name: Cy_SysTick_DisableInterrupt
****************************************************************************//**
*
* Disables the SysTick interrupt.
*
* \sideeffect Clears the SysTick count flag if it was set
*
*******************************************************************************/
void Cy_SysTick_DisableInterrupt(void)
{
SysTick->CTRL = SysTick->CTRL & ~SysTick_CTRL_TICKINT_Msk;
}
/*******************************************************************************
* Function Name: Cy_SysTick_SetReload
****************************************************************************//**
*
* Sets the value the counter is set to on a startup and after it reaches zero.
* This function does not change or reset the current sysTick counter value, so
* it should be cleared using the Cy_SysTick_Clear() API.
*
* \param value: The valid range is [0x0-0x00FFFFFF]. The counter reset value.
*
*******************************************************************************/
void Cy_SysTick_SetReload(uint32_t value)
{
SysTick->LOAD = (value & SysTick_LOAD_RELOAD_Msk);
}
/*******************************************************************************
* Function Name: Cy_SysTick_GetReload
****************************************************************************//**
*
* Gets the value the counter is set to on a startup and after it reaches zero.
*
* \return The counter reset value.
*
*******************************************************************************/
uint32_t Cy_SysTick_GetReload(void)
{
return (SysTick->LOAD);
}
/*******************************************************************************
* Function Name: Cy_SysTick_GetValue
****************************************************************************//**
*
* Gets the current SysTick counter value.
*
* \return The current SysTick counter value.
*
*******************************************************************************/
uint32_t Cy_SysTick_GetValue(void)
{
return (SysTick->VAL);
}
/*******************************************************************************
* Function Name: Cy_SysTick_SetClockSource
****************************************************************************//**
*
* Sets the clock source for the SysTick counter.
*
* Clears the SysTick count flag if it was set. If the clock source is not ready
* this function call will have no effect. After changing the clock source to the
* low frequency clock, the counter and reload register values will remain
* unchanged so the time to the interrupt will be significantly longer and vice
* versa.
*
* Changing the SysTick clock source and/or its frequency will change
* the interrupt interval and that Cy_SysTick_SetReload() should be
* called to compensate this change.
*
* \param clockSource \ref cy_en_systick_clock_source_t Clock source.
*
*******************************************************************************/
void Cy_SysTick_SetClockSource(cy_en_systick_clock_source_t clockSource)
{
if (clockSource == CY_SYSTICK_CLOCK_SOURCE_CLK_CPU)
{
SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
}
else
{
CPUSS->SYSTICK_CTL = _VAL2FLD(CPUSS_SYSTICK_CTL_CLOCK_SOURCE, (uint32_t) clockSource);
SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk;
}
}
/*******************************************************************************
* Function Name: Cy_SysTick_GetClockSource
****************************************************************************//**
*
* Gets the clock source for the SysTick counter.
*
* \returns \ref cy_en_systick_clock_source_t Clock source
*
*******************************************************************************/
cy_en_systick_clock_source_t Cy_SysTick_GetClockSource(void)
{
cy_en_systick_clock_source_t returnValue;
if ((SysTick->CTRL & SysTick_CTRL_CLKSOURCE_Msk) != 0u)
{
returnValue = CY_SYSTICK_CLOCK_SOURCE_CLK_CPU;
}
else
{
returnValue = (cy_en_systick_clock_source_t)_FLD2VAL(CPUSS_SYSTICK_CTL_CLOCK_SOURCE, CPUSS->SYSTICK_CTL);
}
return(returnValue);
}
/*******************************************************************************
* Function Name: Cy_SysTick_GetCountFlag
****************************************************************************//**
*
* The count flag is set, once the SysTick counter reaches zero.
* The flag is cleared on read.
*
* \return Returns a non-zero value if a flag is set, otherwise a zero is
* returned.
*
* \sideeffect Clears the SysTick count flag if it was set.
*
*******************************************************************************/
uint32_t Cy_SysTick_GetCountFlag(void)
{
return (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk);
}
/*******************************************************************************
* Function Name: Cy_SysTick_Clear
****************************************************************************//**
*
* Clears the SysTick counter for a well-defined startup.
*
*******************************************************************************/
void Cy_SysTick_Clear(void)
{
SysTick->VAL = 0u;
}
/*******************************************************************************
* Function Name: Cy_SysTick_SetCallback
****************************************************************************//**
*
* This function allows up to five user-defined interrupt service routine
* functions to be associated with the SysTick interrupt. These are specified
* through the use of pointers to the function.
*
* \param number The number of the callback function addresses to be set.
* The valid range is from 0 to 4.
*
* \param function The pointer to the function that will be associated with the
* SysTick ISR for the specified number.
*
* \return Returns the address of the previous callback function.
* The NULL is returned if the specified address in not set.
*
* \sideeffect
* The registered callback functions will be executed in the interrupt.
*
*******************************************************************************/
Cy_SysTick_Callback Cy_SysTick_SetCallback(uint32_t number, Cy_SysTick_Callback function)
{
Cy_SysTick_Callback retVal;
retVal = Cy_SysTick_Callbacks[number];
Cy_SysTick_Callbacks[number] = function;
return (retVal);
}
/*******************************************************************************
* Function Name: Cy_SysTick_GetCallback
****************************************************************************//**
*
* The function gets the specified callback pointer.
*
* \param number The number of the callback function address to get. The valid
* range is from 0 to 4.
*
* \return
* Returns the address of the specified callback function.
* The NULL is returned if the specified address in not initialized.
*
*******************************************************************************/
Cy_SysTick_Callback Cy_SysTick_GetCallback(uint32_t number)
{
return ((Cy_SysTick_Callback) Cy_SysTick_Callbacks[number]);
}
/*******************************************************************************
* Function Name: Cy_SysTick_ServiceCallbacks
****************************************************************************//**
*
* The system Tick timer interrupt routine.
*
*******************************************************************************/
static void Cy_SysTick_ServiceCallbacks(void)
{
uint32_t i;
/* Verify that tick timer flag was set */
if (0u != Cy_SysTick_GetCountFlag())
{
for (i=0u; i < CY_SYS_SYST_NUM_OF_CALLBACKS; i++)
{
if (Cy_SysTick_Callbacks[i] != (void *) 0)
{
(void)(Cy_SysTick_Callbacks[i])();
}
}
}
}
/* [] END OF FILE */

View File

@ -0,0 +1,170 @@
/***************************************************************************//**
* \file cy_systick.h
* \version 1.0
*
* Provides the API declarations of the SysTick driver.
*
********************************************************************************
* \copyright
* Copyright 2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#ifndef _CY_SYSTICK_H_
#define _CY_SYSTICK_H_
/**
* \defgroup group_arm_system_timer ARM System Timer (SysTick)
* \{
* Provides a SysTick API.
*
* \section group_systick_configuration Configuration Considerations
*
* The SysTick timer is part of the CPU. The timer is a down counter with a
* 24-bit reload/tick value that is clocked by the FastClk/SlowClk. The timer has
* the capability to generate an interrupt when the set number of ticks expires
* and the counter is reloaded. This interrupt is available as part of the Nested
* Vectored Interrupt Controller (NVIC) for service by the CPU and can be used
* for general purpose timing control in user code.
*
* Changing the SysTick clock source and/or its frequency will change the
* interrupt interval and therefore Cy_SysTick_SetReload() should be called to
* compensate for this change.
*
* Because the timer is independent of the CPU (except for the clock), this can be
* handy in applications requiring precise timing that do not have a dedicated
* timer/counter available for the job.
*
* \section group_systick_more_information More Information
*
* Refer to the SysTick section of the ARM reference guide for complete details
* on the registers and their use.
*
* \section group_systick_MISRA MISRA-C Compliance
*
* <table class="doxtable">
* <tr>
* <th>MISRA Rule</th>
* <th>Rule Class (Required/Advisory)</th>
* <th>Rule Description</th>
* <th>Description of Deviation(s)</th>
* </tr>
* <tr>
* <td>8.8</td>
* <td>Required</td>
* <td>An external object or function shall be declared in one and only one file.</td>
* <td>The variable is not used within project, so is defined without previous declaration.</td>
* </tr>
* </table>
*
* \section group_systick_changelog Changelog
*
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_systick_macro Macro
* \defgroup group_systick_functions Functions
* \defgroup group_systick_data_structures Data Structures
*/
#include <stdint.h>
#include <stdbool.h>
#include "syslib/cy_syslib.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \cond */
extern cy_israddress __ramVectors[];
typedef void (*Cy_SysTick_Callback)(void);
/** \endcond */
/**
* \addtogroup group_systick_data_structures
* \{
*/
typedef enum
{
/** The low frequency clock clk_lf is selected. The precision of this clock depends on whether the low frequency
clock source is a SRSS internal RC oscillator (imprecise) or a device external crystal oscillator (precise) */
CY_SYSTICK_CLOCK_SOURCE_CLK_LF = 0u,
/** The internal main oscillator (IMO) clock clk_imo is selected. */
CY_SYSTICK_CLOCK_SOURCE_CLK_IMO = 1u,
/** The external crystal oscillator (ECO) clock clk_eco is selected. */
CY_SYSTICK_CLOCK_SOURCE_CLK_ECO = 2u,
/** The SRSS clk_timer is selected. The clk_timer is a divided/gated version of clk_hf or clk_imo. */
CY_SYSTICK_CLOCK_SOURCE_CLK_TIMER = 3u,
/** The CPU clock is selected. */
CY_SYSTICK_CLOCK_SOURCE_CLK_CPU = 4u,
} cy_en_systick_clock_source_t;
/** \} group_systick_data_structures */
/**
* \addtogroup group_systick_functions
* \{
*/
void Cy_SysTick_Init(cy_en_systick_clock_source_t clockSource, uint32_t interval);
void Cy_SysTick_Enable(void);
void Cy_SysTick_Disable(void);
void Cy_SysTick_EnableInterrupt(void);
void Cy_SysTick_DisableInterrupt(void);
void Cy_SysTick_SetReload(uint32_t value);
uint32_t Cy_SysTick_GetReload(void);
uint32_t Cy_SysTick_GetValue(void);
Cy_SysTick_Callback Cy_SysTick_SetCallback(uint32_t number, Cy_SysTick_Callback function);
Cy_SysTick_Callback Cy_SysTick_GetCallback(uint32_t number);
void Cy_SysTick_SetClockSource(cy_en_systick_clock_source_t clockSource);
cy_en_systick_clock_source_t Cy_SysTick_GetClockSource(void);
uint32_t Cy_SysTick_GetCountFlag(void);
void Cy_SysTick_Clear(void);
/** \} group_systick_functions */
/**
* \addtogroup group_systick_macro
* \{
*/
/** Driver major version */
#define SYSTICK_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define SYSTICK_DRV_VERSION_MINOR 0
/** Number of the callbacks assigned to the SysTick interrupt */
#define CY_SYS_SYST_NUM_OF_CALLBACKS (5u)
/** Interrupt number in the vector table */
#define CY_SYSTICK_IRQ_NUM (15u)
/** \} group_systick_macro */
#ifdef __cplusplus
}
#endif
#endif /* _CY_SYSTICK_H_ */
/** \} group_systick */
/* [] END OF FILE */

View File

@ -0,0 +1,591 @@
/***************************************************************************//**
* \file cy_tcpwm.h
* \version 1.0
*
* The header file of the TCPWM driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_tcpwm Timer Counter PWM (TCPWM)
* \{
* \defgroup group_tcpwm_common Common
* \defgroup group_tcpwm_counter Timer/Counter (TCPWM)
* \defgroup group_tcpwm_pwm PWM (TCPWM)
* \defgroup group_tcpwm_quaddec Quadrature Decoder (TCPWM)
* \} */
/**
* \addtogroup group_tcpwm
* \{
*
* The TCPWM driver is a multifunction driver that implements core
* microcontroller functionality including Timer Counter, PWM, and
* Quadrature Decoder using the TCPWM block.
*
* The driver is based on a hardware structure designed to share the same
* hardware across the various modes of operation. This structure
* allows a single driver to provide a flexible set of functions.
*
* A TCPWM is a collection of counters that can all be triggered simultaneously.
* For each function call, the base register address of the TCPWM being used must
* be passed first, followed by the index of the counter you want to touch next.
* For some functions, you can manage multiple counters simultaneously. You
* provide a bit field representing each counter, rather than the single counter
* index).
*
* The TCPWM supports three operating modes:
* * Timer/Counter
* * PWM
* * Quadrature Decoder
*
* \n
* \b Timer/Counter
*
* Use this mode whenever a specific timing interval or measurement is
* needed. Examples include:
* * Creating a periodic interrupt for running other system tasks
* * Measuring frequency of an input signal
* * Measuring pulse width of an input signal
* * Measuring time between two external events
* * Counting events
* * Triggering other system resources after x number events
* * Capturing time stamps when events occur
*
* The Timer/Counter has the following features:
* * 16- or 32-bit Timer/Counter
* * Programmable Period Register
* * Programmable Compare Register. Compare value can be swapped with a
* buffered compare value on comparison event
* * Capture with buffer register
* * Count Up, Count Down, or Count Up and Down Counting modes
* * Continuous or One Shot Run modes
* * Interrupt and Output on Overflow, Underflow, Capture, or Compare
* * Start, Reload, Stop, Capture, and Count Inputs
*
* \n
* \b PWM
*
* Use this mode when an output square wave is needed with a specific
* period and duty cycle, such as:
* * Creating arbitrary square wave outputs
* * Driving an LED (changing the brightness)
* * Driving Motors (dead time assertion available)
*
* The PWM has the following features:
* * 16- or 32-bit Counter
* * Two Programmable Period registers that can be swapped on overflow
* * Two Output Compare registers that can be swapped on overflow and/or
* underflow
* * Left Aligned, Right Aligned, Center Aligned, and Asymmetric Aligned modes
* * Continuous or One Shot run modes
* * Pseudo Random mode
* * Two PWM outputs with Dead Time insertion, and programmable polarity
* * Interrupt and Output on Overflow, Underflow, or Compare
* * Start, Reload, Stop, Swap (Capture), and Count Inputs
*
* \n
* \b Quadrature \b Decoder
*
* A quadrature decoder is used to decode the output of a quadrature encoder.
* A quadrature encoder senses the position, velocity, and direction of
* an object (for example a rotating axle, or a spinning mouse ball).
* A quadrature decoder can also be used for precision measurement of speed,
* acceleration, and position of a motor's rotor, or with a rotary switch to
* determine user input. \n
*
* The Quadrature Decoder has the following features:
* * 16- or 32-bit Counter
* * Counter Resolution of x1, x2, and x4 the frequency of the phiA (Count) and
* phiB (Start) inputs
* * Index (Reload) Input to determine absolute position
* * A positive edge on phiA increments the counter when phiB is 0 and decrements
* the counter when phiB is 1
*
* \section group_tcpwm_configuration Configuration Considerations
*
* For each mode, the TCPWM driver has a configuration structure, an Init
* function, and an Enable function.
*
* Provide the configuration parameters in the appropriate structure (see
* \ref group_tcpwm_data_structures). Then call the appropriate Init function:
* \ref Cy_TCPWM_Counter_Init, \ref Cy_TCPWM_PWM_Init, or
* \ref Cy_TCPWM_QuadDec_Init. Provide the address of the filled structure as a
* parameter. To enable the counter, call the appropriate Enable function:
* \ref Cy_TCPWM_Counter_Enable, \ref Cy_TCPWM_PWM_Enable, or
* \ref Cy_TCPWM_QuadDec_Enable).
*
* Many functions work with an individual counter. You can also manage multiple
* counters simultaneously for certain functions. These are listed in the
* \ref group_tcpwm_functions_common functions
* section of the TCPWM. You can enable, disable, or trigger (in various ways)
* multiple counters simultaneously. For these functions you provide a bit field
* representing each counter in the TCPWM you want to control. You can
* represent the bit field as an ORed mask of each counter, like
* ((1u << cntNumX) | (1u << cntNumX) | (1u << cntNumX)), where X is the counter
* number from 0 to 31.
*
* \note
* * If none of the input terminals (start, reload(index)) are used, the
* software event \ref Cy_TCPWM_TriggerStart or
* \ref Cy_TCPWM_TriggerReloadOrIndex must be called to start the counting.
* * If count input terminal is not used, the \ref CY_TCPWM_INPUT_LEVEL macro
* should be set for the countInputMode parameter and the \ref CY_TCPWM_INPUT_1
* macro should be set for the countInputMode parameter in the configuration
* structure (\ref group_tcpwm_data_structures) of the appropriate mode.
*
* \section group_tcpwm_more_information More Information
*
* For more information on the TCPWM peripheral, refer to the technical
* reference manual (TRM).
*
* \section group_tcpwm_MISRA MISRA-C Compliance
* The tcpwm driver does not have any specific deviations
*
* \section group_tcpwm_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*/
/** \} group_tcpwm */
/**
* \addtogroup group_tcpwm_common
* Common API for the Timer Counter PWM Block.
* \{
* \defgroup group_tcpwm_macro_common Macro
* \defgroup group_tcpwm_functions_common Functions
* \defgroup group_tcpwm_data_structures_common Data Structures
* \defgroup group_tcpwm_enums Enumerated Types
*/
#if !defined(CY_TCPWM_H)
#define CY_TCPWM_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_tcpwm_macro_common
* \{
*/
/** Driver major version */
#define CY_TCPWM_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_TCPWM_DRV_VERSION_MINOR 0
/******************************************************************************
* API Constants
******************************************************************************/
/** TCPWM driver identifier */
#define CY_TCPWM_ID (CY_PDL_DRV_ID(0x2Du))
/** \defgroup group_tcpwm_input_selection TCPWM Input Selection
* \{
* Selects which input to use
*/
#define CY_TCPWM_INPUT_0 (0u) /**< Input is tied to logic 0 */
#define CY_TCPWM_INPUT_1 (1u) /**< Input is tied to logic 1 */
#define CY_TCPWM_INPUT_TRIG_0 (2u) /**< Input is connected to the trigger input 0 */
#define CY_TCPWM_INPUT_TRIG_1 (3u) /**< Input is connected to the trigger input 1 */
#define CY_TCPWM_INPUT_TRIG_2 (4u) /**< Input is connected to the trigger input 2 */
#define CY_TCPWM_INPUT_TRIG_3 (5u) /**< Input is connected to the trigger input 3 */
#define CY_TCPWM_INPUT_TRIG_4 (6u) /**< Input is connected to the trigger input 4 */
#define CY_TCPWM_INPUT_TRIG_5 (7u) /**< Input is connected to the trigger input 5 */
#define CY_TCPWM_INPUT_TRIG_6 (8u) /**< Input is connected to the trigger input 6 */
#define CY_TCPWM_INPUT_TRIG_7 (9u) /**< Input is connected to the trigger input 7 */
#define CY_TCPWM_INPUT_TRIG_8 (10u) /**< Input is connected to the trigger input 8 */
#define CY_TCPWM_INPUT_TRIG_9 (11u) /**< Input is connected to the trigger input 9 */
#define CY_TCPWM_INPUT_TRIG_10 (12u) /**< Input is connected to the trigger input 10 */
#define CY_TCPWM_INPUT_TRIG_11 (13u) /**< Input is connected to the trigger input 11 */
#define CY_TCPWM_INPUT_TRIG_12 (14u) /**< Input is connected to the trigger input 12 */
#define CY_TCPWM_INPUT_TRIG_13 (15u) /**< Input is connected to the trigger input 13 */
/** Input is defined by Creator, and Init() function does not need to configure input */
#define CY_TCPWM_INPUT_CREATOR (65535u)
/** \} group_tcpwm_input_selection */
/**
* \defgroup group_tcpwm_input_modes Input Modes
* \{
* Configures how TCPWM inputs behave
*/
/** A rising edge triggers the event (Capture, Start, Reload, etc..) */
#define CY_TCPWM_INPUT_RISINGEDGE (0u)
/** A falling edge triggers the event (Capture, Start, Reload, etc..) */
#define CY_TCPWM_INPUT_FALLINGEDGE (1u)
/** A rising edge or falling edge triggers the event (Capture, Start, Reload, etc..) */
#define CY_TCPWM_INPUT_EITHEREDGE (2u)
/** The event is triggered on each edge of the TCPWM clock if the input is high */
#define CY_TCPWM_INPUT_LEVEL (3u)
/** \} group_tcpwm_input_modes */
/**
* \defgroup group_tcpwm_interrupt_sources Interrupt Sources
* \{
* Interrupt Sources
*/
#define CY_TCPWM_INT_ON_TC (1u) /**< Interrupt on Terminal count(TC) */
#define CY_TCPWM_INT_ON_CC (2u) /**< Interrupt on Compare/Capture(CC) */
#define CY_TCPWM_INT_NONE (0u) /**< No Interrupt */
#define CY_TCPWM_INT_ON_CC_OR_TC (3u) /**< Interrupt on TC or CC */
/** \} group_tcpwm_interrupt_sources */
/***************************************
* Registers Constants
***************************************/
/**
* \defgroup group_tcpwm_reg_const Default registers constants
* \{
* Default constants for CNT Registers
*/
#define CY_TCPWM_CNT_CTRL_DEFAULT (0x0u) /**< Default value for CTRL register */
#define CY_TCPWM_CNT_COUNTER_DEFAULT (0x0u) /**< Default value for COUNTER register */
#define CY_TCPWM_CNT_CC_DEFAULT (0xFFFFFFFFu) /**< Default value for CC register */
#define CY_TCPWM_CNT_CC_BUFF_DEFAULT (0xFFFFFFFFu) /**< Default value for CC_BUFF register */
#define CY_TCPWM_CNT_PERIOD_DEFAULT (0xFFFFFFFFu) /**< Default value for PERIOD register */
#define CY_TCPWM_CNT_PERIOD_BUFF_DEFAULT (0xFFFFFFFFu) /**< Default value for PERIOD_BUFF register */
#define CY_TCPWM_CNT_TR_CTRL0_DEFAULT (0x10u) /**< Default value for TR_CTRL0 register */
#define CY_TCPWM_CNT_TR_CTRL1_DEFAULT (0x3FFu) /**< Default value for TR_CTRL1 register */
#define CY_TCPWM_CNT_TR_CTRL2_DEFAULT (0x3Fu) /**< Default value for TR_CTRL2 register */
#define CY_TCPWM_CNT_INTR_DEFAULT (0x3u) /**< Default value for INTR register */
#define CY_TCPWM_CNT_INTR_SET_DEFAULT (0x0u) /**< Default value for INTR_SET register */
#define CY_TCPWM_CNT_INTR_MASK_DEFAULT (0x0u) /**< Default value for INTR_MASK register */
/** \} group_tcpwm_reg_const */
/** Position of Up counting counter status */
#define CY_TCPWM_CNT_STATUS_UP_POS (0x1u)
/** Initial value for the counter in the Up counting mode */
#define CY_TCPWM_CNT_UP_INIT_VAL (0x0u)
/** Initial value for the counter in the Up/Down counting modes */
#define CY_TCPWM_CNT_UP_DOWN_INIT_VAL (0x1u)
/** \} group_tcpwm_macro_common */
/*******************************************************************************
* Enumerations
******************************************************************************/
/**
* \addtogroup group_tcpwm_enums
* \{
*/
/** TCPWM status definitions */
typedef enum
{
CY_TCPWM_SUCCESS = 0x00u, /**< Successful */
CY_TCPWM_BAD_PARAM = CY_TCPWM_ID | CY_PDL_STATUS_ERROR | 0x01u, /**< One or more invalid parameters */
} cy_en_tcpwm_status_t;
/** \} group_tcpwm_enums */
/*******************************************************************************
* Function Prototypes
*******************************************************************************/
/**
* \addtogroup group_tcpwm_functions_common
* \{
*/
__STATIC_INLINE void Cy_TCPWM_Enable_Multiple(TCPWM_Type *base, uint32_t counters);
__STATIC_INLINE void Cy_TCPWM_Disable_Multiple(TCPWM_Type *base, uint32_t counters);
__STATIC_INLINE void Cy_TCPWM_TriggerStart(TCPWM_Type *base, uint32_t counters);
__STATIC_INLINE void Cy_TCPWM_TriggerReloadOrIndex(TCPWM_Type *base, uint32_t counters);
__STATIC_INLINE void Cy_TCPWM_TriggerStopOrKill(TCPWM_Type *base, uint32_t counters);
__STATIC_INLINE void Cy_TCPWM_TriggerCaptureOrSwap(TCPWM_Type *base, uint32_t counters);
__STATIC_INLINE uint32_t Cy_TCPWM_GetInterruptStatus(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_ClearInterrupt(TCPWM_Type *base, uint32_t cntNum, uint32_t source);
__STATIC_INLINE void Cy_TCPWM_SetInterrupt(TCPWM_Type *base, uint32_t cntNum, uint32_t source);
__STATIC_INLINE void Cy_TCPWM_SetInterruptMask(TCPWM_Type *base, uint32_t cntNum, uint32_t mask);
__STATIC_INLINE uint32_t Cy_TCPWM_GetInterruptMask(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE uint32_t Cy_TCPWM_GetInterruptStatusMasked(TCPWM_Type const *base, uint32_t cntNum);
/*******************************************************************************
* Function Name: Cy_TCPWM_Enable_Multiple
****************************************************************************//**
*
* Enables the counter(s) in the TCPWM block. Multiple blocks can be started
* simultaneously.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param counters
* A bit field representing each counter in the TCPWM block.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_Enable_Multiple(TCPWM_Type *base, uint32_t counters)
{
base->CTRL_SET = counters;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Disable_Multiple
****************************************************************************//**
*
* Disables the counter(s) in the TCPWM block. Multiple TCPWM can be disabled
* simultaneously.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param counters
* A bit field representing each counter in the TCPWM block.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_Disable_Multiple(TCPWM_Type *base, uint32_t counters)
{
base->CTRL_CLR = counters;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_TriggerStart
****************************************************************************//**
*
* Triggers a software start on the selected TCPWMs.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param counters
* A bit field representing each counter in the TCPWM block.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_TriggerStart(TCPWM_Type *base, uint32_t counters)
{
base->CMD_START = counters;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_TriggerReloadOrIndex
****************************************************************************//**
*
* Triggers a software reload event (or index in QuadDec mode).
*
* \param base
* The pointer to a TCPWM instance
*
* \param counters
* A bit field representing each counter in the TCPWM block.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_TriggerReloadOrIndex(TCPWM_Type *base, uint32_t counters)
{
base->CMD_RELOAD = counters;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_TriggerStopOrKill
****************************************************************************//**
*
* Triggers a stop in the Timer Counter mode, or a kill in the PWM mode.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param counters
* A bit field representing each counter in the TCPWM block.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_TriggerStopOrKill(TCPWM_Type *base, uint32_t counters)
{
base->CMD_STOP = counters;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_TriggerCaptureOrSwap
****************************************************************************//**
*
* Triggers a Capture in the Timer Counter mode, and a Swap in the PWM mode.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param counters
* A bit field representing each counter in the TCPWM block.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_TriggerCaptureOrSwap(TCPWM_Type *base, uint32_t counters)
{
base->CMD_CAPTURE = counters;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_GetInterruptStatus
****************************************************************************//**
*
* Returns which event triggered the interrupt.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
*. See \ref group_tcpwm_interrupt_sources
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_GetInterruptStatus(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].INTR);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_ClearInterrupt
****************************************************************************//**
*
* Clears Active Interrupt Source
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param source
* source to clear. See \ref group_tcpwm_interrupt_sources
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_ClearInterrupt(TCPWM_Type *base, uint32_t cntNum, uint32_t source)
{
base->CNT[cntNum].INTR = source;
(void)base->CNT[cntNum].INTR;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_SetInterrupt
****************************************************************************//**
*
* Triggers an interrupt via a software write.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param source
* The source to set an interrupt. See \ref group_tcpwm_interrupt_sources.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_SetInterrupt(TCPWM_Type *base, uint32_t cntNum, uint32_t source)
{
base->CNT[cntNum].INTR_SET = source;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_SetInterruptMask
****************************************************************************//**
*
* Sets an interrupt mask. A 1 means that when the event occurs, it will cause an
* interrupt; a 0 means no interrupt will be triggered.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param mask
*. See \ref group_tcpwm_interrupt_sources
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_SetInterruptMask(TCPWM_Type *base, uint32_t cntNum, uint32_t mask)
{
base->CNT[cntNum].INTR_MASK = mask;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_GetInterruptMask
****************************************************************************//**
*
* Returns the interrupt mask.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* Interrupt Mask. See \ref group_tcpwm_interrupt_sources
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_GetInterruptMask(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].INTR_MASK);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_GetInterruptStatusMasked
****************************************************************************//**
*
* Returns which masked interrupt triggered the interrupt.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* Interrupt Mask. See \ref group_tcpwm_interrupt_sources
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_GetInterruptStatusMasked(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].INTR_MASKED);
}
/** \} group_tcpwm_functions_common */
/** \} group_tcpwm_common */
#if defined(__cplusplus)
}
#endif
#endif /* CY_TCPWM_H */
/* [] END OF FILE */

View File

@ -0,0 +1,137 @@
/***************************************************************************//**
* \file cy_tcpwm_counter.c
* \version 1.0
*
* \brief
* The source file of the tcpwm driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_tcpwm_counter.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_Init
****************************************************************************//**
*
* Initializes the counter in the TCPWM block for the Counter operation.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param config
* The pointer to configuration structure. See \ref cy_stc_tcpwm_counter_config_t.
*
* \return error / status code. See \ref cy_en_tcpwm_status_t.
*
*******************************************************************************/
cy_en_tcpwm_status_t Cy_TCPWM_Counter_Init(TCPWM_Type *base, uint32_t cntNum, cy_stc_tcpwm_counter_config_t const *config)
{
cy_en_tcpwm_status_t status = CY_TCPWM_BAD_PARAM;
if ((NULL != base) && (NULL != config))
{
base->CNT[cntNum].CTRL = ( _VAL2FLD(TCPWM_CNT_CTRL_GENERIC, config->clockPrescaler) |
_VAL2FLD(TCPWM_CNT_CTRL_ONE_SHOT, config->runMode) |
_VAL2FLD(TCPWM_CNT_CTRL_UP_DOWN_MODE, config->countDirection) |
_VAL2FLD(TCPWM_CNT_CTRL_MODE, config->compareOrCapture) |
(config->enableCompareSwap ? TCPWM_CNT_CTRL_AUTO_RELOAD_CC_Msk : 0uL));
if (CY_TCPWM_COUNTER_COUNT_UP == config->runMode)
{
base->CNT[cntNum].COUNTER = CY_TCPWM_CNT_UP_INIT_VAL;
}
else if (CY_TCPWM_COUNTER_COUNT_DOWN == config->runMode)
{
base->CNT[cntNum].COUNTER = config->period;
}
else
{
base->CNT[cntNum].COUNTER = CY_TCPWM_CNT_UP_DOWN_INIT_VAL;
}
base->CNT[cntNum].CC = config->compare0;
base->CNT[cntNum].CC_BUFF = config->compare1;
base->CNT[cntNum].PERIOD = config->period;
if (CY_TCPWM_INPUT_CREATOR != config->countInput)
{
base->CNT[cntNum].TR_CTRL0 = (_VAL2FLD(TCPWM_CNT_TR_CTRL0_CAPTURE_SEL, config->captureInput) |
_VAL2FLD(TCPWM_CNT_TR_CTRL0_RELOAD_SEL, config->reloadInput) |
_VAL2FLD(TCPWM_CNT_TR_CTRL0_START_SEL, config->startInput) |
_VAL2FLD(TCPWM_CNT_TR_CTRL0_STOP_SEL, config->stopInput) |
_VAL2FLD(TCPWM_CNT_TR_CTRL0_COUNT_SEL, config->countInput));
}
base->CNT[cntNum].TR_CTRL1 = (_VAL2FLD(TCPWM_CNT_TR_CTRL1_CAPTURE_EDGE, config->captureInputMode) |
_VAL2FLD(TCPWM_CNT_TR_CTRL1_RELOAD_EDGE, config->reloadInputMode) |
_VAL2FLD(TCPWM_CNT_TR_CTRL1_START_EDGE, config->startInputMode) |
_VAL2FLD(TCPWM_CNT_TR_CTRL1_STOP_EDGE, config->stopInputMode) |
_VAL2FLD(TCPWM_CNT_TR_CTRL1_COUNT_EDGE, config->countInputMode));
base->CNT[cntNum].INTR_MASK = config->interruptSources;
status = CY_TCPWM_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_DeInit
****************************************************************************//**
*
* De-initializes the counter in the TCPWM block, returns register values to
* default.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param config
* The pointer to configuration structure. See \ref cy_stc_tcpwm_counter_config_t.
*
*******************************************************************************/
void Cy_TCPWM_Counter_DeInit(TCPWM_Type *base, uint32_t cntNum, cy_stc_tcpwm_counter_config_t const *config)
{
base->CNT[cntNum].CTRL = CY_TCPWM_CNT_CTRL_DEFAULT;
base->CNT[cntNum].COUNTER = CY_TCPWM_CNT_COUNTER_DEFAULT;
base->CNT[cntNum].CC = CY_TCPWM_CNT_CC_DEFAULT;
base->CNT[cntNum].CC_BUFF = CY_TCPWM_CNT_CC_BUFF_DEFAULT;
base->CNT[cntNum].PERIOD = CY_TCPWM_CNT_PERIOD_DEFAULT;
base->CNT[cntNum].PERIOD_BUFF = CY_TCPWM_CNT_PERIOD_BUFF_DEFAULT;
base->CNT[cntNum].TR_CTRL1 = CY_TCPWM_CNT_TR_CTRL1_DEFAULT;
base->CNT[cntNum].TR_CTRL2 = CY_TCPWM_CNT_TR_CTRL2_DEFAULT;
base->CNT[cntNum].INTR = CY_TCPWM_CNT_INTR_DEFAULT;
base->CNT[cntNum].INTR_SET = CY_TCPWM_CNT_INTR_SET_DEFAULT;
base->CNT[cntNum].INTR_MASK = CY_TCPWM_CNT_INTR_MASK_DEFAULT;
if (CY_TCPWM_INPUT_CREATOR != config->countInput)
{
base->CNT[cntNum].TR_CTRL0 = CY_TCPWM_CNT_TR_CTRL0_DEFAULT;
}
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */

View File

@ -0,0 +1,484 @@
/***************************************************************************//**
* \file cy_tcpwm_counter.h
* \version 1.0
*
* \brief
* The header file of the TCPWM Timer Counter driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_tcpwm_macro_counter Macro
* \defgroup group_tcpwm_functions_counter Functions
* \defgroup group_tcpwm_data_structures_counter Data Structures
* \} */
#if !defined(CY_TCPWM_COUNTER_H)
#define CY_TCPWM_COUNTER_H
#include "cy_tcpwm.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_tcpwm_counter
* \{
* Driver API for Timer/Counter.
*/
/**
* \addtogroup group_tcpwm_data_structures_counter
* \{
*/
/** Counter Timer configuration structure */
typedef struct cy_stc_tcpwm_counter_config
{
uint32_t period; /**< Sets the period of the counter */
/** Sets the clock prescaler inside the TCWPM block. See \ref group_tcpwm_counter_clk_prescalers */
uint32_t clockPrescaler;
uint32_t runMode; /**< Sets the Counter Timer Run mode. See \ref group_tcpwm_counter_run_modes */
uint32_t countDirection; /**< Sets the counter direction. See \ref group_tcpwm_counter_direction */
/** The counter can either compare or capture a value. See \ref group_tcpwm_counter_compare_capture */
uint32_t compareOrCapture;
uint32_t compare0; /**< Sets the value for Compare0*/
uint32_t compare1; /**< Sets the value for Compare1*/
bool enableCompareSwap; /**< If enabled, the compare values are swapped each time the comparison is true */
/** Enabled an interrupt on the terminal count, capture or compare. See \ref group_tcpwm_interrupt_sources */
uint32_t interruptSources;
uint32_t captureInputMode; /**< Configures how the capture input behaves. See \ref group_tcpwm_input_modes */
/** Selects which input the capture uses, the inputs are device-specific. See \ref group_tcpwm_input_selection */
uint32_t captureInput;
uint32_t reloadInputMode; /**< Configures how the reload input behaves. See \ref group_tcpwm_input_modes */
/** Selects which input the reload uses, the inputs are device-specific. See \ref group_tcpwm_input_selection */
uint32_t reloadInput;
uint32_t startInputMode; /**< Configures how the start input behaves. See \ref group_tcpwm_input_modes */
/** Selects which input the start uses, the inputs are device-specific. See \ref group_tcpwm_input_selection */
uint32_t startInput;
uint32_t stopInputMode; /**< Configures how the stop input behaves. See \ref group_tcpwm_input_modes */
/** Selects which input the stop uses, the inputs are device-specific. See \ref group_tcpwm_input_selection */
uint32_t stopInput;
uint32_t countInputMode; /**< Configures how the count input behaves. See \ref group_tcpwm_input_modes */
/** Selects which input the count uses, the inputs are device-specific. See \ref group_tcpwm_input_selection */
uint32_t countInput;
}cy_stc_tcpwm_counter_config_t;
/** \} group_tcpwm_data_structures_counter */
/**
* \addtogroup group_tcpwm_macro_counter
* \{
* \defgroup group_tcpwm_counter_run_modes Counter Run Modes
* \{
* Run modes for the counter timer.
*/
#define CY_TCPWM_COUNTER_ONESHOT (1u) /**< Counter runs once and then stops */
#define CY_TCPWM_COUNTER_CONTINUOUS (0u) /**< Counter runs forever */
/** \} group_tcpwm_counter_run_modes */
/** \defgroup group_tcpwm_counter_direction Counter Direction
* The counter directions.
* \{
*/
#define CY_TCPWM_COUNTER_COUNT_UP (0u) /**< Counter counts up */
#define CY_TCPWM_COUNTER_COUNT_DOWN (1u) /**< Counter counts down */
/** Counter counts up and down terminal count only occurs on underflow. */
#define CY_TCPWM_COUNTER_COUNT_UP_DOWN0 (2u)
/** Counter counts up and down terminal count occurs on both overflow and underflow. */
#define CY_TCPWM_COUNTER_COUNT_UP_DOWN1 (3u)
/** \} group_tcpwm_counter_direction */
/** \defgroup group_tcpwm_counter_clk_prescalers Counter CLK Prescalers
* \{
* The clock prescaler values.
*/
#define CY_TCPWM_COUNTER_PRESCALER_DIVBY_1 (0u) /**< Divide by 1 */
#define CY_TCPWM_COUNTER_PRESCALER_DIVBY_2 (1u) /**< Divide by 2 */
#define CY_TCPWM_COUNTER_PRESCALER_DIVBY_4 (2u) /**< Divide by 4 */
#define CY_TCPWM_COUNTER_PRESCALER_DIVBY_8 (3u) /**< Divide by 8 */
#define CY_TCPWM_COUNTER_PRESCALER_DIVBY_16 (4u) /**< Divide by 16 */
#define CY_TCPWM_COUNTER_PRESCALER_DIVBY_32 (5u) /**< Divide by 32 */
#define CY_TCPWM_COUNTER_PRESCALER_DIVBY_64 (6u) /**< Divide by 64 */
#define CY_TCPWM_COUNTER_PRESCALER_DIVBY_128 (7u) /**< Divide by 128 */
/** \} group_tcpwm_counter_clk_prescalers */
/** \defgroup group_tcpwm_counter_compare_capture Counter Compare Capture
* \{
* A compare or capture mode.
*/
#define CY_TCPWM_COUNTER_MODE_CAPTURE (2u) /**< Timer/Counter is in Capture Mode */
#define CY_TCPWM_COUNTER_MODE_COMPARE (0u) /**< Timer/Counter is in Compare Mode */
/** \} group_tcpwm_counter_compare_capture */
/** \defgroup group_tcpwm_counter_status Counter Status
* \{
* The counter status.
*/
#define CY_TCPWM_COUNTER_STATUS_DOWN_COUNTING (0x1uL) /**< Timer/Counter is down counting */
#define CY_TCPWM_COUNTER_STATUS_UP_COUNTING (0x2uL) /**< Timer/Counter is up counting */
/** Timer/Counter is running */
#define CY_TCPWM_COUNTER_STATUS_COUNTER_RUNNING (TCPWM_CNT_STATUS_RUNNING_Msk)
/** \} group_tcpwm_counter_status */
/** \} group_tcpwm_macro_counter */
/*******************************************************************************
* Function Prototypes
*******************************************************************************/
/**
* \addtogroup group_tcpwm_functions_counter
* \{
*/
cy_en_tcpwm_status_t Cy_TCPWM_Counter_Init(TCPWM_Type *base, uint32_t cntNum, cy_stc_tcpwm_counter_config_t const *config);
void Cy_TCPWM_Counter_DeInit(TCPWM_Type *base, uint32_t cntNum, cy_stc_tcpwm_counter_config_t const *config);
__STATIC_INLINE void Cy_TCPWM_Counter_Enable(TCPWM_Type *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_Counter_Disable(TCPWM_Type *base, uint32_t cntNum);
__STATIC_INLINE uint32_t Cy_TCPWM_Counter_GetStatus(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE uint32_t Cy_TCPWM_Counter_GetCapture(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE uint32_t Cy_TCPWM_Counter_GetCaptureBuf(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_Counter_SetCompare0(TCPWM_Type *base, uint32_t cntNum, uint32_t compare0);
__STATIC_INLINE uint32_t Cy_TCPWM_Counter_GetCompare0(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_Counter_SetCompare1(TCPWM_Type *base, uint32_t cntNum, uint32_t compare1);
__STATIC_INLINE uint32_t Cy_TCPWM_Counter_GetCompare1(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_Counter_EnableCompareSwap(TCPWM_Type *base, uint32_t cntNum, bool enable);
__STATIC_INLINE void Cy_TCPWM_Counter_SetCounter(TCPWM_Type *base, uint32_t cntNum, uint32_t count);
__STATIC_INLINE uint32_t Cy_TCPWM_Counter_GetCounter(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_Counter_SetPeriod(TCPWM_Type *base, uint32_t cntNum, uint32_t period);
__STATIC_INLINE uint32_t Cy_TCPWM_Counter_GetPeriod(TCPWM_Type const *base, uint32_t cntNum);
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_Enable
****************************************************************************//**
*
* Enables the counter in the TCPWM block for the Counter operation.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_Counter_Enable(TCPWM_Type *base, uint32_t cntNum)
{
base->CTRL_SET = (1uL << cntNum);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_Disable
****************************************************************************//**
*
* Disables the counter in the TCPWM block.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_Counter_Disable(TCPWM_Type *base, uint32_t cntNum)
{
base->CTRL_CLR = (1uL << cntNum);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_GetStatus
****************************************************************************//**
*
* Returns the status of the Counter Timer.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* The status. See \ref group_tcpwm_counter_status
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_Counter_GetStatus(TCPWM_Type const *base, uint32_t cntNum)
{
uint32_t status = base->CNT[cntNum].STATUS;
/* Generates proper up counting status. Is not generated by HW */
status &= ~CY_TCPWM_COUNTER_STATUS_UP_COUNTING;
status |= ((~status & CY_TCPWM_COUNTER_STATUS_DOWN_COUNTING & (status >> TCPWM_CNT_STATUS_RUNNING_Pos)) <<
CY_TCPWM_CNT_STATUS_UP_POS);
return(status);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_GetCapture
****************************************************************************//**
*
* Returns the capture value when the capture mode is enabled.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* The capture value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_Counter_GetCapture(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].CC);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_GetCaptureBuf
****************************************************************************//**
*
* Returns the buffered capture value when the capture mode is enabled.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* The buffered capture value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_Counter_GetCaptureBuf(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].CC_BUFF);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_SetCompare0
****************************************************************************//**
*
* Sets the compare value for Compare0 when the compare mode is enabled.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param compare0
* The Compare0 value.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_Counter_SetCompare0(TCPWM_Type *base, uint32_t cntNum, uint32_t compare0)
{
base->CNT[cntNum].CC = compare0;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_GetCompare0
****************************************************************************//**
*
* Returns compare value 0.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* Compare value 0.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_Counter_GetCompare0(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].CC);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_SetCompare1
****************************************************************************//**
*
* Sets the compare value for Compare1 when the compare mode is enabled.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param compare1
* The Compare1 value.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_Counter_SetCompare1(TCPWM_Type *base, uint32_t cntNum, uint32_t compare1)
{
base->CNT[cntNum].CC_BUFF = compare1;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_GetCompare1
****************************************************************************//**
*
* Returns compare value 1.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* Compare value 1.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_Counter_GetCompare1(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].CC_BUFF);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_EnableCompareSwap
****************************************************************************//**
*
* Enables the comparison swap when the comparison value is true.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param enable
* true = swap enabled, false = swap disabled
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_Counter_EnableCompareSwap(TCPWM_Type *base, uint32_t cntNum, bool enable)
{
if (enable)
{
base->CNT[cntNum].CTRL |= TCPWM_CNT_CTRL_AUTO_RELOAD_CC_Msk;
}
else
{
base->CNT[cntNum].CTRL &= ~TCPWM_CNT_CTRL_AUTO_RELOAD_CC_Msk;
}
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_SetCounter
****************************************************************************//**
*
* Sets the value of the counter.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param count
* The value to write into the counter.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_Counter_SetCounter(TCPWM_Type *base, uint32_t cntNum, uint32_t count)
{
base->CNT[cntNum].COUNTER = count;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_GetCounter
****************************************************************************//**
*
* Returns the value in the counter.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* The current counter value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_Counter_GetCounter(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].COUNTER);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_SetPeriod
****************************************************************************//**
*
* Sets the value of the period register.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param period
* The value to write into a period.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_Counter_SetPeriod(TCPWM_Type *base, uint32_t cntNum, uint32_t period)
{
base->CNT[cntNum].PERIOD = period;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_Counter_GetPeriod
****************************************************************************//**
*
* Returns the value in the period register.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* The current period value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_Counter_GetPeriod(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].PERIOD);
}
/** \} group_tcpwm_functions_counter */
/** \} group_tcpwm_counter */
#if defined(__cplusplus)
}
#endif
#endif /* CY_TCPWM_COUNTER_H */
/* [] END OF FILE */

View File

@ -0,0 +1,153 @@
/***************************************************************************//**
* \file cy_tcpwm_pwm.c
* \version 1.0
*
* \brief
* The source file of the tcpwm driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_tcpwm_pwm.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_Init
****************************************************************************//**
*
* Initializes the counter in the TCPWM block for the PWM operation.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param config
* The pointer to a configuration structure. See \ref cy_stc_tcpwm_pwm_config_t.
*
* \return error / status code. See \ref cy_en_tcpwm_status_t.
*
*******************************************************************************/
cy_en_tcpwm_status_t Cy_TCPWM_PWM_Init(TCPWM_Type *base, uint32_t cntNum, cy_stc_tcpwm_pwm_config_t const *config)
{
cy_en_tcpwm_status_t status = CY_TCPWM_BAD_PARAM;
if ((NULL != base) && (NULL != config))
{
base->CNT[cntNum].CTRL = ( (config->enableCompareSwap ? TCPWM_CNT_CTRL_AUTO_RELOAD_CC_Msk : 0uL) |
(config->enablePeriodSwap ? TCPWM_CNT_CTRL_AUTO_RELOAD_PERIOD_Msk : 0uL) |
_VAL2FLD(TCPWM_CNT_CTRL_ONE_SHOT, config->runMode) |
_VAL2FLD(TCPWM_CNT_CTRL_UP_DOWN_MODE, config->pwmAlignment) |
_VAL2FLD(TCPWM_CNT_CTRL_MODE, config->pwmMode) |
_VAL2FLD(TCPWM_CNT_CTRL_QUADRATURE_MODE,
(config->invertPWMOut | (config->invertPWMOutN << 1u))) |
(config->killMode << CY_TCPWM_PWM_CTRL_SYNC_KILL_OR_STOP_ON_KILL_POS) |
_VAL2FLD(TCPWM_CNT_CTRL_GENERIC, ((CY_TCPWM_PWM_MODE_DEADTIME == config->pwmMode) ?
config->deadTimeClocks : config->clockPrescaler)));
if (CY_TCPWM_PWM_MODE_PSEUDORANDOM == config->pwmMode)
{
base->CNT[cntNum].COUNTER = CY_TCPWM_CNT_UP_DOWN_INIT_VAL;
base->CNT[cntNum].TR_CTRL2 = CY_TCPWM_PWM_MODE_PR;
}
else
{
if (CY_TCPWM_PWM_LEFT_ALIGN == config->pwmAlignment)
{
base->CNT[cntNum].COUNTER = CY_TCPWM_CNT_UP_INIT_VAL;
base->CNT[cntNum].TR_CTRL2 = CY_TCPWM_PWM_MODE_LEFT;
}
else if (CY_TCPWM_PWM_RIGHT_ALIGN == config->pwmAlignment)
{
base->CNT[cntNum].COUNTER = config->period0;
base->CNT[cntNum].TR_CTRL2 = CY_TCPWM_PWM_MODE_RIGHT;
}
else
{
base->CNT[cntNum].COUNTER = CY_TCPWM_CNT_UP_DOWN_INIT_VAL;
base->CNT[cntNum].TR_CTRL2 = CY_TCPWM_PWM_MODE_CNTR_OR_ASYMM;
}
}
base->CNT[cntNum].CC = config->compare0;
base->CNT[cntNum].CC_BUFF = config->compare1;
base->CNT[cntNum].PERIOD = config->period0;
base->CNT[cntNum].PERIOD_BUFF = config->period1;
if (CY_TCPWM_INPUT_CREATOR != config->countInput)
{
base->CNT[cntNum].TR_CTRL0 = (_VAL2FLD(TCPWM_CNT_TR_CTRL0_CAPTURE_SEL, config->swapInput) |
_VAL2FLD(TCPWM_CNT_TR_CTRL0_RELOAD_SEL, config->reloadInput) |
_VAL2FLD(TCPWM_CNT_TR_CTRL0_START_SEL, config->startInput) |
_VAL2FLD(TCPWM_CNT_TR_CTRL0_STOP_SEL, config->killInput) |
_VAL2FLD(TCPWM_CNT_TR_CTRL0_COUNT_SEL, config->countInput));
}
base->CNT[cntNum].TR_CTRL1 = (_VAL2FLD(TCPWM_CNT_TR_CTRL1_CAPTURE_EDGE, config->swapInputMode) |
_VAL2FLD(TCPWM_CNT_TR_CTRL1_RELOAD_EDGE, config->reloadInputMode) |
_VAL2FLD(TCPWM_CNT_TR_CTRL1_START_EDGE, config->startInputMode) |
_VAL2FLD(TCPWM_CNT_TR_CTRL1_STOP_EDGE, config->killInputMode) |
_VAL2FLD(TCPWM_CNT_TR_CTRL1_COUNT_EDGE, config->countInputMode));
base->CNT[cntNum].INTR_MASK = config->interruptSources;
status = CY_TCPWM_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_DeInit
****************************************************************************//**
*
* De-initializes the counter in the TCPWM block, returns register values to
* default.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param config
* The pointer to a configuration structure. See \ref cy_stc_tcpwm_pwm_config_t.
*
*******************************************************************************/
void Cy_TCPWM_PWM_DeInit(TCPWM_Type *base, uint32_t cntNum, cy_stc_tcpwm_pwm_config_t const *config)
{
base->CNT[cntNum].CTRL = CY_TCPWM_CNT_CTRL_DEFAULT;
base->CNT[cntNum].COUNTER = CY_TCPWM_CNT_COUNTER_DEFAULT;
base->CNT[cntNum].CC = CY_TCPWM_CNT_CC_DEFAULT;
base->CNT[cntNum].CC_BUFF = CY_TCPWM_CNT_CC_BUFF_DEFAULT;
base->CNT[cntNum].PERIOD = CY_TCPWM_CNT_PERIOD_DEFAULT;
base->CNT[cntNum].PERIOD_BUFF = CY_TCPWM_CNT_PERIOD_BUFF_DEFAULT;
base->CNT[cntNum].TR_CTRL1 = CY_TCPWM_CNT_TR_CTRL1_DEFAULT;
base->CNT[cntNum].TR_CTRL2 = CY_TCPWM_CNT_TR_CTRL2_DEFAULT;
base->CNT[cntNum].INTR = CY_TCPWM_CNT_INTR_DEFAULT;
base->CNT[cntNum].INTR_SET = CY_TCPWM_CNT_INTR_SET_DEFAULT;
base->CNT[cntNum].INTR_MASK = CY_TCPWM_CNT_INTR_MASK_DEFAULT;
if (CY_TCPWM_INPUT_CREATOR != config->countInput)
{
base->CNT[cntNum].TR_CTRL0 = CY_TCPWM_CNT_TR_CTRL0_DEFAULT;
}
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */

View File

@ -0,0 +1,576 @@
/***************************************************************************//**
* \file cy_tcpwm_pwm.h
* \version 1.0
*
* \brief
* The header file of the TCPWM PWM driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_tcpwm_macro_pwm Macro
* \defgroup group_tcpwm_functions_pwm Functions
* \defgroup group_tcpwm_data_structures_pwm Data Structures
* \} */
#if !defined(CY_TCPWM_PWM_H)
#define CY_TCPWM_PWM_H
#include "cy_tcpwm.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_tcpwm_pwm
* Driver API for PWM.
* \{
*/
/**
* \addtogroup group_tcpwm_data_structures_pwm
* \{
*/
/** PWM configuration structure */
typedef struct cy_stc_tcpwm_pwm_config
{
uint32_t pwmMode; /**< Sets the PWM mode. See \ref group_tcpwm_pwm_modes */
/** Sets the clock prescaler inside the TCWPM block. See \ref group_tcpwm_pwm_clk_prescalers */
uint32_t clockPrescaler;
uint32_t pwmAlignment; /**< Sets the PWM alignment. See \ref group_tcpwm_pwm_alignment */
uint32_t deadTimeClocks; /**< The number of dead time-clocks if PWM with dead time is chosen */
uint32_t runMode; /**< Sets the PWM run mode. See \ref group_tcpwm_pwm_run_modes */
uint32_t period0; /**< Sets the period0 of the pwm */
uint32_t period1; /**< Sets the period1 of the pwm */
bool enablePeriodSwap; /**< Enables swapping of period 0 and period 1 on terminal count */
uint32_t compare0; /**< Sets the value for Compare0 */
uint32_t compare1; /**< Sets the value for Compare1 */
bool enableCompareSwap; /**< If enabled, the compare values are swapped on the terminal count */
/** Enables an interrupt on the terminal count, capture or compare. See \ref group_tcpwm_interrupt_sources */
uint32_t interruptSources;
uint32_t invertPWMOut; /**< Inverts the PWM output */
uint32_t invertPWMOutN; /**< Inverts the PWM_n output */
uint32_t killMode; /**< Configures the PWM kill modes. See \ref group_tcpwm_pwm_kill_modes */
uint32_t swapInputMode; /**< Configures how the swap input behaves. See \ref group_tcpwm_input_modes */
/** Selects which input the swap uses. Inputs are device-specific. See \ref group_tcpwm_input_selection */
uint32_t swapInput;
uint32_t reloadInputMode; /**< Configures how the reload input behaves. See \ref group_tcpwm_input_modes */
/** Selects which input the reload uses. The inputs are device-specific. See \ref group_tcpwm_input_selection */
uint32_t reloadInput;
uint32_t startInputMode; /**< Configures how the start input behaves. See \ref group_tcpwm_input_modes */
/** Selects which input the start uses. The inputs are device-specific. See \ref group_tcpwm_input_selection */
uint32_t startInput;
uint32_t killInputMode; /**< Configures how the kill input behaves. See \ref group_tcpwm_input_modes */
/** Selects which input the kill uses. The inputs are device-specific. See \ref group_tcpwm_input_selection */
uint32_t killInput;
uint32_t countInputMode; /**< Configures how the count input behaves. See \ref group_tcpwm_input_modes */
/** Selects which input the count uses. The inputs are device-specific. See \ref group_tcpwm_input_selection */
uint32_t countInput;
}cy_stc_tcpwm_pwm_config_t;
/** \} group_tcpwm_data_structures_pwm */
/**
* \addtogroup group_tcpwm_macro_pwm
* \{
* \defgroup group_tcpwm_pwm_run_modes PWM run modes
* \{
* Run modes for the pwm timer.
*/
#define CY_TCPWM_PWM_ONESHOT (1u) /**< Counter runs once and then stops */
#define CY_TCPWM_PWM_CONTINUOUS (0u) /**< Counter runs forever */
/** \} group_tcpwm_pwm_run_modes */
/** \defgroup group_tcpwm_pwm_modes PWM modes
* \{
* Sets the PWM modes.
*/
#define CY_TCPWM_PWM_MODE_PWM (4u) /**< Standard PWM Mode*/
#define CY_TCPWM_PWM_MODE_DEADTIME (5u) /**< PWM with deadtime mode*/
#define CY_TCPWM_PWM_MODE_PSEUDORANDOM (6u) /**< Pseudo Random PWM */
/** \} group_tcpwm_pwm_modes */
/** \defgroup group_tcpwm_pwm_alignment PWM Alignment
* Sets the alignment of the PWM.
* \{
*/
#define CY_TCPWM_PWM_LEFT_ALIGN (0u) /**< PWM is left aligned, meaning it starts high */
#define CY_TCPWM_PWM_RIGHT_ALIGN (1u) /**< PWM is right aligned, meaning it starts low */
/** PWM is centered aligned, terminal count only occurs on underflow */
#define CY_TCPWM_PWM_CENTER_ALIGN (2u)
/** PWM is asymmetrically aligned, terminal count occurs on overflow and underflow */
#define CY_TCPWM_PWM_ASYMMETRIC_ALIGN (3u)
/** \} group_tcpwm_pwm_alignment */
/** \defgroup group_tcpwm_pwm_kill_modes PWM kill modes
* Sets the kill mode for the PWM.
* \{
*/
#define CY_TCPWM_PWM_STOP_ON_KILL (2u) /**< PWM stops counting on kill */
#define CY_TCPWM_PWM_SYNCH_KILL (1u) /**< PWM output is killed after next TC*/
#define CY_TCPWM_PWM_ASYNC_KILL (0u) /**< PWM output is killed instantly */
/** \} group_tcpwm_pwm_kill_modes */
/** \defgroup group_tcpwm_pwm_clk_prescalers PWM CLK Prescaler values
* \{
* Clock prescaler values.
*/
#define CY_TCPWM_PWM_PRESCALER_DIVBY_1 (0u) /**< Divide by 1 */
#define CY_TCPWM_PWM_PRESCALER_DIVBY_2 (1u) /**< Divide by 2 */
#define CY_TCPWM_PWM_PRESCALER_DIVBY_4 (2u) /**< Divide by 4 */
#define CY_TCPWM_PWM_PRESCALER_DIVBY_8 (3u) /**< Divide by 8 */
#define CY_TCPWM_PWM_PRESCALER_DIVBY_16 (4u) /**< Divide by 16 */
#define CY_TCPWM_PWM_PRESCALER_DIVBY_32 (5u) /**< Divide by 32 */
#define CY_TCPWM_PWM_PRESCALER_DIVBY_64 (6u) /**< Divide by 64 */
#define CY_TCPWM_PWM_PRESCALER_DIVBY_128 (7u) /**< Divide by 128 */
/** \} group_tcpwm_pwm_clk_prescalers */
/** \defgroup group_tcpwm_pwm_output_invert PWM output invert
* \{
* Output invert modes.
*/
#define CY_TCPWM_PWM_INVERT_ENABLE (1u) /**< Invert the output mode */
#define CY_TCPWM_PWM_INVERT_DISABLE (0u) /**< Do not invert the output mode */
/** \} group_tcpwm_pwm_output_invert */
/** \defgroup group_tcpwm_pwm_status PWM Status
* \{
* The counter status.
*/
#define CY_TCPWM_PWM_STATUS_DOWN_COUNTING (0x1uL) /**< PWM is down counting */
#define CY_TCPWM_PWM_STATUS_UP_COUNTING (0x2uL) /**< PWM is up counting */
#define CY_TCPWM_PWM_STATUS_COUNTER_RUNNING (TCPWM_CNT_STATUS_RUNNING_Msk) /**< PWM counter is running */
/** \} group_tcpwm_pwm_status */
/***************************************
* Registers Constants
***************************************/
/** \cond INTERNAL */
#define CY_TCPWM_PWM_CTRL_SYNC_KILL_OR_STOP_ON_KILL_POS (2u)
#define CY_TCPWM_PWM_CTRL_SYNC_KILL_OR_STOP_ON_KILL_MASK (0x3uL << CY_TCPWM_PWM_CTRL_SYNC_KILL_OR_STOP_ON_KILL_POS)
/** \endcond */
/** \defgroup group_tcpwm_pwm_output_configuration PWM output signal configuration
* \{
* The configuration of PWM output signal for PWM alignment.
*/
#define CY_TCPWM_PWM_TR_CTRL2_SET (0uL) /**< Set define for PWM output signal configuration */
#define CY_TCPWM_PWM_TR_CTRL2_CLEAR (1uL) /**< Clear define for PWM output signal configuration */
#define CY_TCPWM_PWM_TR_CTRL2_INVERT (2uL) /**< Invert define for PWM output signal configuration */
#define CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE (3uL) /**< No change define for PWM output signal configuration */
/** The configuration of PWM output signal in Pseudo Random Mode */
#define CY_TCPWM_PWM_MODE_PR (_VAL2FLD(TCPWM_CNT_TR_CTRL2_CC_MATCH_MODE, CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE) | \
_VAL2FLD(TCPWM_CNT_TR_CTRL2_OVERFLOW_MODE, CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE) | \
_VAL2FLD(TCPWM_CNT_TR_CTRL2_UNDERFLOW_MODE, CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE))
/** The configuration of PWM output signal for Left alignment */
#define CY_TCPWM_PWM_MODE_LEFT (_VAL2FLD(TCPWM_CNT_TR_CTRL2_CC_MATCH_MODE, CY_TCPWM_PWM_TR_CTRL2_CLEAR) | \
_VAL2FLD(TCPWM_CNT_TR_CTRL2_OVERFLOW_MODE, CY_TCPWM_PWM_TR_CTRL2_SET) | \
_VAL2FLD(TCPWM_CNT_TR_CTRL2_UNDERFLOW_MODE, CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE))
/** The configuration of PWM output signal for Right alignment */
#define CY_TCPWM_PWM_MODE_RIGHT (_VAL2FLD(TCPWM_CNT_TR_CTRL2_CC_MATCH_MODE, CY_TCPWM_PWM_TR_CTRL2_SET) | \
_VAL2FLD(TCPWM_CNT_TR_CTRL2_OVERFLOW_MODE, CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE) | \
_VAL2FLD(TCPWM_CNT_TR_CTRL2_UNDERFLOW_MODE, CY_TCPWM_PWM_TR_CTRL2_CLEAR))
/** The configuration of PWM output signal for Center and Asymmetric alignment */
#define CY_TCPWM_PWM_MODE_CNTR_OR_ASYMM (_VAL2FLD(TCPWM_CNT_TR_CTRL2_CC_MATCH_MODE, CY_TCPWM_PWM_TR_CTRL2_INVERT) | \
_VAL2FLD(TCPWM_CNT_TR_CTRL2_OVERFLOW_MODE, CY_TCPWM_PWM_TR_CTRL2_SET) | \
_VAL2FLD(TCPWM_CNT_TR_CTRL2_UNDERFLOW_MODE, CY_TCPWM_PWM_TR_CTRL2_CLEAR))
/** \} group_tcpwm_pwm_output_configuration */
/** \} group_tcpwm_macro_pwm */
/*******************************************************************************
* Function Prototypes
*******************************************************************************/
/**
* \addtogroup group_tcpwm_functions_pwm
* \{
*/
cy_en_tcpwm_status_t Cy_TCPWM_PWM_Init(TCPWM_Type *base, uint32_t cntNum, cy_stc_tcpwm_pwm_config_t const *config);
void Cy_TCPWM_PWM_DeInit(TCPWM_Type *base, uint32_t cntNum, cy_stc_tcpwm_pwm_config_t const *config);
__STATIC_INLINE void Cy_TCPWM_PWM_Enable(TCPWM_Type *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_PWM_Disable(TCPWM_Type *base, uint32_t cntNum);
__STATIC_INLINE uint32_t Cy_TCPWM_PWM_GetStatus(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_PWM_SetCompare0(TCPWM_Type *base, uint32_t cntNum, uint32_t compare0);
__STATIC_INLINE uint32_t Cy_TCPWM_PWM_GetCompare0(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_PWM_SetCompare1(TCPWM_Type *base, uint32_t cntNum, uint32_t compare1);
__STATIC_INLINE uint32_t Cy_TCPWM_PWM_GetCompare1(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_PWM_EnableCompareSwap(TCPWM_Type *base, uint32_t cntNum, bool enable);
__STATIC_INLINE void Cy_TCPWM_PWM_SetCounter(TCPWM_Type *base, uint32_t cntNum, uint32_t count);
__STATIC_INLINE uint32_t Cy_TCPWM_PWM_GetCounter(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_PWM_SetPeriod0(TCPWM_Type *base, uint32_t cntNum, uint32_t period0);
__STATIC_INLINE uint32_t Cy_TCPWM_PWM_GetPeriod0(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_PWM_SetPeriod1(TCPWM_Type *base, uint32_t cntNum, uint32_t period1);
__STATIC_INLINE uint32_t Cy_TCPWM_PWM_GetPeriod1(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_PWM_EnablePeriodSwap(TCPWM_Type *base, uint32_t cntNum, bool enable);
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_Enable
****************************************************************************//**
*
* Enables the counter in the TCPWM block for the PWM operation.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_PWM_Enable(TCPWM_Type *base, uint32_t cntNum)
{
base->CTRL_SET = (1uL << cntNum);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_Disable
****************************************************************************//**
*
* Disables the counter in the TCPWM block.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_PWM_Disable(TCPWM_Type *base, uint32_t cntNum)
{
base->CTRL_CLR = (1uL << cntNum);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_GetStatus
****************************************************************************//**
*
* Returns the status of the PWM.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* The status. See \ref group_tcpwm_pwm_status
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_PWM_GetStatus(TCPWM_Type const *base, uint32_t cntNum)
{
uint32_t status = base->CNT[cntNum].STATUS;
/* Generates proper up counting status, does not generated by HW */
status &= ~CY_TCPWM_PWM_STATUS_UP_COUNTING;
status |= ((~status & CY_TCPWM_PWM_STATUS_DOWN_COUNTING & (status >> TCPWM_CNT_STATUS_RUNNING_Pos)) <<
CY_TCPWM_CNT_STATUS_UP_POS);
return(status);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_SetCompare0
****************************************************************************//**
*
* Sets the compare value for Compare0 when the compare mode enabled.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param compare0
* The Compare0 value.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_PWM_SetCompare0(TCPWM_Type *base, uint32_t cntNum, uint32_t compare0)
{
base->CNT[cntNum].CC = compare0;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_GetCompare0
****************************************************************************//**
*
* Returns compare value 0.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* Compare value 0.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_PWM_GetCompare0(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].CC);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_SetCompare1
****************************************************************************//**
*
* Sets the compare value for Compare1 when the compare mode is enabled.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param compare1
* The Compare1 value.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_PWM_SetCompare1(TCPWM_Type *base, uint32_t cntNum, uint32_t compare1)
{
base->CNT[cntNum].CC_BUFF = compare1;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_GetCompare1
****************************************************************************//**
*
* Returns compare value 1.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* Compare value 1.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_PWM_GetCompare1(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].CC_BUFF);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_EnableCompareSwap
****************************************************************************//**
*
* Enables the comparison swap on OV and/or UN, depending on the PWM alignment.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param enable
* true = swap enabled; false = swap disabled
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_PWM_EnableCompareSwap(TCPWM_Type *base, uint32_t cntNum, bool enable)
{
if (enable)
{
base->CNT[cntNum].CTRL |= TCPWM_CNT_CTRL_AUTO_RELOAD_CC_Msk;
}
else
{
base->CNT[cntNum].CTRL &= ~TCPWM_CNT_CTRL_AUTO_RELOAD_CC_Msk;
}
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_SetCounter
****************************************************************************//**
*
* Sets the value of the counter.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param count
* The value to write into the counter.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_PWM_SetCounter(TCPWM_Type *base, uint32_t cntNum, uint32_t count)
{
base->CNT[cntNum].COUNTER = count;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_GetCounter
****************************************************************************//**
*
* Returns the value in the counter.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* The current counter value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_PWM_GetCounter(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].COUNTER);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_SetPeriod0
****************************************************************************//**
*
* Sets the value of the period register.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param period0
* The value to write into a period.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_PWM_SetPeriod0(TCPWM_Type *base, uint32_t cntNum, uint32_t period0)
{
base->CNT[cntNum].PERIOD = period0;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_GetPeriod0
****************************************************************************//**
*
* Returns the value in the period register.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* The current period value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_PWM_GetPeriod0(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].PERIOD);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_SetPeriod1
****************************************************************************//**
*
* Sets the value of the period register.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param period1
* The value to write into a period1.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_PWM_SetPeriod1(TCPWM_Type *base, uint32_t cntNum, uint32_t period1)
{
base->CNT[cntNum].PERIOD_BUFF = period1;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_GetPeriod1
****************************************************************************//**
*
* Returns the value in the period register.
*
* \param base
* The pointer to a COUNTER PWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* The current period value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_PWM_GetPeriod1(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].PERIOD_BUFF);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_PWM_EnablePeriodSwap
****************************************************************************//**
*
* Enables a period swap on OV and/or UN, depending on the PWM alignment
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param enable
* true = swap enabled; false = swap disabled
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_PWM_EnablePeriodSwap(TCPWM_Type *base, uint32_t cntNum, bool enable)
{
if (enable)
{
base->CNT[cntNum].CTRL |= TCPWM_CNT_CTRL_AUTO_RELOAD_PERIOD_Msk;
}
else
{
base->CNT[cntNum].CTRL &= ~TCPWM_CNT_CTRL_AUTO_RELOAD_PERIOD_Msk;
}
}
/** \} group_tcpwm_functions_pwm */
/** \} group_tcpwm_pwm */
#if defined(__cplusplus)
}
#endif
#endif /* CY_TCPWM_PWM_H */
/* [] END OF FILE */

View File

@ -0,0 +1,116 @@
/***************************************************************************//**
* \file cy_tcpwm_quaddec.c
* \version 1.0
*
* \brief
* The source file of the tcpwm driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_tcpwm_quaddec.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_TCPWM_QuadDec_Init
****************************************************************************//**
*
* Initializes the counter in the TCPWM block for the QuadDec operation.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param config
* The pointer to a configuration structure. See \ref cy_stc_tcpwm_quaddec_config_t.
*
* \return error / status code. See \ref cy_en_tcpwm_status_t.
*
*******************************************************************************/
cy_en_tcpwm_status_t Cy_TCPWM_QuadDec_Init(TCPWM_Type *base, uint32_t cntNum, cy_stc_tcpwm_quaddec_config_t const *config)
{
cy_en_tcpwm_status_t status = CY_TCPWM_BAD_PARAM;
if ((NULL != base) && (NULL != config))
{
base->CNT[cntNum].CTRL = ( _VAL2FLD(TCPWM_CNT_CTRL_QUADRATURE_MODE, config->resolution) |
_VAL2FLD(TCPWM_CNT_CTRL_MODE, CY_TCPWM_QUADDEC_CTRL_QUADDEC_MODE));
if (CY_TCPWM_INPUT_CREATOR != config->phiAInput)
{
base->CNT[cntNum].TR_CTRL0 = (_VAL2FLD(TCPWM_CNT_TR_CTRL0_COUNT_SEL, config->phiAInput) |
_VAL2FLD(TCPWM_CNT_TR_CTRL0_START_SEL, config->phiBInput) |
_VAL2FLD(TCPWM_CNT_TR_CTRL0_RELOAD_SEL, config->indexInput) |
_VAL2FLD(TCPWM_CNT_TR_CTRL0_STOP_SEL, config->stopInput));
}
base->CNT[cntNum].TR_CTRL1 = (_VAL2FLD(TCPWM_CNT_TR_CTRL1_CAPTURE_EDGE, CY_TCPWM_INPUT_LEVEL) |
_VAL2FLD(TCPWM_CNT_TR_CTRL1_COUNT_EDGE, CY_TCPWM_INPUT_LEVEL) |
_VAL2FLD(TCPWM_CNT_TR_CTRL1_START_EDGE, CY_TCPWM_INPUT_LEVEL) |
_VAL2FLD(TCPWM_CNT_TR_CTRL1_RELOAD_EDGE, config->indexInputMode) |
_VAL2FLD(TCPWM_CNT_TR_CTRL1_STOP_EDGE, config->stopInputMode));
base->CNT[cntNum].INTR_MASK = config->interruptSources;
status = CY_TCPWM_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_QuadDec_DeInit
****************************************************************************//**
*
* De-initializes the counter in the TCPWM block, returns register values to
* default.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param config
* The pointer to a configuration structure. See \ref cy_stc_tcpwm_quaddec_config_t.
*
*******************************************************************************/
void Cy_TCPWM_QuadDec_DeInit(TCPWM_Type *base, uint32_t cntNum, cy_stc_tcpwm_quaddec_config_t const *config)
{
base->CNT[cntNum].CTRL = CY_TCPWM_CNT_CTRL_DEFAULT;
base->CNT[cntNum].COUNTER = CY_TCPWM_CNT_COUNTER_DEFAULT;
base->CNT[cntNum].CC = CY_TCPWM_CNT_CC_DEFAULT;
base->CNT[cntNum].CC_BUFF = CY_TCPWM_CNT_CC_BUFF_DEFAULT;
base->CNT[cntNum].PERIOD = CY_TCPWM_CNT_PERIOD_DEFAULT;
base->CNT[cntNum].PERIOD_BUFF = CY_TCPWM_CNT_PERIOD_BUFF_DEFAULT;
base->CNT[cntNum].TR_CTRL1 = CY_TCPWM_CNT_TR_CTRL1_DEFAULT;
base->CNT[cntNum].TR_CTRL2 = CY_TCPWM_CNT_TR_CTRL2_DEFAULT;
base->CNT[cntNum].INTR = CY_TCPWM_CNT_INTR_DEFAULT;
base->CNT[cntNum].INTR_SET = CY_TCPWM_CNT_INTR_SET_DEFAULT;
base->CNT[cntNum].INTR_MASK = CY_TCPWM_CNT_INTR_MASK_DEFAULT;
if (CY_TCPWM_INPUT_CREATOR != config->phiAInput)
{
base->CNT[cntNum].TR_CTRL0 = CY_TCPWM_CNT_TR_CTRL0_DEFAULT;
}
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */

View File

@ -0,0 +1,281 @@
/***************************************************************************//**
* \file cy_tcpwm_quaddec.h
* \version 1.0
*
* \brief
* The header file of the TCPWM Quadrature Decoder driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_tcpwm_macro_quaddec Macro
* \defgroup group_tcpwm_functions_quaddec Functions
* \defgroup group_tcpwm_data_structures_quaddec Data Structures
* \} */
#if !defined(CY_TCPWM_QUADDEC_H)
#define CY_TCPWM_QUADDEC_H
#include "cy_tcpwm.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_tcpwm_quaddec
* Driver API for Quadrature Decoder.
* \{
*/
/**
* \addtogroup group_tcpwm_data_structures_quaddec
* \{
*/
/** Quadrature Decoder configuration structure */
typedef struct cy_stc_tcpwm_quaddec_config
{
/** Selects the quadrature encoding mode. See \ref group_tcpwm_quaddec_resolution */
uint32_t resolution;
/** Enables an interrupt on the terminal count, capture or compare. See \ref group_tcpwm_interrupt_sources */
uint32_t interruptSources;
/** Configures how the index input behaves. See \ref group_tcpwm_input_modes */
uint32_t indexInputMode;
/** Selects which input the index uses. The inputs are device-specific. See \ref group_tcpwm_input_selection */
uint32_t indexInput;
/** Configures how the stop input behaves. See \ref group_tcpwm_input_modes */
uint32_t stopInputMode;
/** Selects which input the stop uses. The inputs are device-specific. See \ref group_tcpwm_input_selection */
uint32_t stopInput;
/** Selects which input the phiA uses. The inputs are device specific. See \ref group_tcpwm_input_selection */
uint32_t phiAInput;
/** Selects which input the phiB uses. The inputs are device specific. See \ref group_tcpwm_input_selection */
uint32_t phiBInput;
}cy_stc_tcpwm_quaddec_config_t;
/** \} group_tcpwm_data_structures_quaddec */
/**
* \addtogroup group_tcpwm_macro_quaddec
* \{
* \defgroup group_tcpwm_quaddec_resolution QuadDec Resolution
* \{
* The quadrature decoder resolution.
*/
#define CY_TCPWM_QUADDEC_X1 (0u) /**< X1 mode */
#define CY_TCPWM_QUADDEC_X2 (1u) /**< X2 mode */
#define CY_TCPWM_QUADDEC_X4 (2u) /**< X4 mode */
/** \} group_tcpwm_quaddec_resolution */
/** \defgroup group_tcpwm_quaddec_status QuadDec Status
* \{
* The counter status.
*/
#define CY_TCPWM_QUADDEC_STATUS_DOWN_COUNTING (0x1uL) /**< QuadDec is down counting */
#define CY_TCPWM_QUADDEC_STATUS_UP_COUNTING (0x2uL) /**< QuadDec is up counting */
/** QuadDec the counter is running */
#define CY_TCPWM_QUADDEC_STATUS_COUNTER_RUNNING (TCPWM_CNT_STATUS_RUNNING_Msk)
/** \} group_tcpwm_quaddec_status */
/***************************************
* Registers Constants
***************************************/
/** \cond INTERNAL */
#define CY_TCPWM_QUADDEC_CTRL_QUADDEC_MODE (0x3uL) /**< Quadrature encoding mode for CTRL register */
/** \endcond */
/** \} group_tcpwm_macro_quaddec */
/*******************************************************************************
* Function Prototypes
*******************************************************************************/
/**
* \addtogroup group_tcpwm_functions_quaddec
* \{
*/
cy_en_tcpwm_status_t Cy_TCPWM_QuadDec_Init(TCPWM_Type *base, uint32_t cntNum, cy_stc_tcpwm_quaddec_config_t const *config);
void Cy_TCPWM_QuadDec_DeInit(TCPWM_Type *base, uint32_t cntNum, cy_stc_tcpwm_quaddec_config_t const *config);
__STATIC_INLINE void Cy_TCPWM_QuadDec_Enable(TCPWM_Type *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_QuadDec_Disable(TCPWM_Type *base, uint32_t cntNum);
__STATIC_INLINE uint32_t Cy_TCPWM_QuadDec_GetStatus(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE uint32_t Cy_TCPWM_QuadDec_GetCapture(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE uint32_t Cy_TCPWM_QuadDec_GetCaptureBuf(TCPWM_Type const *base, uint32_t cntNum);
__STATIC_INLINE void Cy_TCPWM_QuadDec_SetCounter(TCPWM_Type *base, uint32_t cntNum, uint32_t count);
__STATIC_INLINE uint32_t Cy_TCPWM_QuadDec_GetCounter(TCPWM_Type const *base, uint32_t cntNum);
/*******************************************************************************
* Function Name: Cy_TCPWM_QuadDec_Enable
****************************************************************************//**
*
* Enables the counter in the TCPWM block for the QuadDec operation.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_QuadDec_Enable(TCPWM_Type *base, uint32_t cntNum)
{
base->CTRL_SET = (1uL << cntNum);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_QuadDec_Disable
****************************************************************************//**
*
* Disables the counter in the TCPWM block.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_QuadDec_Disable(TCPWM_Type *base, uint32_t cntNum)
{
base->CTRL_CLR = (1uL << cntNum);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_QuadDec_GetStatus
****************************************************************************//**
*
* Returns the status of the QuadDec.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* The status. See \ref group_tcpwm_quaddec_status
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_QuadDec_GetStatus(TCPWM_Type const *base, uint32_t cntNum)
{
uint32_t status = base->CNT[cntNum].STATUS;
/* Generates proper up counting status, does not generated by HW */
status &= ~CY_TCPWM_QUADDEC_STATUS_UP_COUNTING;
status |= ((~status & CY_TCPWM_QUADDEC_STATUS_DOWN_COUNTING & (status >> TCPWM_CNT_STATUS_RUNNING_Pos)) <<
CY_TCPWM_CNT_STATUS_UP_POS);
return(status);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_QuadDec_GetCapture
****************************************************************************//**
*
* Returns the capture value.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* The capture value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_QuadDec_GetCapture(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].CC);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_QuadDec_GetCaptureBuf
****************************************************************************//**
*
* Returns the buffered capture value.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* The buffered capture value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_QuadDec_GetCaptureBuf(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].CC_BUFF);
}
/*******************************************************************************
* Function Name: Cy_TCPWM_QuadDec_SetCounter
****************************************************************************//**
*
* Sets the value of the counter.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \param count
* The value to write into the counter.
*
*******************************************************************************/
__STATIC_INLINE void Cy_TCPWM_QuadDec_SetCounter(TCPWM_Type *base, uint32_t cntNum, uint32_t count)
{
base->CNT[cntNum].COUNTER = count;
}
/*******************************************************************************
* Function Name: Cy_TCPWM_QuadDec_GetCounter
****************************************************************************//**
*
* Returns the value in the counter.
*
* \param base
* The pointer to a TCPWM instance.
*
* \param cntNum
* The Counter instance number in the selected TCPWM.
*
* \return
* The current counter value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_TCPWM_QuadDec_GetCounter(TCPWM_Type const *base, uint32_t cntNum)
{
return(base->CNT[cntNum].COUNTER);
}
/** \} group_tcpwm_functions_quaddec */
/** \} group_tcpwm_quaddec */
#if defined(__cplusplus)
}
#endif
#endif /* CY_TCPWM_QUADDEC_H */
/* [] END OF FILE */

View File

@ -0,0 +1,112 @@
/***************************************************************************//**
* \file
* \version 1.0
*
* \brief Trigger mux APIs.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "cy_trigmux.h"
/*******************************************************************************
* Function Name: Cy_TrigMux_Connect
****************************************************************************//**
*
* This function connects an input trigger source and output trigger.
*
* \param inTrig
* An input selection for the trigger mux.
* - Bits 11:8 represent the trigger group selection.
* - Bits 6:0 select the input trigger number in the trigger group.
*
* \param outTrig
* The output of the trigger mux. This refers to the consumer of the trigger mux.
* - Bits 11:8 represent the trigger group selection.
* - Bits 6:0 select the output trigger number in the trigger group.
*
* \param invert
* - CY_TR_MUX_TR_INV_ENABLE: The output trigger is inverted.
* - CY_MUX_TR_INV_DISABLE: The output trigger is not inverted.
*
* \param trigType
* - TRIGGER_TYPE_EDGE: The trigger is synchronized to the consumer blocks clock
* and a two-cycle pulse is generated on this clock.
* - TRIGGER_TYPE_LEVEL: The trigger is a simple level output.
*
* \return
* A status
* - 0: Successful connection made.
* - 1: An invalid input selection corresponding to the output.
* Generally when the trigger groups do not match.
*
*******************************************************************************/
cy_en_trigmux_status_t Cy_TrigMux_Connect(uint32_t inTrig, uint32_t outTrig, uint32_t invert, en_trig_type_t trigType)
{
volatile uint32_t* trOutCtlAddr;
cy_en_trigmux_status_t retVal = CY_TRIGMUX_BAD_PARAM;
if ((inTrig & CY_TR_GROUP_MASK) == (outTrig & CY_TR_GROUP_MASK))
{
trOutCtlAddr = &(PERI->TR_GR[(outTrig & CY_TR_GROUP_MASK) >> CY_TR_GROUP_SHIFT].TR_OUT_CTL[outTrig & CY_TR_MASK]);
*trOutCtlAddr = _VAL2FLD(PERI_TR_GR_TR_OUT_CTL_TR_SEL, inTrig) |
_VAL2FLD(PERI_TR_GR_TR_OUT_CTL_TR_INV, invert) |
_VAL2FLD(PERI_TR_GR_TR_OUT_CTL_TR_EDGE, trigType);
retVal = CY_TRIGMUX_SUCCESS;
}
return retVal;
}
/*******************************************************************************
* Function Name: Cy_TrigMux_SwTrigger
****************************************************************************//**
*
* This function generates a software trigger on an input trigger line.
* All output triggers connected to this input trigger will be triggered.
* The function also verifies that there is no activated trigger before
* generating another activation.
*
* \param trigLine
* The input of the trigger mux.
* - Bit 12 represents if the signal is an input/output.
* - Bits 11:8 represent the trigger group selection.
* - Bits 6:0 select the output trigger number in the trigger group.
*
* \param cycles
* The number of cycles during which the trigger remains activated.
* - The valid range: 1-254 cycles.
*
* \return
* A status
* - 0: If there was not an already activated trigger.
* - 1: If there was an already activated trigger.
*
*******************************************************************************/
cy_en_trigmux_status_t Cy_TrigMux_SwTrigger(uint32_t trigLine, uint32_t cycles)
{
cy_en_trigmux_status_t retVal = CY_TRIGMUX_INVALID_STATE;
if (PERI_TR_CMD_ACTIVATE_Msk != (PERI->TR_CMD & PERI_TR_CMD_ACTIVATE_Msk))
{
PERI->TR_CMD = _VAL2FLD(PERI_TR_CMD_TR_SEL, (trigLine & CY_TR_MASK)) |
_VAL2FLD(PERI_TR_CMD_GROUP_SEL, ((trigLine & CY_TR_GROUP_MASK) >> CY_TR_GROUP_SHIFT)) |
_VAL2FLD(PERI_TR_CMD_COUNT, cycles) |
_VAL2FLD(PERI_TR_CMD_OUT_SEL, (trigLine & CY_TR_OUT_CTL_MASK) >> CY_TR_OUT_CTL_SHIFT) |
_VAL2FLD(PERI_TR_CMD_ACTIVATE, CY_TR_ACTIVATE_ENABLE);
retVal = CY_TRIGMUX_SUCCESS;
}
return retVal;
}
/* [] END OF FILE */

View File

@ -0,0 +1,199 @@
/*******************************************************************************
* \file cy_trigmux.h
* \version 1.0
*
* This file provides constants and parameter values for the Trigger multiplexer driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/**
* \defgroup group_trigmux Trigger multiplexer (TrigMux)
* \{
* The trigger multiplexer provides access to the multiplexer that selects a set
* of trigger output signals from different peripheral blocks to route them to the
* specific trigger input of another peripheral block.
*
* The TrigMux driver is based on the trigger multiplexer's hardware block.
* The Trigger multiplexer block consists of multiple trigger multiplexers.
* These trigger multiplexers are grouped in trigger groups. All the trigger
* multiplexers in the trigger group share similar input options. The trigger
* multiplexer groups are either reduction multiplexers or distribution multiplexers.
* The reduction multiplexer groups have input options that are the trigger outputs
* coming from the different peripheral blocks and the reduction multiplexer groups
* route them to intermediate signals. The distribution multiplexer groups have input
* options from these intermediate signals and route them back to multiple peripheral
* blocks as their trigger inputs.
*
* The trigger architecture of the PSoC device is explained in the technical reference
* manual (TRM). Refer to the TRM to better understand the trigger multiplexer routing
* architecture available.
*
* \section group_trigmux_section_Configuration_Considerations Configuration Considerations
*
*
* To route a trigger signal from one peripheral in the PSoC
* to another, the user must configure a reduction multiplexer and a distribution
* multiplexer. The Cy_TrigMux_connect() is used to configure a trigger multiplexer connection.
* The user will need two calls of this API, one for the reduction multiplexer and another
* for the distribution multiplexer, to achieve the trigger connection from a source
* peripheral to a destination peripheral. The Cy_TrigMux_connect() function has two main
* parameters, inTrig and outTrig that refer to the input and output trigger signals
* connected using the multiplexer.
*
* These parameters are represented in the following format:
* \image html trigmux/docs/trigmux_parameter.png
* In addition, the Cy_TrigMux_connect() function also has an invert and trigger type parameter.
* Refer to the API reference for a detailed description of this parameter.
* All the constants associated with the different trigger signals in the system
* (input and output) are defined as constants in the device configuration header file.
* The constants for TrigMux in the device configuration header file are divided into four
* types based on the signal being input/output and being part of a reduction/distribution
* trigger multiplexer.
*
* The four types of the input/output parameters are:
* 1) The parameters for the reduction multiplexer's inputs (input signals of TrigMux);
* 2) The parameters for the reduction multiplexer's outputs (intermediate signals);
* 3) The parameters for the distribution multiplexer's inputs (intermediate signals);
* 4) The parameters for the distribution multiplexer's outputs (output signals of TrigMux).
* Refer to the TRM for a more detailed description of this architecture and different options.
*
* The steps to connect one peripheral block to the other:
*
* Step 1. Find the trigger group number in the Trigger Group Inputs section of the device
* configuration header file that corresponds to the output of the first peripheral block.
* For example, TRIG10_IN_CPUSS_DW0_TR_OUT4 input of the reduction multiplexers belongs
* to Trigger Group 10.
*
* Step 2. Find the trigger group number in the Trigger Group Outputs section of the device
* configuration header file that corresponds to the input of the second peripheral block.
* For example, TRIG3_OUT_TCPWM1_TR_IN0 output of the distribution multiplexer belongs to
* Trigger Group 3.
*
* Step 3. Find the same trigger group number in the Trigger Group Inputs section of the
* device configuration header file that corresponds to the trigger group number found in
* Step 1. Select the reduction multiplexer output that can be connected to the trigger group
* found in Step 2. For example, TRIG3_IN_TR_GROUP10_OUTPUT5 means that Reduction Multiplexer
* Output 5 of Trigger Group 10 can be connected to Trigger Group 3.
*
* Step 4. Find the same trigger group number in the Trigger Group Outputs section of the
* device configuration header file that corresponds to the trigger group number found in Step 2.
* Select the distribution multiplexer input that can be connected to the trigger group found
* in Step 1. For example, TRIG10_OUT_TR_GROUP3_INPUT1 means that the Distribution Multiplexer
* Input 1 of Trigger Group 3 can be connected to the output of the reduction multiplexer
* in Trigger Group 10 found in Step 3.
*
* Step 5. Call Cy_TrigMux_Connect() API twice: the first call - with the constants for the
* inTrig and outTrig parameters found in Steps 1 and Step 4, the second call - with the
* constants for the inTrig and outTrig parameters found in Steps 2 and Step 3.
* For example,
* Cy_TrigMux_Connect(TRIG10_IN_CPUSS_DW0_TR_OUT4, TRIG10_OUT_TR_GROUP3_INPUT1,
* TR_MUX_TR_INV_DISABLE, TRIGGER_TYPE_LEVEL);
* Cy_TrigMux_Connect(TRIG3_IN_TR_GROUP10_OUTPUT5, TRIG3_OUT_TCPWM1_TR_IN0,
* TR_MUX_TR_INV_DISABLE, TRIGGER_TYPE_LEVEL);
*
* \section group_trigmux_more_information More Information
* For more information on the TrigMux peripheral, refer to the technical reference manual (TRM).
*
* \section group_trigmux_MISRA MISRA-C Compliance
* The TrigMux driver does not have any specific deviations.
*
* \section group_trigmux_Changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_trigmux_macro Macro
* \defgroup group_trigmux_functions Functions
* \defgroup group_trigmux_enums Enumerated Types
*/
#if !defined(CY_TRIGMUX_H)
#define CY_TRIGMUX_H
#include "cy_device_headers.h"
#include "syslib/cy_syslib.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_trigmux_macro
* \{
*/
/** The driver major version */
#define CY_TRIGMUX_DRV_VERSION_MAJOR 1
/** The driver minor version */
#define CY_TRIGMUX_DRV_VERSION_MINOR 0
/**< TRIGMUX PDL ID */
#define CY_TRIGMUX_ID CY_PDL_DRV_ID(0x33u) /**< The trigger multiplexer driver identifier */
#define CY_TR_MUX_TR_INV_ENABLE (0x01u) /**< Enable trigger invert */
#define CY_TR_MUX_TR_INV_DISABLE (0x00u) /**< Disable trigger invert */
/** \cond */
#define CY_TR_ACTIVATE_ENABLE (0x01u)
#define CY_TR_GROUP_MASK (0x0F00u)
#define CY_TR_MASK (0x007Fu)
#define CY_TR_GROUP_SHIFT (0x08u)
#define CY_TR_OUT_CTL_MASK (0x1000u)
#define CY_TR_OUT_CTL_SHIFT (12u)
/** \endcond */
/** \} group_trigmux_macro */
/**
* \addtogroup group_trigmux_enums
* \{
*/
/******************************************************************************
* Enumerations
*****************************************************************************/
/** The TRIGMUX error codes. */
typedef enum
{
CY_TRIGMUX_SUCCESS = 0x00u, /**< Successful */
CY_TRIGMUX_BAD_PARAM = CY_TRIGMUX_ID | CY_PDL_STATUS_ERROR | 0x01u, /**< One or more invalid parameters */
CY_TRIGMUX_INVALID_STATE = CY_TRIGMUX_ID | CY_PDL_STATUS_ERROR | 0x02u /**< Operation not setup or is in an improper state */
} cy_en_trigmux_status_t;
/** \} group_trigmux_enums */
/**
* \addtogroup group_trigmux_functions
* \{
*/
cy_en_trigmux_status_t Cy_TrigMux_Connect(uint32_t inTrig, uint32_t outTrig, uint32_t invert, en_trig_type_t trigType);
cy_en_trigmux_status_t Cy_TrigMux_SwTrigger(uint32_t trigLine, uint32_t cycles);
/** \} group_trigmux_functions */
#if defined(__cplusplus)
}
#endif
#endif /* CY_TRIGMUX_H */
/** \} group_lpcomp */
/* [] END OF FILE */

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