Merge pull request #8491 from lrusinowicz/new-target-future_sequana

New target future sequana
pull/8640/head
Cruz Monrreal 2018-11-03 07:05:58 -05:00 committed by GitHub
commit 0e6eac5faa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
190 changed files with 101882 additions and 11 deletions

View File

@ -0,0 +1,117 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2017 ARM Limited
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "hci_api.h"
#include "bstream.h"
#include "driver/CordioHCIDriver.h"
#include "drivers/IPCPipeTransportDriver.h"
#include "psoc6_utils.h"
using namespace ble::vendor::cordio;
using namespace ble::vendor::cypress;
const uint16_t HCI_VEND_SET_BD_ADDR = 0xfda0;
const uint8_t HCI_VEND_SET_BD_ADDR_LEN = 7; /* MAC address + address type */
class Psoc6HCIDriver : public CordioHCIDriver
{
public:
Psoc6HCIDriver(IPCPipeTransportDriver& transport_driver) :
CordioHCIDriver(transport_driver)
{
}
private:
struct BdAddress {
uint8_t mac_address[6];
uint8_t addr_type;
BdAddress() : addr_type(0) {}
};
/**
* Initialize the chip.
* The transport is up at that time.
*/
virtual void do_initialize();
/**
* Terminate the driver
*/
virtual void do_terminate() {}
virtual void handle_reset_sequence(uint8_t *pMsg);
private:
BdAddress bd_address;
};
void Psoc6HCIDriver::do_initialize()
{
cy_get_bd_mac_address(bd_address.mac_address);
}
void Psoc6HCIDriver::handle_reset_sequence(uint8_t *pMsg) {
uint16_t opcode;
/* if event is a command complete event */
if (*pMsg == HCI_CMD_CMPL_EVT) {
/* parse parameters */
uint8_t *pMsg2 = pMsg + HCI_EVT_HDR_LEN;
pMsg2++; /* skip num packets */
BSTREAM_TO_UINT16(opcode, pMsg2);
pMsg2 -= 2;
/* decode opcode */
switch (opcode) {
case HCI_OPCODE_RESET:
/* send next command in sequence */
HciVendorSpecificCmd(HCI_VEND_SET_BD_ADDR,
HCI_VEND_SET_BD_ADDR_LEN,
reinterpret_cast<uint8_t*>(&bd_address));
break;
case HCI_VEND_SET_BD_ADDR:
/* pretend we have just completed reset */
UINT16_TO_BSTREAM(pMsg2, HCI_OPCODE_RESET);
CordioHCIDriver::handle_reset_sequence(pMsg);
break;
default:
/* pass to parent */
CordioHCIDriver::handle_reset_sequence(pMsg);
}
}
}
CordioHCIDriver& ble_cordio_get_hci_driver() {
static IPCPipeTransportDriver transport_driver;
static Psoc6HCIDriver hci_driver(
transport_driver /* other hci driver parameters */
);
return hci_driver;
}

View File

@ -0,0 +1,75 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2017 ARM Limited
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "IPCPipeTransportDriver.h"
#include "ipcpipe_transport.h"
#include "mbed_assert.h"
#include "mbed_error.h"
namespace ble {
namespace vendor {
namespace cypress {
void dump_buffer(uint8_t *buffer, uint32_t len)
{
while (len > 0) {
printf(" %02x", *buffer++);
--len;
}
printf("\n");
}
void ipc_h4_receive(uint32_t *ptr)
{
IpcPipeMessage *message = (IpcPipeMessage *)ptr;
// We don't expect header to be received from M0+ core.
MBED_ASSERT(message->header_length == 0);
// printf("BLE received: ");
// h4_dump_buffer(buffer->message.data, buffer->message.length);
cordio::CordioHCITransportDriver::on_data_received(message->data, message->data_length);
}
IPCPipeTransportDriver::IPCPipeTransportDriver()
{ }
void IPCPipeTransportDriver::initialize()
{
// printf("H4 Transport driver initialization.\n");
ipcpipe_transport_start(IPCPIPE_CLIENT_H4, ipc_h4_receive, NULL);
}
void IPCPipeTransportDriver::terminate()
{
ipcpipe_transport_stop(IPCPIPE_CLIENT_H4);
}
uint16_t IPCPipeTransportDriver::write(uint8_t type, uint16_t len, uint8_t *pData)
{
// printf("BLE sending T<%02x>:", type);
// dump_buffer(pData, len);
ipcpipe_write_data(IPCPIPE_CLIENT_H4, &type, 1, pData, len);
return len;
}
} // namespace cypress
} // namespace vendor
} // namespace ble

View File

@ -0,0 +1,72 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2017 ARM Limited
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PSOC6_IPCPIPE_TRANSPORT_DRIVER_H_
#define PSOC6_IPCPIPE_TRANSPORT_DRIVER_H_
#include <stdint.h>
#include "mbed.h"
#include "CordioHCITransportDriver.h"
namespace ble {
namespace vendor {
namespace cypress {
using namespace ble::vendor;
/**
* Implementation of the H4 driver over PSoC6 IPC pipe.
*/
class IPCPipeTransportDriver : public cordio::CordioHCITransportDriver {
public:
/**
* Initialize the transport driver.
*
*/
IPCPipeTransportDriver();
/**
* Destructor
*/
virtual ~IPCPipeTransportDriver() { }
/**
* @see CordioHCITransportDriver::initialize
*/
virtual void initialize();
/**
* @see CordioHCITransportDriver::terminate
*/
virtual void terminate();
/**
* @see CordioHCITransportDriver::write
*/
virtual uint16_t write(uint8_t type, uint16_t len, uint8_t *pData);
private:
};
} // namespace cypress
} // namespace vendor
} // namespace ble
#endif /* PSOC6_IPCPIPE_TRANSPORT_DRIVER_H_ */

View File

@ -27,5 +27,19 @@
"macro_name": "NVSTORE_AREA_2_SIZE",
"help": "Area 2 size"
}
},
"target_overrides": {
"FUTURE_SEQUANA": {
"area_1_address": "0x100F8000",
"area_1_size": 16384,
"area_2_address": "0x100FC000",
"area_2_size": 16384
},
"FUTURE_SEQUANA_M0": {
"area_1_address": "0x10078000",
"area_1_size": 16384,
"area_2_address": "0x1007C000",
"area_2_size": 16384
}
}
}

View File

@ -0,0 +1,109 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PERIPHERALNAMES_H
#define MBED_PERIPHERALNAMES_H
#include "cmsis.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
UART_0 = (int)SCB0_BASE,
UART_1 = (int)SCB1_BASE,
UART_2 = (int)SCB2_BASE,
UART_3 = (int)SCB3_BASE,
UART_4 = (int)SCB4_BASE,
UART_5 = (int)SCB5_BASE,
UART_6 = (int)SCB6_BASE,
UART_7 = (int)SCB7_BASE,
} UARTName;
typedef enum {
SPI_0 = (int)SCB0_BASE,
SPI_1 = (int)SCB1_BASE,
SPI_2 = (int)SCB2_BASE,
SPI_3 = (int)SCB3_BASE,
SPI_4 = (int)SCB4_BASE,
SPI_5 = (int)SCB5_BASE,
SPI_6 = (int)SCB6_BASE,
SPI_7 = (int)SCB7_BASE,
} SPIName;
typedef enum {
I2C_0 = (int)SCB0_BASE,
I2C_1 = (int)SCB1_BASE,
I2C_2 = (int)SCB2_BASE,
I2C_3 = (int)SCB3_BASE,
I2C_4 = (int)SCB4_BASE,
I2C_5 = (int)SCB5_BASE,
I2C_6 = (int)SCB6_BASE,
I2C_7 = (int)SCB7_BASE,
} I2CName;
typedef enum {
PWM_32b_0 = TCPWM0_BASE,
PWM_32b_1,
PWM_32b_2,
PWM_32b_3,
PWM_32b_4,
PWM_32b_5,
PWM_32b_6,
PWM_32b_7,
PWM_16b_0 = TCPWM1_BASE,
PWM_16b_1,
PWM_16b_2,
PWM_16b_3,
PWM_16b_4,
PWM_16b_5,
PWM_16b_6,
PWM_16b_7,
PWM_16b_8,
PWM_16b_9,
PWM_16b_10,
PWM_16b_11,
PWM_16b_12,
PWM_16b_13,
PWM_16b_14,
PWM_16b_15,
PWM_16b_16,
PWM_16b_17,
PWM_16b_18,
PWM_16b_19,
PWM_16b_20,
PWM_16b_21,
PWM_16b_22,
PWM_16b_23,
} PWMName;
typedef enum {
ADC_0 = (int)SAR_BASE,
} ADCName;
typedef enum {
DAC_0 = (int)CTDAC0_BASE,
} DACName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,62 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PERIPHERALPINS_H
#define MBED_PERIPHERALPINS_H
#include "pinmap.h"
#include "PeripheralNames.h"
// //*** 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_OUT[];
#endif
//*** SERIAL ***
#ifdef DEVICE_SERIAL
extern const PinMap PinMap_UART_TX[];
extern const PinMap PinMap_UART_RX[];
extern const PinMap PinMap_UART_RTS[];
extern const PinMap PinMap_UART_CTS[];
#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
//*** ADC ***
#ifdef DEVICE_ANALOGIN
extern const PinMap PinMap_ADC[];
#endif
//*** DAC ***
#ifdef DEVICE_ANALOGOUT
extern const PinMap PinMap_DAC[];
#endif
#endif

View File

@ -0,0 +1,84 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PINNAMESTYPES_H
#define MBED_PINNAMESTYPES_H
#include "cmsis.h"
typedef enum {
PIN_INPUT = 0,
PIN_OUTPUT
} PinDirection;
typedef enum {
PullNone = 0,
PullUp = 1,
PullDown = 2,
OpenDrainDriveLow = 3,
OpenDrainDriveHigh = 4,
OpenDrain = OpenDrainDriveLow,
PushPull = 5,
AnalogMode = 6,
PullDefault = PullNone
} PinMode;
typedef struct {
en_hsiom_sel_t hsiom : 8;
en_clk_dst_t clock : 8;
PinMode mode : 4;
PinDirection dir : 1;
} PinFunction;
// Encode pin function.
// Output function
#define CY_PIN_FUNCTION(hsiom, clock, mode, dir) (int)(((dir) << 20) | ((mode) << 16) | ((clock) << 8) | (hsiom))
#define CY_PIN_OUT_FUNCTION(hsiom, clock) CY_PIN_FUNCTION(hsiom, clock, PushPull, PIN_OUTPUT)
#define CY_PIN_OD_FUNCTION(hsiom, clock) CY_PIN_FUNCTION(hsiom, clock, OpenDrain, PIN_OUTPUT)
#define CY_PIN_IN_FUNCTION(hsiom, clock) CY_PIN_FUNCTION(hsiom, clock, PullDefault, PIN_INPUT)
#define CY_PIN_PULLUP_FUNCTION(hsiom, clock) CY_PIN_FUNCTION(hsiom, clock, PullUp, PIN_INPUT)
#define CY_PIN_ANALOG_FUNCTION(clock) CY_PIN_FUNCTION(HSIOM_SEL_GPIO, clock, AnalogMode, 0)
// Create unique name to force 32-bit PWM usage on a pin.
#define CY_PIN_FORCE_PWM_32(pin) ((uint32_t)(pin) + 0x8000)
static inline en_hsiom_sel_t CY_PIN_HSIOM(int function)
{
return (en_hsiom_sel_t)(function & 0xFF);
}
static inline en_clk_dst_t CY_PIN_CLOCK(int function)
{
return (en_clk_dst_t)((function >> 8) & 0xFF);
}
static inline PinMode CY_PIN_MODE(int function)
{
return (PinMode)((function >> 16) & 0x0F);
}
static inline PinDirection CY_PIN_DIRECTION(int function)
{
return (PinDirection)((function >> 20) & 1);
}
static inline int CY_PERIPHERAL_BASE(int peripheral)
{
return peripheral & 0xffff0000;
}
#endif

View File

@ -0,0 +1,47 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PORTNAMES_H
#define MBED_PORTNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
// Port[15-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
} PortName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,364 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "PeripheralNames.h"
#include "PeripheralPins.h"
#include "pinmap.h"
#if DEVICE_SERIAL
//*** SERIAL ***
const PinMap PinMap_UART_RX[] = {
{P0_2, UART_0, CY_PIN_IN_FUNCTION( P0_2_SCB0_UART_RX, PCLK_SCB0_CLOCK)},
{P1_0, UART_7, CY_PIN_IN_FUNCTION( P1_0_SCB7_UART_RX, PCLK_SCB7_CLOCK)},
{P5_0, UART_5, CY_PIN_IN_FUNCTION( P5_0_SCB5_UART_RX, PCLK_SCB5_CLOCK)},
{P6_0, UART_3, CY_PIN_IN_FUNCTION( P6_0_SCB3_UART_RX, PCLK_SCB3_CLOCK)},
{P6_4, UART_6, CY_PIN_IN_FUNCTION( P6_4_SCB6_UART_RX, PCLK_SCB6_CLOCK)},
{P7_0, UART_4, CY_PIN_IN_FUNCTION( P7_0_SCB4_UART_RX, PCLK_SCB4_CLOCK)},
{P8_0, UART_4, CY_PIN_IN_FUNCTION( P8_0_SCB4_UART_RX, PCLK_SCB4_CLOCK)},
{P9_0, UART_2, CY_PIN_IN_FUNCTION( P9_0_SCB2_UART_RX, PCLK_SCB2_CLOCK)},
{P10_0, UART_1, CY_PIN_IN_FUNCTION( P10_0_SCB1_UART_RX, PCLK_SCB1_CLOCK)},
{P11_0, UART_5, CY_PIN_IN_FUNCTION( P11_0_SCB5_UART_RX, PCLK_SCB5_CLOCK)},
{P12_0, UART_6, CY_PIN_IN_FUNCTION( P12_0_SCB6_UART_RX, PCLK_SCB6_CLOCK)},
{P13_0, UART_6, CY_PIN_IN_FUNCTION( P13_0_SCB6_UART_RX, PCLK_SCB6_CLOCK)},
{NC, NC, 0}
};
const PinMap PinMap_UART_TX[] = {
{P0_3, UART_0, CY_PIN_OUT_FUNCTION( P0_3_SCB0_UART_TX, PCLK_SCB0_CLOCK)},
{P1_1, UART_7, CY_PIN_OUT_FUNCTION( P1_1_SCB7_UART_TX, PCLK_SCB7_CLOCK)},
{P5_1, UART_5, CY_PIN_OUT_FUNCTION( P5_1_SCB5_UART_TX, PCLK_SCB5_CLOCK)},
{P6_1, UART_3, CY_PIN_OUT_FUNCTION( P6_1_SCB3_UART_TX, PCLK_SCB3_CLOCK)},
{P6_5, UART_6, CY_PIN_OUT_FUNCTION( P6_5_SCB6_UART_TX, PCLK_SCB6_CLOCK)},
{P7_1, UART_4, CY_PIN_OUT_FUNCTION( P7_1_SCB4_UART_TX, PCLK_SCB4_CLOCK)},
{P8_1, UART_4, CY_PIN_OUT_FUNCTION( P8_1_SCB4_UART_TX, PCLK_SCB4_CLOCK)},
{P9_1, UART_2, CY_PIN_OUT_FUNCTION( P9_1_SCB2_UART_TX, PCLK_SCB2_CLOCK)},
{P10_1, UART_1, CY_PIN_OUT_FUNCTION( P10_1_SCB1_UART_TX, PCLK_SCB1_CLOCK)},
{P11_1, UART_5, CY_PIN_OUT_FUNCTION( P11_1_SCB5_UART_TX, PCLK_SCB5_CLOCK)},
{P12_1, UART_6, CY_PIN_OUT_FUNCTION( P12_1_SCB6_UART_TX, PCLK_SCB6_CLOCK)},
{P13_1, UART_6, CY_PIN_OUT_FUNCTION( P13_1_SCB6_UART_TX, PCLK_SCB6_CLOCK)},
{NC, NC, 0}
};
const PinMap PinMap_UART_RTS[] = {
{P0_4, UART_0, CY_PIN_OUT_FUNCTION( P0_4_SCB0_UART_RTS, PCLK_SCB0_CLOCK)},
{P1_2, UART_7, CY_PIN_OUT_FUNCTION( P1_2_SCB7_UART_RTS, PCLK_SCB7_CLOCK)},
{P5_2, UART_5, CY_PIN_OUT_FUNCTION( P5_2_SCB5_UART_RTS, PCLK_SCB5_CLOCK)},
{P6_2, UART_3, CY_PIN_OUT_FUNCTION( P6_2_SCB3_UART_RTS, PCLK_SCB3_CLOCK)},
{P6_6, UART_6, CY_PIN_OUT_FUNCTION( P6_6_SCB6_UART_RTS, PCLK_SCB6_CLOCK)},
{P7_2, UART_4, CY_PIN_OUT_FUNCTION( P7_2_SCB4_UART_RTS, PCLK_SCB4_CLOCK)},
{P8_2, UART_4, CY_PIN_OUT_FUNCTION( P8_2_SCB4_UART_RTS, PCLK_SCB4_CLOCK)},
{P9_2, UART_2, CY_PIN_OUT_FUNCTION( P9_2_SCB2_UART_RTS, PCLK_SCB2_CLOCK)},
{P10_2, UART_1, CY_PIN_OUT_FUNCTION( P10_2_SCB1_UART_RTS, PCLK_SCB1_CLOCK)},
{P11_2, UART_5, CY_PIN_OUT_FUNCTION( P11_2_SCB5_UART_RTS, PCLK_SCB5_CLOCK)},
{P12_2, UART_6, CY_PIN_OUT_FUNCTION( P12_2_SCB6_UART_RTS, PCLK_SCB6_CLOCK)},
{NC, NC, 0}
};
const PinMap PinMap_UART_CTS[] = {
{P0_5, UART_0, CY_PIN_IN_FUNCTION( P0_5_SCB0_UART_CTS, PCLK_SCB0_CLOCK)},
{P1_3, UART_7, CY_PIN_IN_FUNCTION( P1_3_SCB7_UART_CTS, PCLK_SCB7_CLOCK)},
{P5_3, UART_5, CY_PIN_IN_FUNCTION( P5_3_SCB5_UART_CTS, PCLK_SCB5_CLOCK)},
{P6_3, UART_3, CY_PIN_IN_FUNCTION( P6_3_SCB3_UART_CTS, PCLK_SCB3_CLOCK)},
{P6_7, UART_6, CY_PIN_IN_FUNCTION( P6_7_SCB6_UART_CTS, PCLK_SCB6_CLOCK)},
{P7_3, UART_4, CY_PIN_IN_FUNCTION( P7_3_SCB4_UART_CTS, PCLK_SCB4_CLOCK)},
{P8_3, UART_4, CY_PIN_IN_FUNCTION( P8_3_SCB4_UART_CTS, PCLK_SCB4_CLOCK)},
{P9_3, UART_2, CY_PIN_IN_FUNCTION( P9_3_SCB2_UART_CTS, PCLK_SCB2_CLOCK)},
{P10_3, UART_1, CY_PIN_IN_FUNCTION( P10_3_SCB1_UART_CTS, PCLK_SCB1_CLOCK)},
{P11_3, UART_5, CY_PIN_IN_FUNCTION( P11_3_SCB5_UART_CTS, PCLK_SCB5_CLOCK)},
{P12_3, UART_6, CY_PIN_IN_FUNCTION( P12_3_SCB6_UART_CTS, PCLK_SCB6_CLOCK)},
{NC, NC, 0}
};
#endif // DEVICE_SERIAL
#if DEVICE_I2C
//*** I2C ***
const PinMap PinMap_I2C_SCL[] = {
{P0_2, I2C_0, CY_PIN_OD_FUNCTION( P0_2_SCB0_I2C_SCL, PCLK_SCB0_CLOCK)},
{P1_0, I2C_7, CY_PIN_OD_FUNCTION( P1_0_SCB7_I2C_SCL, PCLK_SCB7_CLOCK)},
{P5_0, I2C_5, CY_PIN_OD_FUNCTION( P5_0_SCB5_I2C_SCL, PCLK_SCB5_CLOCK)},
{P6_0, I2C_3, CY_PIN_OD_FUNCTION( P6_0_SCB3_I2C_SCL, PCLK_SCB3_CLOCK)},
{P6_4, I2C_6, CY_PIN_OD_FUNCTION( P6_4_SCB6_I2C_SCL, PCLK_SCB6_CLOCK)},
{P7_0, I2C_4, CY_PIN_OD_FUNCTION( P7_0_SCB4_I2C_SCL, PCLK_SCB4_CLOCK)},
{P8_0, I2C_4, CY_PIN_OD_FUNCTION( P8_0_SCB4_I2C_SCL, PCLK_SCB4_CLOCK)},
{P9_0, I2C_2, CY_PIN_OD_FUNCTION( P9_0_SCB2_I2C_SCL, PCLK_SCB2_CLOCK)},
{P10_0, I2C_1, CY_PIN_OD_FUNCTION( P10_0_SCB1_I2C_SCL, PCLK_SCB1_CLOCK)},
{P11_0, I2C_5, CY_PIN_OD_FUNCTION( P11_0_SCB5_I2C_SCL, PCLK_SCB5_CLOCK)},
{P12_0, I2C_6, CY_PIN_OD_FUNCTION( P12_0_SCB6_I2C_SCL, PCLK_SCB6_CLOCK)},
{P13_0, I2C_6, CY_PIN_OD_FUNCTION( P13_0_SCB6_I2C_SCL, PCLK_SCB6_CLOCK)},
{NC, NC, 0}
};
const PinMap PinMap_I2C_SDA[] = {
{P0_3, I2C_0, CY_PIN_OD_FUNCTION( P0_3_SCB0_I2C_SDA, PCLK_SCB0_CLOCK)},
{P1_1, I2C_7, CY_PIN_OD_FUNCTION( P1_1_SCB7_I2C_SDA, PCLK_SCB7_CLOCK)},
{P5_1, I2C_5, CY_PIN_OD_FUNCTION( P5_1_SCB5_I2C_SDA, PCLK_SCB5_CLOCK)},
{P6_1, I2C_3, CY_PIN_OD_FUNCTION( P6_1_SCB3_I2C_SDA, PCLK_SCB3_CLOCK)},
{P6_5, I2C_6, CY_PIN_OD_FUNCTION( P6_5_SCB6_I2C_SDA, PCLK_SCB6_CLOCK)},
{P7_1, I2C_4, CY_PIN_OD_FUNCTION( P7_1_SCB4_I2C_SDA, PCLK_SCB4_CLOCK)},
{P8_1, I2C_4, CY_PIN_OD_FUNCTION( P8_1_SCB4_I2C_SDA, PCLK_SCB4_CLOCK)},
{P9_1, I2C_2, CY_PIN_OD_FUNCTION( P9_1_SCB2_I2C_SDA, PCLK_SCB2_CLOCK)},
{P10_1, I2C_1, CY_PIN_OD_FUNCTION( P10_1_SCB1_I2C_SDA, PCLK_SCB1_CLOCK)},
{P11_1, I2C_5, CY_PIN_OD_FUNCTION( P11_1_SCB5_I2C_SDA, PCLK_SCB5_CLOCK)},
{P12_1, I2C_6, CY_PIN_OD_FUNCTION( P12_1_SCB6_I2C_SDA, PCLK_SCB6_CLOCK)},
{P13_1, I2C_6, CY_PIN_OD_FUNCTION( P13_1_SCB6_I2C_SDA, PCLK_SCB6_CLOCK)},
{NC, NC, 0}
};
#endif // DEVICE_I2C
#if DEVICE_SPI
//*** SPI ***
const PinMap PinMap_SPI_MOSI[] = {
{P0_2, SPI_0, CY_PIN_OUT_FUNCTION( P0_2_SCB0_SPI_MOSI, PCLK_SCB0_CLOCK)},
{P1_0, SPI_7, CY_PIN_OUT_FUNCTION( P1_0_SCB7_SPI_MOSI, PCLK_SCB7_CLOCK)},
{P5_0, SPI_5, CY_PIN_OUT_FUNCTION( P5_0_SCB5_SPI_MOSI, PCLK_SCB5_CLOCK)},
{P6_0, SPI_3, CY_PIN_OUT_FUNCTION( P6_0_SCB3_SPI_MOSI, PCLK_SCB3_CLOCK)},
{P6_4, SPI_6, CY_PIN_OUT_FUNCTION( P6_4_SCB6_SPI_MOSI, PCLK_SCB6_CLOCK)},
{P7_0, SPI_4, CY_PIN_OUT_FUNCTION( P7_0_SCB4_SPI_MOSI, PCLK_SCB4_CLOCK)},
{P8_0, SPI_4, CY_PIN_OUT_FUNCTION( P8_0_SCB4_SPI_MOSI, PCLK_SCB4_CLOCK)},
{P9_0, SPI_2, CY_PIN_OUT_FUNCTION( P9_0_SCB2_SPI_MOSI, PCLK_SCB2_CLOCK)},
{P10_0, SPI_1, CY_PIN_OUT_FUNCTION( P10_0_SCB1_SPI_MOSI, PCLK_SCB1_CLOCK)},
{P11_0, SPI_5, CY_PIN_OUT_FUNCTION( P11_0_SCB5_SPI_MOSI, PCLK_SCB5_CLOCK)},
{P12_0, SPI_6, CY_PIN_OUT_FUNCTION( P12_0_SCB6_SPI_MOSI, PCLK_SCB6_CLOCK)},
{P13_0, SPI_6, CY_PIN_OUT_FUNCTION( P13_0_SCB6_SPI_MOSI, PCLK_SCB6_CLOCK)},
{NC, NC, 0}
};
const PinMap PinMap_SPI_MISO[] = {
{P0_3, SPI_0, CY_PIN_IN_FUNCTION( P0_3_SCB0_SPI_MISO, PCLK_SCB0_CLOCK)},
{P1_1, SPI_7, CY_PIN_IN_FUNCTION( P1_1_SCB7_SPI_MISO, PCLK_SCB7_CLOCK)},
{P5_1, SPI_5, CY_PIN_IN_FUNCTION( P5_1_SCB5_SPI_MISO, PCLK_SCB5_CLOCK)},
{P6_1, SPI_3, CY_PIN_IN_FUNCTION( P6_1_SCB3_SPI_MISO, PCLK_SCB3_CLOCK)},
{P6_5, SPI_6, CY_PIN_IN_FUNCTION( P6_5_SCB6_SPI_MISO, PCLK_SCB6_CLOCK)},
{P7_1, SPI_4, CY_PIN_IN_FUNCTION( P7_1_SCB4_SPI_MISO, PCLK_SCB4_CLOCK)},
{P8_1, SPI_4, CY_PIN_IN_FUNCTION( P8_1_SCB4_SPI_MISO, PCLK_SCB4_CLOCK)},
{P9_1, SPI_2, CY_PIN_IN_FUNCTION( P9_1_SCB2_SPI_MISO, PCLK_SCB2_CLOCK)},
{P10_1, SPI_1, CY_PIN_IN_FUNCTION( P10_1_SCB1_SPI_MISO, PCLK_SCB1_CLOCK)},
{P11_1, SPI_5, CY_PIN_IN_FUNCTION( P11_1_SCB5_SPI_MISO, PCLK_SCB5_CLOCK)},
{P12_1, SPI_6, CY_PIN_IN_FUNCTION( P12_1_SCB6_SPI_MISO, PCLK_SCB6_CLOCK)},
{P13_1, SPI_6, CY_PIN_IN_FUNCTION( P13_1_SCB6_SPI_MISO, PCLK_SCB6_CLOCK)},
{NC, NC, 0}
};
const PinMap PinMap_SPI_SCLK[] = {
{P0_4, SPI_0, CY_PIN_OUT_FUNCTION( P0_4_SCB0_SPI_CLK, PCLK_SCB0_CLOCK)},
{P1_2, SPI_7, CY_PIN_OUT_FUNCTION( P1_2_SCB7_SPI_CLK, PCLK_SCB7_CLOCK)},
{P5_2, SPI_5, CY_PIN_OUT_FUNCTION( P5_2_SCB5_SPI_CLK, PCLK_SCB5_CLOCK)},
{P6_2, SPI_3, CY_PIN_OUT_FUNCTION( P6_2_SCB3_SPI_CLK, PCLK_SCB3_CLOCK)},
{P6_6, SPI_6, CY_PIN_OUT_FUNCTION( P6_6_SCB6_SPI_CLK, PCLK_SCB6_CLOCK)},
{P7_2, SPI_4, CY_PIN_OUT_FUNCTION( P7_2_SCB4_SPI_CLK, PCLK_SCB4_CLOCK)},
{P8_2, SPI_4, CY_PIN_OUT_FUNCTION( P8_2_SCB4_SPI_CLK, PCLK_SCB4_CLOCK)},
{P9_2, SPI_2, CY_PIN_OUT_FUNCTION( P9_2_SCB2_SPI_CLK, PCLK_SCB2_CLOCK)},
{P10_2, SPI_1, CY_PIN_OUT_FUNCTION( P10_2_SCB1_SPI_CLK, PCLK_SCB1_CLOCK)},
{P11_2, SPI_5, CY_PIN_OUT_FUNCTION( P11_2_SCB5_SPI_CLK, PCLK_SCB5_CLOCK)},
{P12_2, SPI_6, CY_PIN_OUT_FUNCTION( P12_2_SCB6_SPI_CLK, PCLK_SCB6_CLOCK)},
{NC, NC, 0}
};
const PinMap PinMap_SPI_SSEL[] = {
{P0_5, SPI_0, CY_PIN_OUT_FUNCTION( P0_5_SCB0_SPI_SELECT0, PCLK_SCB0_CLOCK)},
{P1_3, SPI_7, CY_PIN_OUT_FUNCTION( P1_3_SCB7_SPI_SELECT0, PCLK_SCB7_CLOCK)},
{P5_3, SPI_5, CY_PIN_OUT_FUNCTION( P5_3_SCB5_SPI_SELECT0, PCLK_SCB5_CLOCK)},
{P6_3, SPI_3, CY_PIN_OUT_FUNCTION( P6_3_SCB3_SPI_SELECT0, PCLK_SCB3_CLOCK)},
{P6_7, SPI_6, CY_PIN_OUT_FUNCTION( P6_7_SCB6_SPI_SELECT0, PCLK_SCB6_CLOCK)},
{P7_3, SPI_4, CY_PIN_OUT_FUNCTION( P7_3_SCB4_SPI_SELECT0, PCLK_SCB4_CLOCK)},
{P8_3, SPI_4, CY_PIN_OUT_FUNCTION( P8_3_SCB4_SPI_SELECT0, PCLK_SCB4_CLOCK)},
{P9_3, SPI_2, CY_PIN_OUT_FUNCTION( P9_3_SCB2_SPI_SELECT0, PCLK_SCB2_CLOCK)},
{P10_3, SPI_1, CY_PIN_OUT_FUNCTION( P10_3_SCB1_SPI_SELECT0, PCLK_SCB1_CLOCK)},
{P11_3, SPI_5, CY_PIN_OUT_FUNCTION( P11_3_SCB5_SPI_SELECT0, PCLK_SCB5_CLOCK)},
{P12_3, SPI_6, CY_PIN_OUT_FUNCTION( P12_3_SCB6_SPI_SELECT0, PCLK_SCB6_CLOCK)},
{NC, NC, 0}
};
#endif // DEVICE_SPI
#if DEVICE_PWMOUT
//*** PWM ***
const PinMap PinMap_PWM_OUT[] = {
// 16-bit PWM outputs
{P0_0, PWM_16b_0, CY_PIN_OUT_FUNCTION(P0_0_TCPWM1_LINE0, PCLK_TCPWM1_CLOCKS0)},
{P0_2, PWM_16b_1, CY_PIN_OUT_FUNCTION(P0_2_TCPWM1_LINE1, PCLK_TCPWM1_CLOCKS1)},
{P0_4, PWM_16b_2, CY_PIN_OUT_FUNCTION(P0_4_TCPWM1_LINE2, PCLK_TCPWM1_CLOCKS2)},
{P1_0, PWM_16b_3, CY_PIN_OUT_FUNCTION(P1_0_TCPWM1_LINE3, PCLK_TCPWM1_CLOCKS3)},
{P1_2, PWM_16b_12, CY_PIN_OUT_FUNCTION(P1_2_TCPWM1_LINE12, PCLK_TCPWM1_CLOCKS12)},
{P1_4, PWM_16b_13, CY_PIN_OUT_FUNCTION(P1_4_TCPWM1_LINE13, PCLK_TCPWM1_CLOCKS13)},
{P5_0, PWM_16b_4, CY_PIN_OUT_FUNCTION(P5_0_TCPWM1_LINE4, PCLK_TCPWM1_CLOCKS4)},
{P5_2, PWM_16b_5, CY_PIN_OUT_FUNCTION(P5_2_TCPWM1_LINE5, PCLK_TCPWM1_CLOCKS5)},
{P5_4, PWM_16b_6, CY_PIN_OUT_FUNCTION(P5_4_TCPWM1_LINE6, PCLK_TCPWM1_CLOCKS6)},
{P5_6, PWM_16b_7, CY_PIN_OUT_FUNCTION(P5_6_TCPWM1_LINE7, PCLK_TCPWM1_CLOCKS7)},
{P6_0, PWM_16b_8, CY_PIN_OUT_FUNCTION(P6_0_TCPWM1_LINE8, PCLK_TCPWM1_CLOCKS8)},
{P6_2, PWM_16b_9, CY_PIN_OUT_FUNCTION(P6_2_TCPWM1_LINE9, PCLK_TCPWM1_CLOCKS9)},
{P6_4, PWM_16b_10, CY_PIN_OUT_FUNCTION(P6_4_TCPWM1_LINE10, PCLK_TCPWM1_CLOCKS10)},
{P6_6, PWM_16b_11, CY_PIN_OUT_FUNCTION(P6_6_TCPWM1_LINE11, PCLK_TCPWM1_CLOCKS11)},
{P7_0, PWM_16b_12, CY_PIN_OUT_FUNCTION(P7_0_TCPWM1_LINE12, PCLK_TCPWM1_CLOCKS12)},
{P7_2, PWM_16b_13, CY_PIN_OUT_FUNCTION(P7_2_TCPWM1_LINE13, PCLK_TCPWM1_CLOCKS13)},
{P7_4, PWM_16b_14, CY_PIN_OUT_FUNCTION(P7_4_TCPWM1_LINE14, PCLK_TCPWM1_CLOCKS14)},
{P7_6, PWM_16b_15, CY_PIN_OUT_FUNCTION(P7_6_TCPWM1_LINE15, PCLK_TCPWM1_CLOCKS15)},
{P8_0, PWM_16b_16, CY_PIN_OUT_FUNCTION(P8_0_TCPWM1_LINE16, PCLK_TCPWM1_CLOCKS16)},
{P8_2, PWM_16b_17, CY_PIN_OUT_FUNCTION(P8_2_TCPWM1_LINE17, PCLK_TCPWM1_CLOCKS17)},
{P8_4, PWM_16b_18, CY_PIN_OUT_FUNCTION(P8_4_TCPWM1_LINE18, PCLK_TCPWM1_CLOCKS18)},
{P8_6, PWM_16b_19, CY_PIN_OUT_FUNCTION(P8_6_TCPWM1_LINE19, PCLK_TCPWM1_CLOCKS19)},
{P9_0, PWM_16b_20, CY_PIN_OUT_FUNCTION(P9_0_TCPWM1_LINE20, PCLK_TCPWM1_CLOCKS20)},
{P9_2, PWM_16b_21, CY_PIN_OUT_FUNCTION(P9_2_TCPWM1_LINE21, PCLK_TCPWM1_CLOCKS21)},
{P9_4, PWM_16b_0, CY_PIN_OUT_FUNCTION(P9_4_TCPWM1_LINE0, PCLK_TCPWM1_CLOCKS0)},
{P9_6, PWM_16b_1, CY_PIN_OUT_FUNCTION(P9_6_TCPWM1_LINE1, PCLK_TCPWM1_CLOCKS1)},
{P10_0, PWM_16b_22, CY_PIN_OUT_FUNCTION(P10_0_TCPWM1_LINE22, PCLK_TCPWM1_CLOCKS22)},
{P10_2, PWM_16b_23, CY_PIN_OUT_FUNCTION(P10_2_TCPWM1_LINE23, PCLK_TCPWM1_CLOCKS23)},
{P10_4, PWM_16b_0, CY_PIN_OUT_FUNCTION(P10_4_TCPWM1_LINE0, PCLK_TCPWM1_CLOCKS0)},
{P10_6, PWM_16b_2, CY_PIN_OUT_FUNCTION(P10_6_TCPWM1_LINE2, PCLK_TCPWM1_CLOCKS2)},
{P11_0, PWM_16b_1, CY_PIN_OUT_FUNCTION(P11_0_TCPWM1_LINE1, PCLK_TCPWM1_CLOCKS1)},
{P11_2, PWM_16b_2, CY_PIN_OUT_FUNCTION(P11_2_TCPWM1_LINE2, PCLK_TCPWM1_CLOCKS2)},
{P11_4, PWM_16b_3, CY_PIN_OUT_FUNCTION(P11_4_TCPWM1_LINE3, PCLK_TCPWM1_CLOCKS3)},
{P12_0, PWM_16b_4, CY_PIN_OUT_FUNCTION(P12_0_TCPWM1_LINE4, PCLK_TCPWM1_CLOCKS4)},
{P12_2, PWM_16b_5, CY_PIN_OUT_FUNCTION(P12_2_TCPWM1_LINE5, PCLK_TCPWM1_CLOCKS5)},
{P12_4, PWM_16b_6, CY_PIN_OUT_FUNCTION(P12_4_TCPWM1_LINE6, PCLK_TCPWM1_CLOCKS6)},
{P12_6, PWM_16b_7, CY_PIN_OUT_FUNCTION(P12_6_TCPWM1_LINE7, PCLK_TCPWM1_CLOCKS7)},
{P13_0, PWM_16b_8, CY_PIN_OUT_FUNCTION(P13_0_TCPWM1_LINE8, PCLK_TCPWM1_CLOCKS8)},
{P13_6, PWM_16b_11, CY_PIN_OUT_FUNCTION(P13_6_TCPWM1_LINE11, PCLK_TCPWM1_CLOCKS11)},
// 16-bit PWM inverted outputs
{P0_1, PWM_16b_0, CY_PIN_OUT_FUNCTION(P0_1_TCPWM1_LINE_COMPL0, PCLK_TCPWM1_CLOCKS0)},
{P0_3, PWM_16b_1, CY_PIN_OUT_FUNCTION(P0_3_TCPWM1_LINE_COMPL1, PCLK_TCPWM1_CLOCKS1)},
{P0_5, PWM_16b_2, CY_PIN_OUT_FUNCTION(P0_5_TCPWM1_LINE_COMPL2, PCLK_TCPWM1_CLOCKS2)},
{P1_1, PWM_16b_3, CY_PIN_OUT_FUNCTION(P1_1_TCPWM1_LINE_COMPL3, PCLK_TCPWM1_CLOCKS3)},
{P1_3, PWM_16b_12, CY_PIN_OUT_FUNCTION(P1_3_TCPWM1_LINE_COMPL12, PCLK_TCPWM1_CLOCKS12)},
{P1_5, PWM_16b_14, CY_PIN_OUT_FUNCTION(P1_5_TCPWM1_LINE_COMPL14, PCLK_TCPWM1_CLOCKS14)},
{P5_1, PWM_16b_4, CY_PIN_OUT_FUNCTION(P5_1_TCPWM1_LINE_COMPL4, PCLK_TCPWM1_CLOCKS4)},
{P5_3, PWM_16b_5, CY_PIN_OUT_FUNCTION(P5_3_TCPWM1_LINE_COMPL5, PCLK_TCPWM1_CLOCKS5)},
{P5_5, PWM_16b_6, CY_PIN_OUT_FUNCTION(P5_5_TCPWM1_LINE_COMPL6, PCLK_TCPWM1_CLOCKS6)},
{P6_1, PWM_16b_8, CY_PIN_OUT_FUNCTION(P6_1_TCPWM1_LINE_COMPL8, PCLK_TCPWM1_CLOCKS8)},
{P6_3, PWM_16b_9, CY_PIN_OUT_FUNCTION(P6_3_TCPWM1_LINE_COMPL9, PCLK_TCPWM1_CLOCKS9)},
{P6_5, PWM_16b_10, CY_PIN_OUT_FUNCTION(P6_5_TCPWM1_LINE_COMPL10, PCLK_TCPWM1_CLOCKS10)},
{P6_7, PWM_16b_11, CY_PIN_OUT_FUNCTION(P6_7_TCPWM1_LINE_COMPL11, PCLK_TCPWM1_CLOCKS11)},
{P7_1, PWM_16b_12, CY_PIN_OUT_FUNCTION(P7_1_TCPWM1_LINE_COMPL12, PCLK_TCPWM1_CLOCKS12)},
{P7_3, PWM_16b_13, CY_PIN_OUT_FUNCTION(P7_3_TCPWM1_LINE_COMPL13, PCLK_TCPWM1_CLOCKS13)},
{P7_5, PWM_16b_14, CY_PIN_OUT_FUNCTION(P7_5_TCPWM1_LINE_COMPL14, PCLK_TCPWM1_CLOCKS14)},
{P7_7, PWM_16b_15, CY_PIN_OUT_FUNCTION(P7_7_TCPWM1_LINE_COMPL15, PCLK_TCPWM1_CLOCKS15)},
{P8_1, PWM_16b_16, CY_PIN_OUT_FUNCTION(P8_1_TCPWM1_LINE_COMPL16, PCLK_TCPWM1_CLOCKS16)},
{P8_3, PWM_16b_17, CY_PIN_OUT_FUNCTION(P8_3_TCPWM1_LINE_COMPL17, PCLK_TCPWM1_CLOCKS17)},
{P8_5, PWM_16b_18, CY_PIN_OUT_FUNCTION(P8_5_TCPWM1_LINE_COMPL18, PCLK_TCPWM1_CLOCKS18)},
{P8_7, PWM_16b_19, CY_PIN_OUT_FUNCTION(P8_7_TCPWM1_LINE_COMPL19, PCLK_TCPWM1_CLOCKS19)},
{P9_1, PWM_16b_20, CY_PIN_OUT_FUNCTION(P9_1_TCPWM1_LINE_COMPL20, PCLK_TCPWM1_CLOCKS20)},
{P9_3, PWM_16b_21, CY_PIN_OUT_FUNCTION(P9_3_TCPWM1_LINE_COMPL21, PCLK_TCPWM1_CLOCKS21)},
{P9_5, PWM_16b_0, CY_PIN_OUT_FUNCTION(P9_5_TCPWM1_LINE_COMPL0, PCLK_TCPWM1_CLOCKS0)},
{P9_7, PWM_16b_1, CY_PIN_OUT_FUNCTION(P9_7_TCPWM1_LINE_COMPL1, PCLK_TCPWM1_CLOCKS1)},
{P10_1, PWM_16b_22, CY_PIN_OUT_FUNCTION(P10_1_TCPWM1_LINE_COMPL22, PCLK_TCPWM1_CLOCKS22)},
{P10_3, PWM_16b_23, CY_PIN_OUT_FUNCTION(P10_3_TCPWM1_LINE_COMPL23, PCLK_TCPWM1_CLOCKS23)},
{P10_5, PWM_16b_0, CY_PIN_OUT_FUNCTION(P10_5_TCPWM1_LINE_COMPL0, PCLK_TCPWM1_CLOCKS0)},
{P11_1, PWM_16b_1, CY_PIN_OUT_FUNCTION(P11_1_TCPWM1_LINE_COMPL1, PCLK_TCPWM1_CLOCKS1)},
{P11_3, PWM_16b_2, CY_PIN_OUT_FUNCTION(P11_3_TCPWM1_LINE_COMPL2, PCLK_TCPWM1_CLOCKS2)},
{P11_5, PWM_16b_3, CY_PIN_OUT_FUNCTION(P11_5_TCPWM1_LINE_COMPL3, PCLK_TCPWM1_CLOCKS3)},
{P12_1, PWM_16b_4, CY_PIN_OUT_FUNCTION(P12_1_TCPWM1_LINE_COMPL4, PCLK_TCPWM1_CLOCKS4)},
{P12_3, PWM_16b_5, CY_PIN_OUT_FUNCTION(P12_3_TCPWM1_LINE_COMPL5, PCLK_TCPWM1_CLOCKS5)},
{P12_5, PWM_16b_6, CY_PIN_OUT_FUNCTION(P12_5_TCPWM1_LINE_COMPL6, PCLK_TCPWM1_CLOCKS6)},
{P12_7, PWM_16b_7, CY_PIN_OUT_FUNCTION(P12_7_TCPWM1_LINE_COMPL7, PCLK_TCPWM1_CLOCKS7)},
{P13_1, PWM_16b_8, CY_PIN_OUT_FUNCTION(P13_1_TCPWM1_LINE_COMPL8, PCLK_TCPWM1_CLOCKS8)},
{P13_7, PWM_16b_11, CY_PIN_OUT_FUNCTION(P13_7_TCPWM1_LINE_COMPL11, PCLK_TCPWM1_CLOCKS11)},
// 32-bit PWM outputs
{PWM32(P0_0), PWM_32b_0, CY_PIN_OUT_FUNCTION(P0_0_TCPWM0_LINE0, PCLK_TCPWM0_CLOCKS0)},
{PWM32(P0_2), PWM_32b_1, CY_PIN_OUT_FUNCTION(P0_2_TCPWM0_LINE1, PCLK_TCPWM0_CLOCKS1)},
{PWM32(P0_4), PWM_32b_2, CY_PIN_OUT_FUNCTION(P0_4_TCPWM0_LINE2, PCLK_TCPWM0_CLOCKS2)},
{PWM32(P1_0), PWM_32b_3, CY_PIN_OUT_FUNCTION(P1_0_TCPWM0_LINE3, PCLK_TCPWM0_CLOCKS3)},
{PWM32(P1_2), PWM_32b_4, CY_PIN_OUT_FUNCTION(P1_2_TCPWM0_LINE4, PCLK_TCPWM0_CLOCKS4)},
{PWM32(P1_4), PWM_32b_5, CY_PIN_OUT_FUNCTION(P1_4_TCPWM0_LINE5, PCLK_TCPWM0_CLOCKS5)},
{PWM32(P5_0), PWM_32b_4, CY_PIN_OUT_FUNCTION(P5_0_TCPWM0_LINE4, PCLK_TCPWM0_CLOCKS4)},
{PWM32(P5_2), PWM_32b_5, CY_PIN_OUT_FUNCTION(P5_2_TCPWM0_LINE5, PCLK_TCPWM0_CLOCKS5)},
{PWM32(P5_4), PWM_32b_6, CY_PIN_OUT_FUNCTION(P5_4_TCPWM0_LINE6, PCLK_TCPWM0_CLOCKS6)},
{PWM32(P5_6), PWM_32b_7, CY_PIN_OUT_FUNCTION(P5_6_TCPWM0_LINE7, PCLK_TCPWM0_CLOCKS7)},
{PWM32(P6_0), PWM_32b_0, CY_PIN_OUT_FUNCTION(P6_0_TCPWM0_LINE0, PCLK_TCPWM0_CLOCKS0)},
{PWM32(P6_2), PWM_32b_1, CY_PIN_OUT_FUNCTION(P6_2_TCPWM0_LINE1, PCLK_TCPWM0_CLOCKS1)},
{PWM32(P6_4), PWM_32b_2, CY_PIN_OUT_FUNCTION(P6_4_TCPWM0_LINE2, PCLK_TCPWM0_CLOCKS2)},
{PWM32(P6_6), PWM_32b_3, CY_PIN_OUT_FUNCTION(P6_6_TCPWM0_LINE3, PCLK_TCPWM0_CLOCKS3)},
{PWM32(P7_0), PWM_32b_4, CY_PIN_OUT_FUNCTION(P7_0_TCPWM0_LINE4, PCLK_TCPWM0_CLOCKS4)},
{PWM32(P7_2), PWM_32b_5, CY_PIN_OUT_FUNCTION(P7_2_TCPWM0_LINE5, PCLK_TCPWM0_CLOCKS5)},
{PWM32(P7_4), PWM_32b_6, CY_PIN_OUT_FUNCTION(P7_4_TCPWM0_LINE6, PCLK_TCPWM0_CLOCKS6)},
{PWM32(P7_6), PWM_32b_7, CY_PIN_OUT_FUNCTION(P7_6_TCPWM0_LINE7, PCLK_TCPWM0_CLOCKS7)},
{PWM32(P8_0), PWM_32b_0, CY_PIN_OUT_FUNCTION(P8_0_TCPWM0_LINE0, PCLK_TCPWM0_CLOCKS0)},
{PWM32(P8_2), PWM_32b_1, CY_PIN_OUT_FUNCTION(P8_2_TCPWM0_LINE1, PCLK_TCPWM0_CLOCKS1)},
{PWM32(P8_4), PWM_32b_2, CY_PIN_OUT_FUNCTION(P8_4_TCPWM0_LINE2, PCLK_TCPWM0_CLOCKS2)},
{PWM32(P8_6), PWM_32b_3, CY_PIN_OUT_FUNCTION(P8_6_TCPWM0_LINE3, PCLK_TCPWM0_CLOCKS3)},
{PWM32(P9_0), PWM_32b_4, CY_PIN_OUT_FUNCTION(P9_0_TCPWM0_LINE4, PCLK_TCPWM0_CLOCKS4)},
{PWM32(P9_2), PWM_32b_5, CY_PIN_OUT_FUNCTION(P9_2_TCPWM0_LINE5, PCLK_TCPWM0_CLOCKS5)},
{PWM32(P9_4), PWM_32b_7, CY_PIN_OUT_FUNCTION(P9_4_TCPWM0_LINE7, PCLK_TCPWM0_CLOCKS7)},
{PWM32(P9_6), PWM_32b_0, CY_PIN_OUT_FUNCTION(P9_6_TCPWM0_LINE0, PCLK_TCPWM0_CLOCKS0)},
{PWM32(P10_0), PWM_32b_6, CY_PIN_OUT_FUNCTION(P10_0_TCPWM0_LINE6, PCLK_TCPWM0_CLOCKS6)},
{PWM32(P10_2), PWM_32b_7, CY_PIN_OUT_FUNCTION(P10_2_TCPWM0_LINE7, PCLK_TCPWM0_CLOCKS7)},
{PWM32(P10_4), PWM_32b_0, CY_PIN_OUT_FUNCTION(P10_4_TCPWM0_LINE0, PCLK_TCPWM0_CLOCKS0)},
{PWM32(P10_6), PWM_32b_1, CY_PIN_OUT_FUNCTION(P10_6_TCPWM0_LINE1, PCLK_TCPWM0_CLOCKS1)},
{PWM32(P11_0), PWM_32b_1, CY_PIN_OUT_FUNCTION(P11_0_TCPWM0_LINE1, PCLK_TCPWM0_CLOCKS1)},
{PWM32(P11_2), PWM_32b_2, CY_PIN_OUT_FUNCTION(P11_2_TCPWM0_LINE2, PCLK_TCPWM0_CLOCKS2)},
{PWM32(P11_4), PWM_32b_3, CY_PIN_OUT_FUNCTION(P11_4_TCPWM0_LINE3, PCLK_TCPWM0_CLOCKS3)},
{PWM32(P12_0), PWM_32b_4, CY_PIN_OUT_FUNCTION(P12_0_TCPWM0_LINE4, PCLK_TCPWM0_CLOCKS4)},
{PWM32(P12_2), PWM_32b_5, CY_PIN_OUT_FUNCTION(P12_2_TCPWM0_LINE5, PCLK_TCPWM0_CLOCKS5)},
{PWM32(P12_4), PWM_32b_6, CY_PIN_OUT_FUNCTION(P12_4_TCPWM0_LINE6, PCLK_TCPWM0_CLOCKS6)},
{PWM32(P12_6), PWM_32b_7, CY_PIN_OUT_FUNCTION(P12_6_TCPWM0_LINE7, PCLK_TCPWM0_CLOCKS7)},
{PWM32(P13_0), PWM_32b_0, CY_PIN_OUT_FUNCTION(P13_0_TCPWM0_LINE0, PCLK_TCPWM0_CLOCKS0)},
{PWM32(P13_6), PWM_32b_3, CY_PIN_OUT_FUNCTION(P13_6_TCPWM0_LINE3, PCLK_TCPWM0_CLOCKS3)},
// 32-bit PWM inverted outputs
{PWM32(P0_1), PWM_32b_0, CY_PIN_OUT_FUNCTION(P0_1_TCPWM0_LINE_COMPL0, PCLK_TCPWM0_CLOCKS0)},
{PWM32(P0_3), PWM_32b_1, CY_PIN_OUT_FUNCTION(P0_3_TCPWM0_LINE_COMPL1, PCLK_TCPWM0_CLOCKS1)},
{PWM32(P0_5), PWM_32b_2, CY_PIN_OUT_FUNCTION(P0_5_TCPWM0_LINE_COMPL2, PCLK_TCPWM0_CLOCKS2)},
{PWM32(P1_1), PWM_32b_3, CY_PIN_OUT_FUNCTION(P1_1_TCPWM0_LINE_COMPL3, PCLK_TCPWM0_CLOCKS3)},
{PWM32(P1_3), PWM_32b_4, CY_PIN_OUT_FUNCTION(P1_3_TCPWM0_LINE_COMPL4, PCLK_TCPWM0_CLOCKS4)},
{PWM32(P1_5), PWM_32b_5, CY_PIN_OUT_FUNCTION(P1_5_TCPWM0_LINE_COMPL5, PCLK_TCPWM0_CLOCKS5)},
{PWM32(P5_1), PWM_32b_4, CY_PIN_OUT_FUNCTION(P5_1_TCPWM0_LINE_COMPL4, PCLK_TCPWM0_CLOCKS4)},
{PWM32(P5_3), PWM_32b_5, CY_PIN_OUT_FUNCTION(P5_3_TCPWM0_LINE_COMPL5, PCLK_TCPWM0_CLOCKS5)},
{PWM32(P5_5), PWM_32b_6, CY_PIN_OUT_FUNCTION(P5_5_TCPWM0_LINE_COMPL6, PCLK_TCPWM0_CLOCKS6)},
{PWM32(P6_1), PWM_32b_0, CY_PIN_OUT_FUNCTION(P6_1_TCPWM0_LINE_COMPL0, PCLK_TCPWM0_CLOCKS0)},
{PWM32(P6_3), PWM_32b_1, CY_PIN_OUT_FUNCTION(P6_3_TCPWM0_LINE_COMPL1, PCLK_TCPWM0_CLOCKS1)},
{PWM32(P6_5), PWM_32b_2, CY_PIN_OUT_FUNCTION(P6_5_TCPWM0_LINE_COMPL2, PCLK_TCPWM0_CLOCKS2)},
{PWM32(P6_7), PWM_32b_3, CY_PIN_OUT_FUNCTION(P6_7_TCPWM0_LINE_COMPL3, PCLK_TCPWM0_CLOCKS3)},
{PWM32(P7_1), PWM_32b_4, CY_PIN_OUT_FUNCTION(P7_1_TCPWM0_LINE_COMPL4, PCLK_TCPWM0_CLOCKS4)},
{PWM32(P7_3), PWM_32b_5, CY_PIN_OUT_FUNCTION(P7_3_TCPWM0_LINE_COMPL5, PCLK_TCPWM0_CLOCKS5)},
{PWM32(P7_5), PWM_32b_6, CY_PIN_OUT_FUNCTION(P7_5_TCPWM0_LINE_COMPL6, PCLK_TCPWM0_CLOCKS6)},
{PWM32(P7_7), PWM_32b_7, CY_PIN_OUT_FUNCTION(P7_7_TCPWM0_LINE_COMPL7, PCLK_TCPWM0_CLOCKS7)},
{PWM32(P8_1), PWM_32b_0, CY_PIN_OUT_FUNCTION(P8_1_TCPWM0_LINE_COMPL0, PCLK_TCPWM0_CLOCKS0)},
{PWM32(P8_3), PWM_32b_1, CY_PIN_OUT_FUNCTION(P8_3_TCPWM0_LINE_COMPL1, PCLK_TCPWM0_CLOCKS1)},
{PWM32(P8_5), PWM_32b_2, CY_PIN_OUT_FUNCTION(P8_5_TCPWM0_LINE_COMPL2, PCLK_TCPWM0_CLOCKS2)},
{PWM32(P8_7), PWM_32b_3, CY_PIN_OUT_FUNCTION(P8_7_TCPWM0_LINE_COMPL3, PCLK_TCPWM0_CLOCKS3)},
{PWM32(P9_1), PWM_32b_4, CY_PIN_OUT_FUNCTION(P9_1_TCPWM0_LINE_COMPL4, PCLK_TCPWM0_CLOCKS4)},
{PWM32(P9_3), PWM_32b_5, CY_PIN_OUT_FUNCTION(P9_3_TCPWM0_LINE_COMPL5, PCLK_TCPWM0_CLOCKS5)},
{PWM32(P9_5), PWM_32b_7, CY_PIN_OUT_FUNCTION(P9_5_TCPWM0_LINE_COMPL7, PCLK_TCPWM0_CLOCKS7)},
{PWM32(P9_7), PWM_32b_0, CY_PIN_OUT_FUNCTION(P9_7_TCPWM0_LINE_COMPL0, PCLK_TCPWM0_CLOCKS0)},
{PWM32(P10_1), PWM_32b_6, CY_PIN_OUT_FUNCTION(P10_1_TCPWM0_LINE_COMPL6, PCLK_TCPWM0_CLOCKS6)},
{PWM32(P10_3), PWM_32b_7, CY_PIN_OUT_FUNCTION(P10_3_TCPWM0_LINE_COMPL7, PCLK_TCPWM0_CLOCKS7)},
{PWM32(P10_5), PWM_32b_0, CY_PIN_OUT_FUNCTION(P10_5_TCPWM0_LINE_COMPL0, PCLK_TCPWM0_CLOCKS0)},
{PWM32(P11_1), PWM_32b_1, CY_PIN_OUT_FUNCTION(P11_1_TCPWM0_LINE_COMPL1, PCLK_TCPWM0_CLOCKS1)},
{PWM32(P11_3), PWM_32b_2, CY_PIN_OUT_FUNCTION(P11_3_TCPWM0_LINE_COMPL2, PCLK_TCPWM0_CLOCKS2)},
{PWM32(P11_5), PWM_32b_3, CY_PIN_OUT_FUNCTION(P11_5_TCPWM0_LINE_COMPL3, PCLK_TCPWM0_CLOCKS3)},
{PWM32(P12_1), PWM_32b_4, CY_PIN_OUT_FUNCTION(P12_1_TCPWM0_LINE_COMPL4, PCLK_TCPWM0_CLOCKS4)},
{PWM32(P12_3), PWM_32b_5, CY_PIN_OUT_FUNCTION(P12_3_TCPWM0_LINE_COMPL5, PCLK_TCPWM0_CLOCKS5)},
{PWM32(P12_5), PWM_32b_6, CY_PIN_OUT_FUNCTION(P12_5_TCPWM0_LINE_COMPL6, PCLK_TCPWM0_CLOCKS6)},
{PWM32(P12_7), PWM_32b_7, CY_PIN_OUT_FUNCTION(P12_7_TCPWM0_LINE_COMPL7, PCLK_TCPWM0_CLOCKS7)},
{PWM32(P13_1), PWM_32b_0, CY_PIN_OUT_FUNCTION(P13_1_TCPWM0_LINE_COMPL0, PCLK_TCPWM0_CLOCKS0)},
{PWM32(P13_7), PWM_32b_3, CY_PIN_OUT_FUNCTION(P13_7_TCPWM0_LINE_COMPL3, PCLK_TCPWM0_CLOCKS3)},
{NC, NC, 0}
};
#endif // DEVICE_PWMOUT
#if DEVICE_ANALOGIN
const PinMap PinMap_ADC[] = {
{P10_0, ADC_0, CY_PIN_ANALOG_FUNCTION(PCLK_PASS_CLOCK_SAR)},
{P10_1, ADC_0, CY_PIN_ANALOG_FUNCTION(PCLK_PASS_CLOCK_SAR)},
{P10_2, ADC_0, CY_PIN_ANALOG_FUNCTION(PCLK_PASS_CLOCK_SAR)},
{P10_3, ADC_0, CY_PIN_ANALOG_FUNCTION(PCLK_PASS_CLOCK_SAR)},
{P10_4, ADC_0, CY_PIN_ANALOG_FUNCTION(PCLK_PASS_CLOCK_SAR)},
{P10_5, ADC_0, CY_PIN_ANALOG_FUNCTION(PCLK_PASS_CLOCK_SAR)},
{P10_6, ADC_0, CY_PIN_ANALOG_FUNCTION(PCLK_PASS_CLOCK_SAR)},
{P10_7, ADC_0, CY_PIN_ANALOG_FUNCTION(PCLK_PASS_CLOCK_SAR)},
{NC, NC, 0}
};
#endif // DEVICE_ANALOGIN
#if DEVICE_ANALOGOUT
const PinMap PinMap_DAC[] = {
{P9_6, DAC_0, CY_PIN_ANALOG_FUNCTION(PCLK_PASS_CLOCK_CTDAC)},
{NC, NC, 0}
};
#endif // DEVICE_ANALOGIN

View File

@ -0,0 +1,5 @@
README for Cypress Peripheral Driver Library
============================================
This folder tree contains parts (binary-only libraries and M0/M4 core specific files) of Cypress Peripheral Driver Library (PDL) necessary to support PSoC 6 MCUs. Library names have been changed (vs. standard PDL version) by prepending a "lib" prefix to fit Mbed OS build system conventions.
See [Cypress PDL page](http://www.cypress.com/documentation/software-and-drivers/peripheral-driver-library-pdl) for details.

View File

@ -0,0 +1,207 @@
#! armcc -E
; The first line specifies a preprocessor command that the linker invokes
; to pass a scatter file through a C preprocessor.
;*******************************************************************************
;* \file cy8c6xx7_cm0plus.scat
;* \version 2.10
;*
;* Linker file for the ARMCC.
;*
;* The main purpose of the linker script is to describe how the sections in the
;* input files should be mapped into the output file, and to control the memory
;* layout of the output file.
;*
;* \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 the warnings
;* during the build process: L6314W (no section matches pattern) and/or L6329W
;* (pattern only matches removed unused sections). In your project, you can
;* suppress the warning by passing the "--diag_suppress=L6314W,L6329W" option to
;* the linker, simply comment out or remove the relevant code in the linker
;* file.
;*
;*******************************************************************************
;* \copyright
;* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
;* SPDX-License-Identifier: Apache-2.0
;******************************************************************************/
; The defines below describe the location and size of blocks of memory in the target.
; Use these defines to specify the memory regions available for allocation.
; The following defines control RAM and flash memory allocation for the CM0+ core.
; You can change the memory allocation by editing the RAM and Flash defines.
; Your changes must be aligned with the corresponding defines for the CM4 core in 'xx_cm4_dual.scat',
; where 'xx' is the device group; for example, 'cy8c6xx7_cm4_dual.scat'.
; RAM
; RAM
#define RAM_START 0x08000000
#define RAM_SIZE 0x00010000
; Flash
; Flash
#define FLASH_START 0x10000000
#define FLASH_SIZE 0x00078000
; The following defines describe a 32K flash region used for EEPROM emulation.
; This region can also be used as the general purpose flash.
; You can assign sections to this memory region for only one of the cores.
; Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region.
; Therefore, repurposing this memory region will prevent such middleware from operation.
#define EM_EEPROM_START 0x14000000
#define EM_EEPROM_SIZE 0x8000
; The following defines describe device specific memory regions and must not be changed.
; Supervisory flash: User data
#define SFLASH_USER_DATA_START 0x16000800
#define SFLASH_USER_DATA_SIZE 0x00000800
; Supervisory flash: Normal Access Restrictions (NAR)
#define SFLASH_NAR_START 0x16001A00
#define SFLASH_NAR_SIZE 0x00000200
; Supervisory flash: Public Key
#define SFLASH_PUBLIC_KEY_START 0x16005A00
#define SFLASH_PUBLIC_KEY_SIZE 0x00000C00
; Supervisory flash: Table of Content # 2
#define SFLASH_TOC_2_START 0x16007C00
#define SFLASH_TOC_2_SIZE 0x00000200
; Supervisory flash: Table of Content # 2 Copy
#define SFLASH_RTOC_2_START 0x16007E00
#define SFLASH_RTOC_2_SIZE 0x00000200
; External memory
#define XIP_START 0x18000000
#define XIP_SIZE 0x08000000
; eFuse
#define EFUSE_START 0x90700000
#define EFUSE_SIZE 0x100000
LR_IROM1 FLASH_START FLASH_SIZE
{
.cy_app_header +0
{
* (.cy_app_header)
}
ER_FLASH_VECTORS +0
{
* (RESET, +FIRST)
}
ER_FLASH_CODE +0 FIXED
{
* (InRoot$$Sections)
* (+RO)
}
ER_RAM_VECTORS RAM_START UNINIT
{
* (RESET_RAM, +FIRST)
}
RW_RAM_DATA +0
{
* (.cy_ramfunc)
.ANY (+RW, +ZI)
}
; Place variables in the section that should not be initialized during the
; device startup.
RW_IRAM1 +0 UNINIT
{
* (.noinit)
}
}
; Emulated EEPROM Flash area
LR_EM_EEPROM EM_EEPROM_START EM_EEPROM_SIZE
{
.cy_em_eeprom +0
{
* (.cy_em_eeprom)
}
}
; Supervisory flash: User data
LR_SFLASH_USER_DATA SFLASH_USER_DATA_START SFLASH_USER_DATA_SIZE
{
.cy_sflash_user_data +0
{
* (.cy_sflash_user_data)
}
}
; Supervisory flash: Normal Access Restrictions (NAR)
LR_SFLASH_NAR SFLASH_NAR_START SFLASH_NAR_SIZE
{
.cy_sflash_nar +0
{
* (.cy_sflash_nar)
}
}
; Supervisory flash: Public Key
LR_SFLASH_PUBLIC_KEY SFLASH_PUBLIC_KEY_START SFLASH_PUBLIC_KEY_SIZE
{
.cy_sflash_public_key +0
{
* (.cy_sflash_public_key)
}
}
; Supervisory flash: Table of Content # 2
LR_SFLASH_TOC_2 SFLASH_TOC_2_START SFLASH_TOC_2_SIZE
{
.cy_toc_part2 +0
{
* (.cy_toc_part2)
}
}
; Supervisory flash: Table of Content # 2 Copy
LR_SFLASH_RTOC_2 SFLASH_RTOC_2_START SFLASH_RTOC_2_SIZE
{
.cy_rtoc_part2 +0
{
* (.cy_rtoc_part2)
}
}
; Places the code in the Execute in Place (XIP) section. See the smif driver documentation for details.
LR_EROM XIP_START XIP_SIZE
{
.cy_xip +0
{
* (.cy_xip)
}
}
; eFuse
LR_EFUSE EFUSE_START EFUSE_SIZE
{
.cy_efuse +0
{
* (.cy_efuse)
}
}
; The section is used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage.
CYMETA 0x90500000
{
.cymeta +0 { * (.cymeta) }
}
/* [] END OF FILE */

View File

@ -0,0 +1,279 @@
;/**************************************************************************//**
; * @file startup_psoc63_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.
; */
;/*
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
;*/
__initial_sp EQU 0x08010000
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD 0x0000000D ; NMI Handler located at ROM code
DCD HardFault_Handler ; Hard Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External interrupts Description
DCD NvicMux0_IRQHandler ; CM0 + NVIC Mux input 0
DCD NvicMux1_IRQHandler ; CM0 + NVIC Mux input 1
DCD NvicMux2_IRQHandler ; CM0 + NVIC Mux input 2
DCD NvicMux3_IRQHandler ; CM0 + NVIC Mux input 3
DCD NvicMux4_IRQHandler ; CM0 + NVIC Mux input 4
DCD NvicMux5_IRQHandler ; CM0 + NVIC Mux input 5
DCD NvicMux6_IRQHandler ; CM0 + NVIC Mux input 6
DCD NvicMux7_IRQHandler ; CM0 + NVIC Mux input 7
DCD NvicMux8_IRQHandler ; CM0 + NVIC Mux input 8
DCD NvicMux9_IRQHandler ; CM0 + NVIC Mux input 9
DCD NvicMux10_IRQHandler ; CM0 + NVIC Mux input 10
DCD NvicMux11_IRQHandler ; CM0 + NVIC Mux input 11
DCD NvicMux12_IRQHandler ; CM0 + NVIC Mux input 12
DCD NvicMux13_IRQHandler ; CM0 + NVIC Mux input 13
DCD NvicMux14_IRQHandler ; CM0 + NVIC Mux input 14
DCD NvicMux15_IRQHandler ; CM0 + NVIC Mux input 15
DCD NvicMux16_IRQHandler ; CM0 + NVIC Mux input 16
DCD NvicMux17_IRQHandler ; CM0 + NVIC Mux input 17
DCD NvicMux18_IRQHandler ; CM0 + NVIC Mux input 18
DCD NvicMux19_IRQHandler ; CM0 + NVIC Mux input 19
DCD NvicMux20_IRQHandler ; CM0 + NVIC Mux input 20
DCD NvicMux21_IRQHandler ; CM0 + NVIC Mux input 21
DCD NvicMux22_IRQHandler ; CM0 + NVIC Mux input 22
DCD NvicMux23_IRQHandler ; CM0 + NVIC Mux input 23
DCD NvicMux24_IRQHandler ; CM0 + NVIC Mux input 24
DCD NvicMux25_IRQHandler ; CM0 + NVIC Mux input 25
DCD NvicMux26_IRQHandler ; CM0 + NVIC Mux input 26
DCD NvicMux27_IRQHandler ; CM0 + NVIC Mux input 27
DCD NvicMux28_IRQHandler ; CM0 + NVIC Mux input 28
DCD NvicMux29_IRQHandler ; CM0 + NVIC Mux input 29
DCD NvicMux30_IRQHandler ; CM0 + NVIC Mux input 30
DCD NvicMux31_IRQHandler ; CM0 + NVIC Mux input 31
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
EXPORT __ramVectors
AREA RESET_RAM, READWRITE, NOINIT
__ramVectors SPACE __Vectors_Size
AREA |.text|, CODE, READONLY
; Saves and disables the interrupts
Cy_SaveIRQ PROC
EXPORT Cy_SaveIRQ
MRS r0, PRIMASK
CPSID I
BX LR
ENDP
; Restores the interrupts
Cy_RestoreIRQ PROC
EXPORT Cy_RestoreIRQ
MSR PRIMASK, r0
BX LR
ENDP
; Weak function for startup customization
Cy_OnResetUser PROC
EXPORT Cy_OnResetUser [WEAK]
BX LR
ENDP
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
; Define strong function for startup customization
BL Cy_OnResetUser
; Copy vectors from ROM to RAM
LDR r1, =__Vectors
LDR r0, =__ramVectors
LDR r2, =__Vectors_Size
Vectors_Copy
LDR r3, [r1]
STR r3, [r0]
ADDS r0, r0, #4
ADDS r1, r1, #4
SUBS r2, r2, #1
CMP r2, #0
BNE Vectors_Copy
; Update Vector Table Offset Register. */
LDR r0, =__ramVectors
LDR r1, =0xE000ED08
STR r0, [r1]
dsb 0xF
LDR R0, =__main
BLX R0
; Should never get here
B .
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
Cy_SysLib_FaultHandler PROC
EXPORT Cy_SysLib_FaultHandler [WEAK]
B .
ENDP
HardFault_Handler PROC
EXPORT HardFault_Handler [WEAK]
movs r0, #4
mov r1, LR
tst r0, r1
beq L_MSP
mrs r0, PSP
bl L_API_call
L_MSP
mrs r0, MSP
L_API_call
bl Cy_SysLib_FaultHandler
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
PendSV_Handler PROC
EXPORT PendSV_Handler [WEAK]
B .
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
Default_Handler PROC
EXPORT Default_Handler [WEAK]
EXPORT NvicMux0_IRQHandler [WEAK]
EXPORT NvicMux1_IRQHandler [WEAK]
EXPORT NvicMux2_IRQHandler [WEAK]
EXPORT NvicMux3_IRQHandler [WEAK]
EXPORT NvicMux4_IRQHandler [WEAK]
EXPORT NvicMux5_IRQHandler [WEAK]
EXPORT NvicMux6_IRQHandler [WEAK]
EXPORT NvicMux7_IRQHandler [WEAK]
EXPORT NvicMux8_IRQHandler [WEAK]
EXPORT NvicMux9_IRQHandler [WEAK]
EXPORT NvicMux10_IRQHandler [WEAK]
EXPORT NvicMux11_IRQHandler [WEAK]
EXPORT NvicMux12_IRQHandler [WEAK]
EXPORT NvicMux13_IRQHandler [WEAK]
EXPORT NvicMux14_IRQHandler [WEAK]
EXPORT NvicMux15_IRQHandler [WEAK]
EXPORT NvicMux16_IRQHandler [WEAK]
EXPORT NvicMux17_IRQHandler [WEAK]
EXPORT NvicMux18_IRQHandler [WEAK]
EXPORT NvicMux19_IRQHandler [WEAK]
EXPORT NvicMux20_IRQHandler [WEAK]
EXPORT NvicMux21_IRQHandler [WEAK]
EXPORT NvicMux22_IRQHandler [WEAK]
EXPORT NvicMux23_IRQHandler [WEAK]
EXPORT NvicMux24_IRQHandler [WEAK]
EXPORT NvicMux25_IRQHandler [WEAK]
EXPORT NvicMux26_IRQHandler [WEAK]
EXPORT NvicMux27_IRQHandler [WEAK]
EXPORT NvicMux28_IRQHandler [WEAK]
EXPORT NvicMux29_IRQHandler [WEAK]
EXPORT NvicMux30_IRQHandler [WEAK]
EXPORT NvicMux31_IRQHandler [WEAK]
NvicMux0_IRQHandler
NvicMux1_IRQHandler
NvicMux2_IRQHandler
NvicMux3_IRQHandler
NvicMux4_IRQHandler
NvicMux5_IRQHandler
NvicMux6_IRQHandler
NvicMux7_IRQHandler
NvicMux8_IRQHandler
NvicMux9_IRQHandler
NvicMux10_IRQHandler
NvicMux11_IRQHandler
NvicMux12_IRQHandler
NvicMux13_IRQHandler
NvicMux14_IRQHandler
NvicMux15_IRQHandler
NvicMux16_IRQHandler
NvicMux17_IRQHandler
NvicMux18_IRQHandler
NvicMux19_IRQHandler
NvicMux20_IRQHandler
NvicMux21_IRQHandler
NvicMux22_IRQHandler
NvicMux23_IRQHandler
NvicMux24_IRQHandler
NvicMux25_IRQHandler
NvicMux26_IRQHandler
NvicMux27_IRQHandler
NvicMux28_IRQHandler
NvicMux29_IRQHandler
NvicMux30_IRQHandler
NvicMux31_IRQHandler
B .
ENDP
ALIGN
END
; [] END OF FILE

View File

@ -0,0 +1,393 @@
/***************************************************************************//**
* \file cy8c6xx7_cm0plus.ld
* \version 2.10
*
* Linker file for the GNU C compiler.
*
* The main purpose of the linker script is to describe how the sections in the
* input files should be mapped into the output file, and to control the memory
* layout of the output file.
*
* \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-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
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)
/* The MEMORY section below describes the location and size of blocks of memory in the target.
* Use this section to specify the memory regions available for allocation.
*/
MEMORY
{
/* The ram and flash regions control RAM and flash memory allocation for the CM0+ core.
* You can change the memory allocation by editing the 'ram' and 'flash' regions.
* Your changes must be aligned with the corresponding memory regions for the CM4 core in 'xx_cm4_dual.ld',
* where 'xx' is the device group; for example, 'cy8c6xx7_cm4_dual.ld'.
*/
ram (rwx) : ORIGIN = 0x08000000, LENGTH = 0x10000
flash (rx) : ORIGIN = 0x10000000, LENGTH = 0x78000
/* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash.
* You can assign sections to this memory region for only one of the cores.
* Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region.
* Therefore, repurposing this memory region will prevent such middleware from operation.
*/
em_eeprom (rx) : ORIGIN = 0x14000000, LENGTH = 0x8000 /* 32 KB */
/* The following regions define device specific memory regions and must not be changed. */
sflash_user_data (rx) : ORIGIN = 0x16000800, LENGTH = 0x800 /* Supervisory flash: User data */
sflash_nar (rx) : ORIGIN = 0x16001A00, LENGTH = 0x200 /* Supervisory flash: Normal Access Restrictions (NAR) */
sflash_public_key (rx) : ORIGIN = 0x16005A00, LENGTH = 0xC00 /* Supervisory flash: Public Key */
sflash_toc_2 (rx) : ORIGIN = 0x16007C00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 */
sflash_rtoc_2 (rx) : ORIGIN = 0x16007E00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 Copy */
xip (rx) : ORIGIN = 0x18000000, LENGTH = 0x8000000 /* 128 MB */
efuse (r) : ORIGIN = 0x90700000, LENGTH = 0x100000 /* 1 MB */
}
/* 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
*/
SECTIONS
{
.cy_app_header :
{
KEEP(*(.cy_app_header))
} > flash
.text :
{
. = 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*))
/* To copy multiple ROM to RAM sections,
* uncomment copy table section and,
* define __STARTUP_COPY_MULTIPLE in startup_psoc63_cm4.S */
. = 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__ = .;
/* To clear multiple BSS sections,
* uncomment zero table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_psoc63_cm4.S */
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
__zero_table_end__ = .;
} > flash
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > flash
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > flash
__exidx_end = .;
__etext = . ;
.ramVectors (NOLOAD) : ALIGN(8)
{
__ram_vectors_start__ = .;
KEEP(*(.ram_vectors))
__ram_vectors_end__ = .;
} > ram
.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);
KEEP(*(.cy_ramfunc*))
. = ALIGN(4);
__data_end__ = .;
} > ram
/* Place variables in the section that should not be initialized during the
* device startup.
*/
.noinit (NOLOAD) : ALIGN(8)
{
KEEP(*(.noinit))
} > ram
/* 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
.heap (NOLOAD):
{
__HeapBase = .;
__end__ = .;
end = __end__;
KEEP(*(.heap*))
__HeapLimit = .;
} > ram
/* .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
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(ram) + LENGTH(ram);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
/* Emulated EEPROM Flash area */
.cy_em_eeprom :
{
KEEP(*(.cy_em_eeprom))
} > em_eeprom
/* Supervisory Flash: User data */
.cy_sflash_user_data :
{
KEEP(*(.cy_sflash_user_data))
} > sflash_user_data
/* Supervisory Flash: Normal Access Restrictions (NAR) */
.cy_sflash_nar :
{
KEEP(*(.cy_sflash_nar))
} > sflash_nar
/* Supervisory Flash: Public Key */
.cy_sflash_public_key :
{
KEEP(*(.cy_sflash_public_key))
} > sflash_public_key
/* Supervisory Flash: Table of Content # 2 */
.cy_toc_part2 :
{
KEEP(*(.cy_toc_part2))
} > sflash_toc_2
/* Supervisory Flash: Table of Content # 2 Copy */
.cy_rtoc_part2 :
{
KEEP(*(.cy_rtoc_part2))
} > sflash_rtoc_2
/* Places the code in the Execute in Place (XIP) section. See the smif driver
* documentation for details.
*/
.cy_xip :
{
KEEP(*(.cy_xip))
} > xip
/* eFuse */
.cy_efuse :
{
KEEP(*(.cy_efuse))
} > efuse
/* These sections are used for additional metadata (silicon revision,
* Silicon/JTAG ID, etc.) storage.
*/
.cymeta 0x90500000 : { KEEP(*(.cymeta)) } :NONE
}
/* The following symbols used by the cymcuelftool. */
/* Flash */
__cy_memory_0_start = 0x10000000;
__cy_memory_0_length = 0x00100000;
__cy_memory_0_row_size = 0x200;
/* Emulated EEPROM Flash area */
__cy_memory_1_start = 0x14000000;
__cy_memory_1_length = 0x8000;
__cy_memory_1_row_size = 0x200;
/* Supervisory Flash */
__cy_memory_2_start = 0x16000000;
__cy_memory_2_length = 0x8000;
__cy_memory_2_row_size = 0x200;
/* XIP */
__cy_memory_3_start = 0x18000000;
__cy_memory_3_length = 0x08000000;
__cy_memory_3_row_size = 0x200;
/* eFuse */
__cy_memory_4_start = 0x90700000;
__cy_memory_4_length = 0x100000;
__cy_memory_4_row_size = 1;
/* EOF */

View File

@ -0,0 +1,415 @@
/**************************************************************************//**
* @file startup_psoc63_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 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 Description */
.long NvicMux0_IRQHandler /* CM0 + NVIC Mux input 0 */
.long NvicMux1_IRQHandler /* CM0 + NVIC Mux input 1 */
.long NvicMux2_IRQHandler /* CM0 + NVIC Mux input 2 */
.long NvicMux3_IRQHandler /* CM0 + NVIC Mux input 3 */
.long NvicMux4_IRQHandler /* CM0 + NVIC Mux input 4 */
.long NvicMux5_IRQHandler /* CM0 + NVIC Mux input 5 */
.long NvicMux6_IRQHandler /* CM0 + NVIC Mux input 6 */
.long NvicMux7_IRQHandler /* CM0 + NVIC Mux input 7 */
.long NvicMux8_IRQHandler /* CM0 + NVIC Mux input 8 */
.long NvicMux9_IRQHandler /* CM0 + NVIC Mux input 9 */
.long NvicMux10_IRQHandler /* CM0 + NVIC Mux input 10 */
.long NvicMux11_IRQHandler /* CM0 + NVIC Mux input 11 */
.long NvicMux12_IRQHandler /* CM0 + NVIC Mux input 12 */
.long NvicMux13_IRQHandler /* CM0 + NVIC Mux input 13 */
.long NvicMux14_IRQHandler /* CM0 + NVIC Mux input 14 */
.long NvicMux15_IRQHandler /* CM0 + NVIC Mux input 15 */
.long NvicMux16_IRQHandler /* CM0 + NVIC Mux input 16 */
.long NvicMux17_IRQHandler /* CM0 + NVIC Mux input 17 */
.long NvicMux18_IRQHandler /* CM0 + NVIC Mux input 18 */
.long NvicMux19_IRQHandler /* CM0 + NVIC Mux input 19 */
.long NvicMux20_IRQHandler /* CM0 + NVIC Mux input 20 */
.long NvicMux21_IRQHandler /* CM0 + NVIC Mux input 21 */
.long NvicMux22_IRQHandler /* CM0 + NVIC Mux input 22 */
.long NvicMux23_IRQHandler /* CM0 + NVIC Mux input 23 */
.long NvicMux24_IRQHandler /* CM0 + NVIC Mux input 24 */
.long NvicMux25_IRQHandler /* CM0 + NVIC Mux input 25 */
.long NvicMux26_IRQHandler /* CM0 + NVIC Mux input 26 */
.long NvicMux27_IRQHandler /* CM0 + NVIC Mux input 27 */
.long NvicMux28_IRQHandler /* CM0 + NVIC Mux input 28 */
.long NvicMux29_IRQHandler /* CM0 + NVIC Mux input 29 */
.long NvicMux30_IRQHandler /* CM0 + NVIC Mux input 30 */
.long NvicMux31_IRQHandler /* CM0 + NVIC Mux input 31 */
.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
/* 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
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 NvicMux0_IRQHandler /* CM0 + NVIC Mux input 0 */
def_irq_handler NvicMux1_IRQHandler /* CM0 + NVIC Mux input 1 */
def_irq_handler NvicMux2_IRQHandler /* CM0 + NVIC Mux input 2 */
def_irq_handler NvicMux3_IRQHandler /* CM0 + NVIC Mux input 3 */
def_irq_handler NvicMux4_IRQHandler /* CM0 + NVIC Mux input 4 */
def_irq_handler NvicMux5_IRQHandler /* CM0 + NVIC Mux input 5 */
def_irq_handler NvicMux6_IRQHandler /* CM0 + NVIC Mux input 6 */
def_irq_handler NvicMux7_IRQHandler /* CM0 + NVIC Mux input 7 */
def_irq_handler NvicMux8_IRQHandler /* CM0 + NVIC Mux input 8 */
def_irq_handler NvicMux9_IRQHandler /* CM0 + NVIC Mux input 9 */
def_irq_handler NvicMux10_IRQHandler /* CM0 + NVIC Mux input 10 */
def_irq_handler NvicMux11_IRQHandler /* CM0 + NVIC Mux input 11 */
def_irq_handler NvicMux12_IRQHandler /* CM0 + NVIC Mux input 12 */
def_irq_handler NvicMux13_IRQHandler /* CM0 + NVIC Mux input 13 */
def_irq_handler NvicMux14_IRQHandler /* CM0 + NVIC Mux input 14 */
def_irq_handler NvicMux15_IRQHandler /* CM0 + NVIC Mux input 15 */
def_irq_handler NvicMux16_IRQHandler /* CM0 + NVIC Mux input 16 */
def_irq_handler NvicMux17_IRQHandler /* CM0 + NVIC Mux input 17 */
def_irq_handler NvicMux18_IRQHandler /* CM0 + NVIC Mux input 18 */
def_irq_handler NvicMux19_IRQHandler /* CM0 + NVIC Mux input 19 */
def_irq_handler NvicMux20_IRQHandler /* CM0 + NVIC Mux input 20 */
def_irq_handler NvicMux21_IRQHandler /* CM0 + NVIC Mux input 21 */
def_irq_handler NvicMux22_IRQHandler /* CM0 + NVIC Mux input 22 */
def_irq_handler NvicMux23_IRQHandler /* CM0 + NVIC Mux input 23 */
def_irq_handler NvicMux24_IRQHandler /* CM0 + NVIC Mux input 24 */
def_irq_handler NvicMux25_IRQHandler /* CM0 + NVIC Mux input 25 */
def_irq_handler NvicMux26_IRQHandler /* CM0 + NVIC Mux input 26 */
def_irq_handler NvicMux27_IRQHandler /* CM0 + NVIC Mux input 27 */
def_irq_handler NvicMux28_IRQHandler /* CM0 + NVIC Mux input 28 */
def_irq_handler NvicMux29_IRQHandler /* CM0 + NVIC Mux input 29 */
def_irq_handler NvicMux30_IRQHandler /* CM0 + NVIC Mux input 30 */
def_irq_handler NvicMux31_IRQHandler /* CM0 + NVIC Mux input 31 */
.end
/* [] END OF FILE */

View File

@ -0,0 +1,216 @@
/***************************************************************************//**
* \file cy8c6xx7_cm0plus.icf
* \version 2.10
*
* Linker file for the IAR compiler.
*
* The main purpose of the linker script is to describe how the sections in the
* input files should be mapped into the output file, and to control the memory
* layout of the output file.
*
* \note The entry point 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-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/* The symbols below define the location and size of blocks of memory in the target.
* Use these symbols to specify the memory regions available for allocation.
*/
/* The following symbols control RAM and flash memory allocation for the CM0+ core.
* You can change the memory allocation by editing RAM and Flash symbols.
* Your changes must be aligned with the corresponding symbols for CM4 core in 'xx_cm4_dual.icf',
* where 'xx' is the device group; for example, 'cy8c6xx7_cm4_dual.icf'.
*/
/* RAM */
define symbol __ICFEDIT_region_IRAM1_start__ = 0x08000000;
define symbol __ICFEDIT_region_IRAM1_end__ = 0x08010000;
/* Flash */
define symbol __ICFEDIT_region_IROM1_start__ = 0x10000000;
define symbol __ICFEDIT_region_IROM1_end__ = 0x10078000;
/* The following symbols define a 32K flash region used for EEPROM emulation.
* This region can also be used as the general purpose flash.
* You can assign sections to this memory region for only one of the cores.
* Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region.
* Therefore, repurposing this memory region will prevent such middleware from operation.
*/
define symbol __ICFEDIT_region_IROM2_start__ = 0x14000000;
define symbol __ICFEDIT_region_IROM2_end__ = 0x14007FFF;
/* The following symbols define device specific memory regions and must not be changed. */
/* Supervisory FLASH - User Data */
define symbol __ICFEDIT_region_IROM3_start__ = 0x16000800;
define symbol __ICFEDIT_region_IROM3_end__ = 0x160007FF;
/* Supervisory FLASH - Normal Access Restrictions (NAR) */
define symbol __ICFEDIT_region_IROM4_start__ = 0x16001A00;
define symbol __ICFEDIT_region_IROM4_end__ = 0x16001BFF;
/* Supervisory FLASH - Public Key */
define symbol __ICFEDIT_region_IROM5_start__ = 0x16005A00;
define symbol __ICFEDIT_region_IROM5_end__ = 0x160065FF;
/* Supervisory FLASH - Table of Content # 2 */
define symbol __ICFEDIT_region_IROM6_start__ = 0x16007C00;
define symbol __ICFEDIT_region_IROM6_end__ = 0x16007DFF;
/* Supervisory FLASH - Table of Content # 2 Copy */
define symbol __ICFEDIT_region_IROM7_start__ = 0x16007E00;
define symbol __ICFEDIT_region_IROM7_end__ = 0x16007FFF;
/* eFuse */
define symbol __ICFEDIT_region_IROM8_start__ = 0x90700000;
define symbol __ICFEDIT_region_IROM8_end__ = 0x907FFFFF;
/* XIP */
define symbol __ICFEDIT_region_EROM1_start__ = 0x18000000;
define symbol __ICFEDIT_region_EROM1_end__ = 0x1FFFFFFF;
define symbol __ICFEDIT_region_EROM2_start__ = 0x0;
define symbol __ICFEDIT_region_EROM2_end__ = 0x0;
define symbol __ICFEDIT_region_EROM3_start__ = 0x0;
define symbol __ICFEDIT_region_EROM3_end__ = 0x0;
define symbol __ICFEDIT_region_IRAM2_start__ = 0x0;
define symbol __ICFEDIT_region_IRAM2_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM1_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM1_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM2_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM2_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM3_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM3_end__ = 0x0;
/*-Sizes-*/
if (!isdefinedsymbol(__STACK_SIZE)) {
define symbol __ICFEDIT_size_cstack__ = 0x1000;
} else {
define symbol __ICFEDIT_size_cstack__ = __STACK_SIZE;
}
define symbol __ICFEDIT_size_proc_stack__ = 0x0;
if (!isdefinedsymbol(__HEAP_SIZE)) {
define symbol __ICFEDIT_size_heap__ = 0x4000;
} else {
define symbol __ICFEDIT_size_heap__ = __HEAP_SIZE;
}
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__];
define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__];
define region IROM3_region = mem:[from __ICFEDIT_region_IROM3_start__ to __ICFEDIT_region_IROM3_end__];
define region IROM4_region = mem:[from __ICFEDIT_region_IROM4_start__ to __ICFEDIT_region_IROM4_end__];
define region IROM5_region = mem:[from __ICFEDIT_region_IROM5_start__ to __ICFEDIT_region_IROM5_end__];
define region IROM6_region = mem:[from __ICFEDIT_region_IROM6_start__ to __ICFEDIT_region_IROM6_end__];
define region IROM7_region = mem:[from __ICFEDIT_region_IROM7_start__ to __ICFEDIT_region_IROM7_end__];
define region IROM8_region = mem:[from __ICFEDIT_region_IROM8_start__ to __ICFEDIT_region_IROM8_end__];
define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__];
define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
define block HSTACK {block HEAP, block PROC_STACK, last block CSTACK};
define block RO {first section .intvec, readonly};
/*-Initializations-*/
initialize by copy { readwrite };
do not initialize { section .noinit, section .intvec_ram };
/*-Placement-*/
/* Flash */
".cy_app_header" : place at start of IROM1_region { section .cy_app_header };
place in IROM1_region { block RO };
/* Emulated EEPROM Flash area */
".cy_em_eeprom" : place at start of IROM2_region { section .cy_em_eeprom };
/* Supervisory Flash - User Data */
".cy_sflash_user_data" : place at start of IROM3_region { section .cy_sflash_user_data };
/* Supervisory Flash - NAR */
".cy_sflash_nar" : place at start of IROM4_region { section .cy_sflash_nar };
/* Supervisory Flash - Public Key */
".cy_sflash_public_key" : place at start of IROM5_region { section .cy_sflash_public_key };
/* Supervisory Flash - TOC2 */
".cy_toc_part2" : place at start of IROM6_region { section .cy_toc_part2 };
/* Supervisory Flash - RTOC2 */
".cy_rtoc_part2" : place at start of IROM7_region { section .cy_rtoc_part2 };
/* eFuse */
".cy_efuse" : place at start of IROM8_region { section .cy_efuse };
/* Execute in Place (XIP). See the smif driver documentation for details. */
".cy_xip" : place at start of EROM1_region { section .cy_xip };
/* RAM */
place at start of IRAM1_region { readwrite section .intvec_ram};
place in IRAM1_region { readwrite };
place at end of IRAM1_region { block HSTACK };
/* These sections are used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. */
".cymeta" : place at address mem : 0x90500000 { readonly section .cymeta };
keep { section .cy_app_header,
section .cy_em_eeprom,
section .cy_sflash_user_data,
section .cy_sflash_nar,
section .cy_sflash_public_key,
section .cy_toc_part2,
section .cy_rtoc_part2,
section .cy_efuse,
section .cy_xip,
section .cymeta,
};
/* The following symbols used by the cymcuelftool. */
/* Flash */
define exported symbol __cy_memory_0_start = 0x10000000;
define exported symbol __cy_memory_0_length = 0x00100000;
define exported symbol __cy_memory_0_row_size = 0x200;
/* Emulated EEPROM Flash area */
define exported symbol __cy_memory_1_start = 0x14000000;
define exported symbol __cy_memory_1_length = 0x8000;
define exported symbol __cy_memory_1_row_size = 0x200;
/* Supervisory Flash */
define exported symbol __cy_memory_2_start = 0x16000000;
define exported symbol __cy_memory_2_length = 0x8000;
define exported symbol __cy_memory_2_row_size = 0x200;
/* XIP */
define exported symbol __cy_memory_3_start = 0x18000000;
define exported symbol __cy_memory_3_length = 0x08000000;
define exported symbol __cy_memory_3_row_size = 0x200;
/* eFuse */
define exported symbol __cy_memory_4_start = 0x90700000;
define exported symbol __cy_memory_4_length = 0x100000;
define exported symbol __cy_memory_4_row_size = 1;
/* EOF */

View File

@ -0,0 +1,417 @@
;/**************************************************************************//**
; * @file startup_psoc63_cm0plus.s
; * @brief CMSIS Core Device Startup File for
; * ARMCM0plus Device Series
; * @version V5.00
; * @date 08. 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.
; */
;
; The modules in this file are included in the libraries, and may be replaced
; by any user-defined modules that define the PUBLIC symbol _program_start or
; a user defined start symbol.
; To override the cstartup defined in the library, simply add your modified
; version to the workbench project.
;
; The vector table is normally located at address 0.
; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
; The name "__vector_table" has special meaning for C-SPY:
; it is where the SP start value is found, and the NVIC vector
; table register (VTOR) is initialized to this address if != 0.
;
; Cortex-M version
;
MODULE ?cstartup
;; Forward declaration of sections.
SECTION CSTACK:DATA:NOROOT(3)
SECTION .intvec_ram:DATA:NOROOT(2)
SECTION .intvec:CODE:NOROOT(2)
EXTERN __iar_program_start
PUBLIC __vector_table
PUBLIC __vector_table_0x1c
PUBLIC __Vectors
PUBLIC __Vectors_End
PUBLIC __Vectors_Size
PUBLIC __ramVectors
DATA
__vector_table
DCD sfe(CSTACK)
DCD Reset_Handler
DCD 0x0000000D ; NMI_Handler is defined in ROM code
DCD HardFault_Handler
DCD 0
DCD 0
DCD 0
__vector_table_0x1c
DCD 0
DCD 0
DCD 0
DCD 0
DCD SVC_Handler
DCD 0
DCD 0
DCD PendSV_Handler
DCD SysTick_Handler
; External interrupts Power Mode Description
DCD NvicMux0_IRQHandler ; CM0 + NVIC Mux input 0
DCD NvicMux1_IRQHandler ; CM0 + NVIC Mux input 1
DCD NvicMux2_IRQHandler ; CM0 + NVIC Mux input 2
DCD NvicMux3_IRQHandler ; CM0 + NVIC Mux input 3
DCD NvicMux4_IRQHandler ; CM0 + NVIC Mux input 4
DCD NvicMux5_IRQHandler ; CM0 + NVIC Mux input 5
DCD NvicMux6_IRQHandler ; CM0 + NVIC Mux input 6
DCD NvicMux7_IRQHandler ; CM0 + NVIC Mux input 7
DCD NvicMux8_IRQHandler ; CM0 + NVIC Mux input 8
DCD NvicMux9_IRQHandler ; CM0 + NVIC Mux input 9
DCD NvicMux10_IRQHandler ; CM0 + NVIC Mux input 10
DCD NvicMux11_IRQHandler ; CM0 + NVIC Mux input 11
DCD NvicMux12_IRQHandler ; CM0 + NVIC Mux input 12
DCD NvicMux13_IRQHandler ; CM0 + NVIC Mux input 13
DCD NvicMux14_IRQHandler ; CM0 + NVIC Mux input 14
DCD NvicMux15_IRQHandler ; CM0 + NVIC Mux input 15
DCD NvicMux16_IRQHandler ; CM0 + NVIC Mux input 16
DCD NvicMux17_IRQHandler ; CM0 + NVIC Mux input 17
DCD NvicMux18_IRQHandler ; CM0 + NVIC Mux input 18
DCD NvicMux19_IRQHandler ; CM0 + NVIC Mux input 19
DCD NvicMux20_IRQHandler ; CM0 + NVIC Mux input 20
DCD NvicMux21_IRQHandler ; CM0 + NVIC Mux input 21
DCD NvicMux22_IRQHandler ; CM0 + NVIC Mux input 22
DCD NvicMux23_IRQHandler ; CM0 + NVIC Mux input 23
DCD NvicMux24_IRQHandler ; CM0 + NVIC Mux input 24
DCD NvicMux25_IRQHandler ; CM0 + NVIC Mux input 25
DCD NvicMux26_IRQHandler ; CM0 + NVIC Mux input 26
DCD NvicMux27_IRQHandler ; CM0 + NVIC Mux input 27
DCD NvicMux28_IRQHandler ; CM0 + NVIC Mux input 28
DCD NvicMux29_IRQHandler ; CM0 + NVIC Mux input 29
DCD NvicMux30_IRQHandler ; CM0 + NVIC Mux input 30
DCD NvicMux31_IRQHandler ; CM0 + NVIC Mux input 31
__Vectors_End
__Vectors EQU __vector_table
__Vectors_Size EQU __Vectors_End - __Vectors
SECTION .intvec_ram:DATA:REORDER:NOROOT(2)
__ramVectors
DS32 __Vectors_Size
THUMB
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Default handlers
;;
PUBWEAK Default_Handler
SECTION .text:CODE:REORDER:NOROOT(2)
Default_Handler
B Default_Handler
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Saves and disables the interrupts
;;
PUBLIC Cy_SaveIRQ
SECTION .text:CODE:REORDER:NOROOT(2)
Cy_SaveIRQ
MRS r0, PRIMASK
CPSID I
BX LR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Restores the interrupts
;;
PUBLIC Cy_RestoreIRQ
SECTION .text:CODE:REORDER:NOROOT(2)
Cy_RestoreIRQ
MSR PRIMASK, r0
BX LR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Weak function for startup customization
;;
PUBWEAK Cy_OnResetUser
SECTION .text:CODE:REORDER:NOROOT(2)
Cy_OnResetUser
BX LR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Default interrupt handlers.
;;
THUMB
PUBWEAK Reset_Handler
SECTION .text:CODE:REORDER:NOROOT(2)
Reset_Handler
; Define strong function for startup customization
LDR R0, =Cy_OnResetUser
BLX R0
; Copy vectors from ROM to RAM
LDR r1, =__vector_table
LDR r0, =__ramVectors
LDR r2, =__Vectors_Size
intvec_copy
LDR r3, [r1]
STR r3, [r0]
ADDS r0, r0, #4
ADDS r1, r1, #4
SUBS r2, r2, #1
CMP r2, #0
BNE intvec_copy
; Update Vector Table Offset Register
LDR r0, =__ramVectors
LDR r1, =0xE000ED08
STR r0, [r1]
dsb
LDR R0, =__iar_program_start
BLX R0
; Should never get here
Cy_Main_Exited
B Cy_Main_Exited
PUBWEAK NMI_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
NMI_Handler
B NMI_Handler
PUBWEAK Cy_SysLib_FaultHandler
SECTION .text:CODE:REORDER:NOROOT(1)
Cy_SysLib_FaultHandler
B Cy_SysLib_FaultHandler
PUBWEAK HardFault_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
HardFault_Handler
IMPORT Cy_SysLib_FaultHandler
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
; Storing LR content for Creator call stack trace
push {LR}
bl Cy_SysLib_FaultHandler
PUBWEAK SVC_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
SVC_Handler
B SVC_Handler
PUBWEAK PendSV_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
PendSV_Handler
B PendSV_Handler
PUBWEAK SysTick_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
SysTick_Handler
B SysTick_Handler
; External interrupts
PUBWEAK NvicMux0_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux0_IRQHandler
B NvicMux0_IRQHandler
PUBWEAK NvicMux1_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux1_IRQHandler
B NvicMux1_IRQHandler
PUBWEAK NvicMux2_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux2_IRQHandler
B NvicMux2_IRQHandler
PUBWEAK NvicMux3_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux3_IRQHandler
B NvicMux3_IRQHandler
PUBWEAK NvicMux4_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux4_IRQHandler
B NvicMux4_IRQHandler
PUBWEAK NvicMux5_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux5_IRQHandler
B NvicMux5_IRQHandler
PUBWEAK NvicMux6_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux6_IRQHandler
B NvicMux6_IRQHandler
PUBWEAK NvicMux7_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux7_IRQHandler
B NvicMux7_IRQHandler
PUBWEAK NvicMux8_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux8_IRQHandler
B NvicMux8_IRQHandler
PUBWEAK NvicMux9_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux9_IRQHandler
B NvicMux9_IRQHandler
PUBWEAK NvicMux10_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux10_IRQHandler
B NvicMux10_IRQHandler
PUBWEAK NvicMux11_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux11_IRQHandler
B NvicMux11_IRQHandler
PUBWEAK NvicMux12_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux12_IRQHandler
B NvicMux12_IRQHandler
PUBWEAK NvicMux13_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux13_IRQHandler
B NvicMux13_IRQHandler
PUBWEAK NvicMux14_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux14_IRQHandler
B NvicMux14_IRQHandler
PUBWEAK NvicMux15_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux15_IRQHandler
B NvicMux15_IRQHandler
PUBWEAK NvicMux16_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux16_IRQHandler
B NvicMux16_IRQHandler
PUBWEAK NvicMux17_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux17_IRQHandler
B NvicMux17_IRQHandler
PUBWEAK NvicMux18_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux18_IRQHandler
B NvicMux18_IRQHandler
PUBWEAK NvicMux19_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux19_IRQHandler
B NvicMux19_IRQHandler
PUBWEAK NvicMux20_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux20_IRQHandler
B NvicMux20_IRQHandler
PUBWEAK NvicMux21_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux21_IRQHandler
B NvicMux21_IRQHandler
PUBWEAK NvicMux22_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux22_IRQHandler
B NvicMux22_IRQHandler
PUBWEAK NvicMux23_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux23_IRQHandler
B NvicMux23_IRQHandler
PUBWEAK NvicMux24_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux24_IRQHandler
B NvicMux24_IRQHandler
PUBWEAK NvicMux25_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux25_IRQHandler
B NvicMux25_IRQHandler
PUBWEAK NvicMux26_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux26_IRQHandler
B NvicMux26_IRQHandler
PUBWEAK NvicMux27_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux27_IRQHandler
B NvicMux27_IRQHandler
PUBWEAK NvicMux28_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux28_IRQHandler
B NvicMux28_IRQHandler
PUBWEAK NvicMux29_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux29_IRQHandler
B NvicMux29_IRQHandler
PUBWEAK NvicMux30_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux30_IRQHandler
B NvicMux30_IRQHandler
PUBWEAK NvicMux31_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(1)
NvicMux31_IRQHandler
B NvicMux31_IRQHandler
END
; [] END OF FILE

View File

@ -0,0 +1,38 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "psoc6_utils.h"
#include "ipc_rpc.h"
#include "rpc_defs.h"
#include "cy_ipc_config.h"
#include "ipc/cy_ipc_pipe.h"
#define RPC_GEN RPC_GEN_IMPLEMENTATION
#include "rpc_api.h"
#undef RPC_GEN
void ipcrpc_init(void)
{
uint32_t rpc_counter = 0;
#define RPC_GEN RPC_GEN_INITIALIZATION
#include "rpc_api.h"
#undef RPC_GEN
}
/* [] END OF FILE */

View File

@ -0,0 +1,636 @@
/***************************************************************************//**
* \file system_psoc63_cm0plus.c
* \version 2.10
*
* The device system-source file.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* Copyright 2017-2018, Future Electronics
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "device.h"
#include "system_psoc63.h"
#include "cy_device_headers.h"
#include "ipc_rpc.h"
#include "psoc6_utils.h"
#if defined(CY_DEVICE_PSOC6ABLE2)
#if !defined(CY_PSOC6ABLE2_REV_0A_SUPPORT_DISABLE)
#include "syslib/cy_syslib.h"
#endif /* !defined(CY_PSOC6ABLE2_REV_0A_SUPPORT_DISABLE) */
#if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
#include "ipc/cy_ipc_drv.h"
#include "flash/cy_flash.h"
#endif /* !defined(CY_IPC_DEFAULT_CFG_DISABLE) */
#endif /* defined(CY_DEVICE_PSOC6ABLE2) */
/*******************************************************************************
* SystemCoreClockUpdate()
*******************************************************************************/
/** Default HFClk frequency in Hz */
#define CY_CLK_HFCLK0_FREQ_HZ_DEFAULT CY_CLK_HFCLK0_FREQ_HZ
/** Default PeriClk frequency in Hz */
#define CY_CLK_PERICLK_FREQ_HZ_DEFAULT CY_CLK_PERICLK_FREQ_HZ
/** Default SlowClk system core frequency in Hz */
#define CY_CLK_SYSTEM_FREQ_HZ_DEFAULT CY_CLK_SLOWCLK_FREQ_HZ
/**
* Holds the SlowClk (Cortex-M0+) or FastClk (Cortex-M4) system core clock,
* which is the system clock frequency supplied to the SysTick timer and the
* processor core clock.
* This variable implements CMSIS Core global variable.
* Refer to the [CMSIS documentation]
* (http://www.keil.com/pack/doc/CMSIS/Core/html/group__system__init__gr.html "System and Clock Configuration")
* for more details.
* 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_CLK_SYSTEM_FREQ_HZ_DEFAULT;
/** Holds the HFClk0 clock frequency. Updated by \ref SystemCoreClockUpdate(). */
uint32_t cy_Hfclk0FreqHz = CY_CLK_HFCLK0_FREQ_HZ_DEFAULT;
/** Holds the PeriClk clock frequency. Updated by \ref SystemCoreClockUpdate(). */
uint32_t cy_PeriClkFreqHz = CY_CLK_PERICLK_FREQ_HZ_DEFAULT;
/** Holds the Alternate high frequency clock in Hz. Updated by \ref SystemCoreClockUpdate(). */
#if defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL)
uint32_t cy_BleEcoClockFreqHz = CY_CLK_ALTHF_FREQ_HZ;
#endif /* defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL) */
/*******************************************************************************
* SystemInit()
*******************************************************************************/
/* WDT lock bits */
#define CY_WDT_LOCK_BIT0 ((uint32_t)0x01u << 30u)
#define CY_WDT_LOCK_BIT1 ((uint32_t)0x01u << 31u)
/* CLK_FLL_CONFIG default values */
#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)
/*******************************************************************************
* SystemCoreClockUpdate (void)
*******************************************************************************/
/* 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_CLK_SYSTEM_FREQ_HZ_DEFAULT;
uint32_t cy_delayFreqKhz = (CY_CLK_SYSTEM_FREQ_HZ_DEFAULT + CY_DELAY_1K_MINUS_1_THRESHOLD) /
CY_DELAY_1K_THRESHOLD;
uint8_t cy_delayFreqMhz = (uint8_t)((CY_CLK_SYSTEM_FREQ_HZ_DEFAULT + CY_DELAY_1M_MINUS_1_THRESHOLD) /
CY_DELAY_1M_THRESHOLD);
uint32_t cy_delay32kMs = CY_DELAY_MS_OVERFLOW_THRESHOLD *
((CY_CLK_SYSTEM_FREQ_HZ_DEFAULT + CY_DELAY_1K_MINUS_1_THRESHOLD) / CY_DELAY_1K_THRESHOLD);
#define CY_ROOT_PATH_SRC_IMO (0UL)
#define CY_ROOT_PATH_SRC_EXT (1UL)
#if (SRSS_ECO_PRESENT == 1U)
#define CY_ROOT_PATH_SRC_ECO (2UL)
#endif /* (SRSS_ECO_PRESENT == 1U) */
#if (SRSS_ALTHF_PRESENT == 1U)
#define CY_ROOT_PATH_SRC_ALTHF (3UL)
#endif /* (SRSS_ALTHF_PRESENT == 1U) */
#define CY_ROOT_PATH_SRC_DSI_MUX (4UL)
#define CY_ROOT_PATH_SRC_DSI_MUX_HVILO (16UL)
#define CY_ROOT_PATH_SRC_DSI_MUX_WCO (17UL)
#if (SRSS_ALTLF_PRESENT == 1U)
#define CY_ROOT_PATH_SRC_DSI_MUX_ALTLF (18UL)
#endif /* (SRSS_ALTLF_PRESENT == 1U) */
#if (SRSS_PILO_PRESENT == 1U)
#define CY_ROOT_PATH_SRC_DSI_MUX_PILO (19UL)
#endif /* (SRSS_PILO_PRESENT == 1U) */
/*******************************************************************************
* Cy_SysEnableCM4(), Cy_SysRetainCM4(), and Cy_SysResetCM4()
*******************************************************************************/
#define CY_SYS_CM4_PWR_CTL_KEY_OPEN (0x05FAUL)
#define CY_SYS_CM4_PWR_CTL_KEY_CLOSE (0xFA05UL)
/*******************************************************************************
* Function Name: mbed_sdk_init
****************************************************************************//**
*
* Mbed's post-memory-initialization function.
* Used here to initialize common parts of the Cypress libraries.
*
*******************************************************************************/
void mbed_sdk_init(void)
{
/* Initialize shared resource manager */
cy_srm_initialize();
/* Initialize system and clocks. */
/* Placed here as it must be done after proper LIBC initialization. */
SystemInit();
/* Allocate and initialize semaphores for the system operations. */
Cy_IPC_SystemSemaInit();
Cy_IPC_SystemPipeInit();
Cy_Flash_Init();
ipcrpc_init();
}
/*******************************************************************************
* Function Name: SystemInit
****************************************************************************//**
*
* Initializes the system:
* - Restores FLL registers to the default state.
* - Unlocks and disables WDT.
* - Calls the Cy_SystemInit() function, if compiled from PSoC Creator.
* - Calls \ref SystemCoreClockUpdate().
*
*******************************************************************************/
void SystemInit(void)
{
/* Restore FLL registers to the default state as they are not restored by the 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();
#if defined(CY_DEVICE_PSOC6ABLE2)
#if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
/* Allocate and initialize semaphores for the system operations. */
Cy_IPC_SystemSemaInit();
Cy_IPC_SystemPipeInit();
Cy_Flash_Init();
#endif /* CY_IPC_DEFAULT_CFG_DISABLE */
#if !defined(CY_PSOC6ABLE2_REV_0A_SUPPORT_DISABLE)
if (CY_SYSLIB_DEVICE_REV_0A == Cy_SysLib_GetDeviceRevision())
{
/* Clear data register of IPC structure #7, reserved for the Deep-Sleep operations. */
IPC_STRUCT7->DATA = 0UL;
/* Release IPC structure #7 to avoid deadlocks in case of SW or WDT reset during Deep-Sleep entering. */
IPC_STRUCT7->RELEASE = 0UL;
}
#endif /* !defined(CY_PSOC6ABLE2_REV_0A_SUPPORT_DISABLE) */
#endif /* CY_DEVICE_PSOC6ABLE2 */
}
/*******************************************************************************
* 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: SystemCoreClockUpdate
****************************************************************************//**
*
* Gets core clock frequency and updates \ref SystemCoreClock, \ref
* cy_Hfclk0FreqHz, and \ref cy_PeriClkFreqHz.
*
* Updates global variables used by the \ref Cy_SysLib_Delay(), \ref
* Cy_SysLib_DelayUs(), and \ref Cy_SysLib_DelayCycles().
*
*******************************************************************************/
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_CLK_IMO_FREQ_HZ;
break;
case CY_ROOT_PATH_SRC_EXT:
srcFreqHz = CY_CLK_EXT_FREQ_HZ;
break;
#if (SRSS_ECO_PRESENT == 1U)
case CY_ROOT_PATH_SRC_ECO:
srcFreqHz = CY_CLK_ECO_FREQ_HZ;
break;
#endif /* (SRSS_ECO_PRESENT == 1U) */
#if defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL) && (SRSS_ALTHF_PRESENT == 1U)
case CY_ROOT_PATH_SRC_ALTHF:
srcFreqHz = cy_BleEcoClockFreqHz;
break;
#endif /* defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL) && (SRSS_ALTHF_PRESENT == 1U) */
case CY_ROOT_PATH_SRC_DSI_MUX:
{
uint32_t dsi_src;
dsi_src = _FLD2VAL(SRSS_CLK_DSI_SELECT_DSI_MUX, SRSS->CLK_DSI_SELECT[rootPath]);
switch (dsi_src)
{
case CY_ROOT_PATH_SRC_DSI_MUX_HVILO:
srcFreqHz = CY_CLK_HVILO_FREQ_HZ;
break;
case CY_ROOT_PATH_SRC_DSI_MUX_WCO:
srcFreqHz = CY_CLK_WCO_FREQ_HZ;
break;
#if (SRSS_ALTLF_PRESENT == 1U)
case CY_ROOT_PATH_SRC_DSI_MUX_ALTLF:
srcFreqHz = CY_CLK_ALTLF_FREQ_HZ;
break;
#endif /* (SRSS_ALTLF_PRESENT == 1U) */
#if (SRSS_PILO_PRESENT == 1U)
case CY_ROOT_PATH_SRC_DSI_MUX_PILO:
srcFreqHz = CY_CLK_PILO_FREQ_HZ;
break;
#endif /* (SRSS_PILO_PRESENT == 1U) */
default:
srcFreqHz = CY_CLK_HVILO_FREQ_HZ;
break;
}
}
break;
default:
srcFreqHz = CY_CLK_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;
}
#if (CY_SYSTEM_CPU_CM0P == 1UL) || defined(CY_DOXYGEN)
/*******************************************************************************
* Function Name: Cy_SysGetCM4Status
****************************************************************************//**
*
* Returns the Cortex-M4 core power mode.
*
* \return \ref group_system_config_cm4_status_macro
*
*******************************************************************************/
uint32_t Cy_SysGetCM4Status(void)
{
uint32_t regValue;
/* Get current power mode */
regValue = CPUSS->CM4_PWR_CTL & CPUSS_CM4_PWR_CTL_PWR_MODE_Msk;
return (regValue);
}
/*******************************************************************************
* Function Name: Cy_SysEnableCM4
****************************************************************************//**
*
* Sets vector table base address and enables the Cortex-M4 core.
*
* \note If the CPU is already enabled, it is reset and then enabled.
*
* \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 regValue;
uint32_t interruptState;
uint32_t cpuState;
interruptState = Cy_SaveIRQ();
cpuState = Cy_SysGetCM4Status();
if (CY_SYS_CM4_STATUS_ENABLED == cpuState)
{
Cy_SysResetCM4();
}
CPUSS->CM4_VECTOR_TABLE_BASE = vectorTableOffset;
regValue = CPUSS->CM4_PWR_CTL & ~(CPUSS_CM4_PWR_CTL_VECTKEYSTAT_Msk | CPUSS_CM4_PWR_CTL_PWR_MODE_Msk);
regValue |= _VAL2FLD(CPUSS_CM4_PWR_CTL_VECTKEYSTAT, CY_SYS_CM4_PWR_CTL_KEY_OPEN);
regValue |= CY_SYS_CM4_STATUS_ENABLED;
CPUSS->CM4_PWR_CTL = regValue;
while((CPUSS->CM4_STATUS & CPUSS_CM4_STATUS_PWR_DONE_Msk) == 0UL)
{
/* Wait for the power mode to take effect */
}
Cy_RestoreIRQ(interruptState);
}
/*******************************************************************************
* Function Name: Cy_SysDisableCM4
****************************************************************************//**
*
* Disables the Cortex-M4 core and waits for the mode to take the effect.
*
* \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_SysDisableCM4(void)
{
uint32_t interruptState;
uint32_t regValue;
interruptState = Cy_SaveIRQ();
regValue = CPUSS->CM4_PWR_CTL & ~(CPUSS_CM4_PWR_CTL_VECTKEYSTAT_Msk | CPUSS_CM4_PWR_CTL_PWR_MODE_Msk);
regValue |= _VAL2FLD(CPUSS_CM4_PWR_CTL_VECTKEYSTAT, CY_SYS_CM4_PWR_CTL_KEY_OPEN);
regValue |= CY_SYS_CM4_STATUS_DISABLED;
CPUSS->CM4_PWR_CTL = regValue;
while((CPUSS->CM4_STATUS & CPUSS_CM4_STATUS_PWR_DONE_Msk) == 0UL)
{
/* Wait for the power mode to take effect */
}
Cy_RestoreIRQ(interruptState);
}
/*******************************************************************************
* Function Name: Cy_SysRetainCM4
****************************************************************************//**
*
* Retains the Cortex-M4 core and exists without waiting for the mode to take
* effect.
*
* \note The retained mode can be entered only from the enabled mode.
*
* \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 interruptState;
uint32_t regValue;
interruptState = Cy_SaveIRQ();
regValue = CPUSS->CM4_PWR_CTL & ~(CPUSS_CM4_PWR_CTL_VECTKEYSTAT_Msk | CPUSS_CM4_PWR_CTL_PWR_MODE_Msk);
regValue |= _VAL2FLD(CPUSS_CM4_PWR_CTL_VECTKEYSTAT, CY_SYS_CM4_PWR_CTL_KEY_OPEN);
regValue |= CY_SYS_CM4_STATUS_RETAINED;
CPUSS->CM4_PWR_CTL = regValue;
Cy_RestoreIRQ(interruptState);
}
/*******************************************************************************
* Function Name: Cy_SysResetCM4
****************************************************************************//**
*
* Resets the Cortex-M4 core and waits for the mode to take the effect.
*
* \note The reset mode can not be entered from the retained mode.
*
* \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 interruptState;
uint32_t regValue;
interruptState = Cy_SaveIRQ();
regValue = CPUSS->CM4_PWR_CTL & ~(CPUSS_CM4_PWR_CTL_VECTKEYSTAT_Msk | CPUSS_CM4_PWR_CTL_PWR_MODE_Msk);
regValue |= _VAL2FLD(CPUSS_CM4_PWR_CTL_VECTKEYSTAT, CY_SYS_CM4_PWR_CTL_KEY_OPEN);
regValue |= CY_SYS_CM4_STATUS_RESET;
CPUSS->CM4_PWR_CTL = regValue;
while((CPUSS->CM4_STATUS & CPUSS_CM4_STATUS_PWR_DONE_Msk) == 0UL)
{
/* Wait for the power mode to take effect */
}
Cy_RestoreIRQ(interruptState);
}
#endif /* #if (CY_SYSTEM_CPU_CM0P == 1UL) || defined(CY_DOXYGEN) */
/*******************************************************************************
* Function Name: Cy_MemorySymbols
****************************************************************************//**
*
* The intention of the function is to declare boundaries of the memories for the
* MDK compilers. For the rest of the supported compilers, this is done using
* linker configuration files. The following symbols used by the cymcuelftool.
*
*******************************************************************************/
#if defined (__ARMCC_VERSION)
__asm void Cy_MemorySymbols(void)
{
/* Flash */
EXPORT __cy_memory_0_start
EXPORT __cy_memory_0_length
EXPORT __cy_memory_0_row_size
/* Working Flash */
EXPORT __cy_memory_1_start
EXPORT __cy_memory_1_length
EXPORT __cy_memory_1_row_size
/* Supervisory Flash */
EXPORT __cy_memory_2_start
EXPORT __cy_memory_2_length
EXPORT __cy_memory_2_row_size
/* XIP */
EXPORT __cy_memory_3_start
EXPORT __cy_memory_3_length
EXPORT __cy_memory_3_row_size
/* eFuse */
EXPORT __cy_memory_4_start
EXPORT __cy_memory_4_length
EXPORT __cy_memory_4_row_size
/* Flash */
__cy_memory_0_start EQU __cpp(CY_FLASH_BASE)
__cy_memory_0_length EQU __cpp(CY_FLASH_SIZE)
__cy_memory_0_row_size EQU 0x200
/* Flash region for EEPROM emulation */
__cy_memory_1_start EQU __cpp(CY_EM_EEPROM_BASE)
__cy_memory_1_length EQU __cpp(CY_EM_EEPROM_SIZE)
__cy_memory_1_row_size EQU 0x200
/* Supervisory Flash */
__cy_memory_2_start EQU __cpp(CY_SFLASH_BASE)
__cy_memory_2_length EQU __cpp(CY_SFLASH_SIZE)
__cy_memory_2_row_size EQU 0x200
/* XIP */
__cy_memory_3_start EQU __cpp(CY_XIP_BASE)
__cy_memory_3_length EQU __cpp(CY_XIP_SIZE)
__cy_memory_3_row_size EQU 0x200
/* eFuse */
__cy_memory_4_start EQU __cpp(0x90700000)
__cy_memory_4_length EQU __cpp(0x100000)
__cy_memory_4_row_size EQU __cpp(1)
}
#endif /* defined (__ARMCC_VERSION) */
/* [] END OF FILE */

View File

@ -0,0 +1,5 @@
README for Cypress Peripheral Driver Library
============================================
This folder tree contains parts (binary-only libraries and M0/M4 core specific files) of Cypress Peripheral Driver Library (PDL) necessary to support PSoC 6 MCUs. Library names have been changed (vs. standard PDL version) by prepending a "lib" prefix to fit Mbed OS build system conventions.
See [Cypress PDL page](http://www.cypress.com/documentation/software-and-drivers/peripheral-driver-library-pdl) for details.

View File

@ -0,0 +1,212 @@
#! armcc -E
; The first line specifies a preprocessor command that the linker invokes
; to pass a scatter file through a C preprocessor.
;*******************************************************************************
;* \file cy8c6xx7_cm4_dual.scat
;* \version 2.10
;*
;* Linker file for the ARMCC.
;*
;* The main purpose of the linker script is to describe how the sections in the
;* input files should be mapped into the output file, and to control the memory
;* layout of the output file.
;*
;* \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 the warnings
;* during the build process: L6314W (no section matches pattern) and/or L6329W
;* (pattern only matches removed unused sections). In your project, you can
;* suppress the warning by passing the "--diag_suppress=L6314W,L6329W" option to
;* the linker, simply comment out or remove the relevant code in the linker
;* file.
;*
;*******************************************************************************
;* \copyright
;* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
;* SPDX-License-Identifier: Apache-2.0
;******************************************************************************/
; The defines below describe the location and size of blocks of memory in the target.
; Use these defines to specify the memory regions available for allocation.
; The following defines control RAM and flash memory allocation for the CM4 core.
; You can change the memory allocation by editing RAM and Flash defines.
; Note that 2 KB of RAM (at the end of the RAM section) are reserved for system use.
; Using this memory region for other purposes will lead to unexpected behavior.
; Your changes must be aligned with the corresponding defines for CM0+ core in 'xx_cm0plus.scat',
; where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.scat'.
; RAM
; RAM
#define RAM_START 0x08010000
#define RAM_SIZE 0x00037800
; Flash
; Flash
#define FLASH_START 0x10080000
#define FLASH_SIZE 0x00078000
; The following defines describe a 32K flash region used for EEPROM emulation.
; This region can also be used as the general purpose flash.
; You can assign sections to this memory region for only one of the cores.
; Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region.
; Therefore, repurposing this memory region will prevent such middleware from operation.
#define EM_EEPROM_START 0x14000000
#define EM_EEPROM_SIZE 0x8000
; The following defines describe device specific memory regions and must not be changed.
; Supervisory flash: User data
#define SFLASH_USER_DATA_START 0x16000800
#define SFLASH_USER_DATA_SIZE 0x00000800
; Supervisory flash: Normal Access Restrictions (NAR)
#define SFLASH_NAR_START 0x16001A00
#define SFLASH_NAR_SIZE 0x00000200
; Supervisory flash: Public Key
#define SFLASH_PUBLIC_KEY_START 0x16005A00
#define SFLASH_PUBLIC_KEY_SIZE 0x00000C00
; Supervisory flash: Table of Content # 2
#define SFLASH_TOC_2_START 0x16007C00
#define SFLASH_TOC_2_SIZE 0x00000200
; Supervisory flash: Table of Content # 2 Copy
#define SFLASH_RTOC_2_START 0x16007E00
#define SFLASH_RTOC_2_SIZE 0x00000200
; External memory
#define XIP_START 0x18000000
#define XIP_SIZE 0x08000000
; eFuse
#define EFUSE_START 0x90700000
#define EFUSE_SIZE 0x100000
LR_IROM1 FLASH_START FLASH_SIZE
{
ER_FLASH_VECTORS +0
{
* (RESET, +FIRST)
}
ER_FLASH_CODE +0 FIXED
{
* (InRoot$$Sections)
* (+RO)
}
ER_RAM_VECTORS RAM_START UNINIT
{
* (RESET_RAM, +FIRST)
}
RW_RAM_DATA +0
{
* (.cy_ramfunc)
.ANY (+RW, +ZI)
}
; Place variables in the section that should not be initialized during the
; device startup.
RW_IRAM1 +0 UNINIT
{
* (.noinit)
}
; Used for the digital signature of the secure application and the
; Bootloader SDK appication. The size of the section depends on the required
; data size.
.cy_app_signature (FLASH_START + FLASH_SIZE - 256) 256
{
* (.cy_app_signature)
}
}
; Emulated EEPROM Flash area
LR_EM_EEPROM EM_EEPROM_START EM_EEPROM_SIZE
{
.cy_em_eeprom +0
{
* (.cy_em_eeprom)
}
}
; Supervisory flash: User data
LR_SFLASH_USER_DATA SFLASH_USER_DATA_START SFLASH_USER_DATA_SIZE
{
.cy_sflash_user_data +0
{
* (.cy_sflash_user_data)
}
}
; Supervisory flash: Normal Access Restrictions (NAR)
LR_SFLASH_NAR SFLASH_NAR_START SFLASH_NAR_SIZE
{
.cy_sflash_nar +0
{
* (.cy_sflash_nar)
}
}
; Supervisory flash: Public Key
LR_SFLASH_PUBLIC_KEY SFLASH_PUBLIC_KEY_START SFLASH_PUBLIC_KEY_SIZE
{
.cy_sflash_public_key +0
{
* (.cy_sflash_public_key)
}
}
; Supervisory flash: Table of Content # 2
LR_SFLASH_TOC_2 SFLASH_TOC_2_START SFLASH_TOC_2_SIZE
{
.cy_toc_part2 +0
{
* (.cy_toc_part2)
}
}
; Supervisory flash: Table of Content # 2 Copy
LR_SFLASH_RTOC_2 SFLASH_RTOC_2_START SFLASH_RTOC_2_SIZE
{
.cy_rtoc_part2 +0
{
* (.cy_rtoc_part2)
}
}
; Places the code in the Execute in Place (XIP) section. See the smif driver documentation for details.
LR_EROM XIP_START XIP_SIZE
{
.cy_xip +0
{
* (.cy_xip)
}
}
; eFuse
LR_EFUSE EFUSE_START EFUSE_SIZE
{
.cy_efuse +0
{
* (.cy_efuse)
}
}
; The section is used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage.
CYMETA 0x90500000
{
.cymeta +0 { * (.cymeta) }
}
/* [] END OF FILE */

View File

@ -0,0 +1,654 @@
;/**************************************************************************//**
; * @file startup_psoc63_cm4.s
; * @brief CMSIS Core Device Startup File for
; * ARMCM4 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.
; */
;/*
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
;*/
__initial_sp EQU 0x08047800
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD 0x0000000D ; NMI Handler located at ROM code
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External interrupts Power Mode Description
DCD ioss_interrupts_gpio_0_IRQHandler ; GPIO Port Interrupt #0
DCD ioss_interrupts_gpio_1_IRQHandler ; GPIO Port Interrupt #1
DCD ioss_interrupts_gpio_2_IRQHandler ; GPIO Port Interrupt #2
DCD ioss_interrupts_gpio_3_IRQHandler ; GPIO Port Interrupt #3
DCD ioss_interrupts_gpio_4_IRQHandler ; GPIO Port Interrupt #4
DCD ioss_interrupts_gpio_5_IRQHandler ; GPIO Port Interrupt #5
DCD ioss_interrupts_gpio_6_IRQHandler ; GPIO Port Interrupt #6
DCD ioss_interrupts_gpio_7_IRQHandler ; GPIO Port Interrupt #7
DCD ioss_interrupts_gpio_8_IRQHandler ; GPIO Port Interrupt #8
DCD ioss_interrupts_gpio_9_IRQHandler ; GPIO Port Interrupt #9
DCD ioss_interrupts_gpio_10_IRQHandler ; GPIO Port Interrupt #10
DCD ioss_interrupts_gpio_11_IRQHandler ; GPIO Port Interrupt #11
DCD ioss_interrupts_gpio_12_IRQHandler ; GPIO Port Interrupt #12
DCD ioss_interrupts_gpio_13_IRQHandler ; GPIO Port Interrupt #13
DCD ioss_interrupts_gpio_14_IRQHandler ; GPIO Port Interrupt #14
DCD ioss_interrupt_gpio_IRQHandler ; GPIO All Ports
DCD ioss_interrupt_vdd_IRQHandler ; GPIO Supply Detect Interrupt
DCD lpcomp_interrupt_IRQHandler ; Low Power Comparator Interrupt
DCD scb_8_interrupt_IRQHandler ; Serial Communication Block #8 (DeepSleep capable)
DCD srss_interrupt_mcwdt_0_IRQHandler ; Multi Counter Watchdog Timer interrupt
DCD srss_interrupt_mcwdt_1_IRQHandler ; Multi Counter Watchdog Timer interrupt
DCD srss_interrupt_backup_IRQHandler ; Backup domain interrupt
DCD srss_interrupt_IRQHandler ; Other combined Interrupts for SRSS (LVD, WDT, CLKCAL)
DCD pass_interrupt_ctbs_IRQHandler ; CTBm Interrupt (all CTBms)
DCD bless_interrupt_IRQHandler ; Bluetooth Radio interrupt
DCD cpuss_interrupts_ipc_0_IRQHandler ; CPUSS Inter Process Communication Interrupt #0
DCD cpuss_interrupts_ipc_1_IRQHandler ; CPUSS Inter Process Communication Interrupt #1
DCD cpuss_interrupts_ipc_2_IRQHandler ; CPUSS Inter Process Communication Interrupt #2
DCD cpuss_interrupts_ipc_3_IRQHandler ; CPUSS Inter Process Communication Interrupt #3
DCD cpuss_interrupts_ipc_4_IRQHandler ; CPUSS Inter Process Communication Interrupt #4
DCD cpuss_interrupts_ipc_5_IRQHandler ; CPUSS Inter Process Communication Interrupt #5
DCD cpuss_interrupts_ipc_6_IRQHandler ; CPUSS Inter Process Communication Interrupt #6
DCD cpuss_interrupts_ipc_7_IRQHandler ; CPUSS Inter Process Communication Interrupt #7
DCD cpuss_interrupts_ipc_8_IRQHandler ; CPUSS Inter Process Communication Interrupt #8
DCD cpuss_interrupts_ipc_9_IRQHandler ; CPUSS Inter Process Communication Interrupt #9
DCD cpuss_interrupts_ipc_10_IRQHandler ; CPUSS Inter Process Communication Interrupt #10
DCD cpuss_interrupts_ipc_11_IRQHandler ; CPUSS Inter Process Communication Interrupt #11
DCD cpuss_interrupts_ipc_12_IRQHandler ; CPUSS Inter Process Communication Interrupt #12
DCD cpuss_interrupts_ipc_13_IRQHandler ; CPUSS Inter Process Communication Interrupt #13
DCD cpuss_interrupts_ipc_14_IRQHandler ; CPUSS Inter Process Communication Interrupt #14
DCD cpuss_interrupts_ipc_15_IRQHandler ; CPUSS Inter Process Communication Interrupt #15
DCD scb_0_interrupt_IRQHandler ; Serial Communication Block #0
DCD scb_1_interrupt_IRQHandler ; Serial Communication Block #1
DCD scb_2_interrupt_IRQHandler ; Serial Communication Block #2
DCD scb_3_interrupt_IRQHandler ; Serial Communication Block #3
DCD scb_4_interrupt_IRQHandler ; Serial Communication Block #4
DCD scb_5_interrupt_IRQHandler ; Serial Communication Block #5
DCD scb_6_interrupt_IRQHandler ; Serial Communication Block #6
DCD scb_7_interrupt_IRQHandler ; Serial Communication Block #7
DCD csd_interrupt_IRQHandler ; CSD (Capsense) interrupt
DCD cpuss_interrupts_dw0_0_IRQHandler ; CPUSS DataWire #0, Channel #0
DCD cpuss_interrupts_dw0_1_IRQHandler ; CPUSS DataWire #0, Channel #1
DCD cpuss_interrupts_dw0_2_IRQHandler ; CPUSS DataWire #0, Channel #2
DCD cpuss_interrupts_dw0_3_IRQHandler ; CPUSS DataWire #0, Channel #3
DCD cpuss_interrupts_dw0_4_IRQHandler ; CPUSS DataWire #0, Channel #4
DCD cpuss_interrupts_dw0_5_IRQHandler ; CPUSS DataWire #0, Channel #5
DCD cpuss_interrupts_dw0_6_IRQHandler ; CPUSS DataWire #0, Channel #6
DCD cpuss_interrupts_dw0_7_IRQHandler ; CPUSS DataWire #0, Channel #7
DCD cpuss_interrupts_dw0_8_IRQHandler ; CPUSS DataWire #0, Channel #8
DCD cpuss_interrupts_dw0_9_IRQHandler ; CPUSS DataWire #0, Channel #9
DCD cpuss_interrupts_dw0_10_IRQHandler ; CPUSS DataWire #0, Channel #10
DCD cpuss_interrupts_dw0_11_IRQHandler ; CPUSS DataWire #0, Channel #11
DCD cpuss_interrupts_dw0_12_IRQHandler ; CPUSS DataWire #0, Channel #12
DCD cpuss_interrupts_dw0_13_IRQHandler ; CPUSS DataWire #0, Channel #13
DCD cpuss_interrupts_dw0_14_IRQHandler ; CPUSS DataWire #0, Channel #14
DCD cpuss_interrupts_dw0_15_IRQHandler ; CPUSS DataWire #0, Channel #15
DCD cpuss_interrupts_dw1_0_IRQHandler ; CPUSS DataWire #1, Channel #0
DCD cpuss_interrupts_dw1_1_IRQHandler ; CPUSS DataWire #1, Channel #1
DCD cpuss_interrupts_dw1_2_IRQHandler ; CPUSS DataWire #1, Channel #2
DCD cpuss_interrupts_dw1_3_IRQHandler ; CPUSS DataWire #1, Channel #3
DCD cpuss_interrupts_dw1_4_IRQHandler ; CPUSS DataWire #1, Channel #4
DCD cpuss_interrupts_dw1_5_IRQHandler ; CPUSS DataWire #1, Channel #5
DCD cpuss_interrupts_dw1_6_IRQHandler ; CPUSS DataWire #1, Channel #6
DCD cpuss_interrupts_dw1_7_IRQHandler ; CPUSS DataWire #1, Channel #7
DCD cpuss_interrupts_dw1_8_IRQHandler ; CPUSS DataWire #1, Channel #8
DCD cpuss_interrupts_dw1_9_IRQHandler ; CPUSS DataWire #1, Channel #9
DCD cpuss_interrupts_dw1_10_IRQHandler ; CPUSS DataWire #1, Channel #10
DCD cpuss_interrupts_dw1_11_IRQHandler ; CPUSS DataWire #1, Channel #11
DCD cpuss_interrupts_dw1_12_IRQHandler ; CPUSS DataWire #1, Channel #12
DCD cpuss_interrupts_dw1_13_IRQHandler ; CPUSS DataWire #1, Channel #13
DCD cpuss_interrupts_dw1_14_IRQHandler ; CPUSS DataWire #1, Channel #14
DCD cpuss_interrupts_dw1_15_IRQHandler ; CPUSS DataWire #1, Channel #15
DCD cpuss_interrupts_fault_0_IRQHandler ; CPUSS Fault Structure Interrupt #0
DCD cpuss_interrupts_fault_1_IRQHandler ; CPUSS Fault Structure Interrupt #1
DCD cpuss_interrupt_crypto_IRQHandler ; CRYPTO Accelerator Interrupt
DCD cpuss_interrupt_fm_IRQHandler ; FLASH Macro Interrupt
DCD cpuss_interrupts_cm0_cti_0_IRQHandler ; CM0+ CTI #0
DCD cpuss_interrupts_cm0_cti_1_IRQHandler ; CM0+ CTI #1
DCD cpuss_interrupts_cm4_cti_0_IRQHandler ; CM4 CTI #0
DCD cpuss_interrupts_cm4_cti_1_IRQHandler ; CM4 CTI #1
DCD tcpwm_0_interrupts_0_IRQHandler ; TCPWM #0, Counter #0
DCD tcpwm_0_interrupts_1_IRQHandler ; TCPWM #0, Counter #1
DCD tcpwm_0_interrupts_2_IRQHandler ; TCPWM #0, Counter #2
DCD tcpwm_0_interrupts_3_IRQHandler ; TCPWM #0, Counter #3
DCD tcpwm_0_interrupts_4_IRQHandler ; TCPWM #0, Counter #4
DCD tcpwm_0_interrupts_5_IRQHandler ; TCPWM #0, Counter #5
DCD tcpwm_0_interrupts_6_IRQHandler ; TCPWM #0, Counter #6
DCD tcpwm_0_interrupts_7_IRQHandler ; TCPWM #0, Counter #7
DCD tcpwm_1_interrupts_0_IRQHandler ; TCPWM #1, Counter #0
DCD tcpwm_1_interrupts_1_IRQHandler ; TCPWM #1, Counter #1
DCD tcpwm_1_interrupts_2_IRQHandler ; TCPWM #1, Counter #2
DCD tcpwm_1_interrupts_3_IRQHandler ; TCPWM #1, Counter #3
DCD tcpwm_1_interrupts_4_IRQHandler ; TCPWM #1, Counter #4
DCD tcpwm_1_interrupts_5_IRQHandler ; TCPWM #1, Counter #5
DCD tcpwm_1_interrupts_6_IRQHandler ; TCPWM #1, Counter #6
DCD tcpwm_1_interrupts_7_IRQHandler ; TCPWM #1, Counter #7
DCD tcpwm_1_interrupts_8_IRQHandler ; TCPWM #1, Counter #8
DCD tcpwm_1_interrupts_9_IRQHandler ; TCPWM #1, Counter #9
DCD tcpwm_1_interrupts_10_IRQHandler ; TCPWM #1, Counter #10
DCD tcpwm_1_interrupts_11_IRQHandler ; TCPWM #1, Counter #11
DCD tcpwm_1_interrupts_12_IRQHandler ; TCPWM #1, Counter #12
DCD tcpwm_1_interrupts_13_IRQHandler ; TCPWM #1, Counter #13
DCD tcpwm_1_interrupts_14_IRQHandler ; TCPWM #1, Counter #14
DCD tcpwm_1_interrupts_15_IRQHandler ; TCPWM #1, Counter #15
DCD tcpwm_1_interrupts_16_IRQHandler ; TCPWM #1, Counter #16
DCD tcpwm_1_interrupts_17_IRQHandler ; TCPWM #1, Counter #17
DCD tcpwm_1_interrupts_18_IRQHandler ; TCPWM #1, Counter #18
DCD tcpwm_1_interrupts_19_IRQHandler ; TCPWM #1, Counter #19
DCD tcpwm_1_interrupts_20_IRQHandler ; TCPWM #1, Counter #20
DCD tcpwm_1_interrupts_21_IRQHandler ; TCPWM #1, Counter #21
DCD tcpwm_1_interrupts_22_IRQHandler ; TCPWM #1, Counter #22
DCD tcpwm_1_interrupts_23_IRQHandler ; TCPWM #1, Counter #23
DCD udb_interrupts_0_IRQHandler ; UDB Interrupt #0
DCD udb_interrupts_1_IRQHandler ; UDB Interrupt #1
DCD udb_interrupts_2_IRQHandler ; UDB Interrupt #2
DCD udb_interrupts_3_IRQHandler ; UDB Interrupt #3
DCD udb_interrupts_4_IRQHandler ; UDB Interrupt #4
DCD udb_interrupts_5_IRQHandler ; UDB Interrupt #5
DCD udb_interrupts_6_IRQHandler ; UDB Interrupt #6
DCD udb_interrupts_7_IRQHandler ; UDB Interrupt #7
DCD udb_interrupts_8_IRQHandler ; UDB Interrupt #8
DCD udb_interrupts_9_IRQHandler ; UDB Interrupt #9
DCD udb_interrupts_10_IRQHandler ; UDB Interrupt #10
DCD udb_interrupts_11_IRQHandler ; UDB Interrupt #11
DCD udb_interrupts_12_IRQHandler ; UDB Interrupt #12
DCD udb_interrupts_13_IRQHandler ; UDB Interrupt #13
DCD udb_interrupts_14_IRQHandler ; UDB Interrupt #14
DCD udb_interrupts_15_IRQHandler ; UDB Interrupt #15
DCD pass_interrupt_sar_IRQHandler ; SAR ADC interrupt
DCD audioss_interrupt_i2s_IRQHandler ; I2S Audio interrupt
DCD audioss_interrupt_pdm_IRQHandler ; PDM/PCM Audio interrupt
DCD profile_interrupt_IRQHandler ; Energy Profiler interrupt
DCD smif_interrupt_IRQHandler ; Serial Memory Interface interrupt
DCD usb_interrupt_hi_IRQHandler ; USB Interrupt
DCD usb_interrupt_med_IRQHandler ; USB Interrupt
DCD usb_interrupt_lo_IRQHandler ; USB Interrupt
DCD pass_interrupt_dacs_IRQHandler ; Consolidated interrrupt for all DACs
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
EXPORT __ramVectors
AREA RESET_RAM, READWRITE, NOINIT
__ramVectors SPACE __Vectors_Size
AREA |.text|, CODE, READONLY
; Saves and disables the interrupts
Cy_SaveIRQ PROC
EXPORT Cy_SaveIRQ
MRS r0, PRIMASK
CPSID I
BX LR
ENDP
; Restores the interrupts
Cy_RestoreIRQ PROC
EXPORT Cy_RestoreIRQ
MSR PRIMASK, r0
BX LR
ENDP
; Weak function for startup customization
Cy_OnResetUser PROC
EXPORT Cy_OnResetUser [WEAK]
BX LR
ENDP
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT Cy_SystemInitFpuEnable
IMPORT __main
; Define strong function for startup customization
BL Cy_OnResetUser
; Copy vectors from ROM to RAM
LDR r1, =__Vectors
LDR r0, =__ramVectors
LDR r2, =__Vectors_Size
Vectors_Copy
LDR r3, [r1]
STR r3, [r0]
ADDS r0, r0, #4
ADDS r1, r1, #4
SUBS r2, r2, #1
CMP r2, #0
BNE Vectors_Copy
; Update Vector Table Offset Register. */
LDR r0, =__ramVectors
LDR r1, =0xE000ED08
STR r0, [r1]
dsb 0xF
; Enable the FPU if used
LDR R0, =Cy_SystemInitFpuEnable
BLX R0
LDR R0, =__main
BLX R0
; Should never get here
B .
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
Cy_SysLib_FaultHandler PROC
EXPORT Cy_SysLib_FaultHandler [WEAK]
B .
ENDP
HardFault_Wrapper\
PROC
EXPORT HardFault_Wrapper [WEAK]
movs r0, #4
mov r1, LR
tst r0, r1
beq L_MSP
mrs r0, PSP
bl L_API_call
L_MSP
mrs r0, MSP
L_API_call
bl Cy_SysLib_FaultHandler
ENDP
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B HardFault_Wrapper
ENDP
MemManage_Handler\
PROC
EXPORT MemManage_Handler [WEAK]
B HardFault_Wrapper
ENDP
BusFault_Handler\
PROC
EXPORT BusFault_Handler [WEAK]
B HardFault_Wrapper
ENDP
UsageFault_Handler\
PROC
EXPORT UsageFault_Handler [WEAK]
B HardFault_Wrapper
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
DebugMon_Handler\
PROC
EXPORT DebugMon_Handler [WEAK]
B .
ENDP
PendSV_Handler PROC
EXPORT PendSV_Handler [WEAK]
B .
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
Default_Handler PROC
EXPORT Default_Handler [WEAK]
EXPORT ioss_interrupts_gpio_0_IRQHandler [WEAK]
EXPORT ioss_interrupts_gpio_1_IRQHandler [WEAK]
EXPORT ioss_interrupts_gpio_2_IRQHandler [WEAK]
EXPORT ioss_interrupts_gpio_3_IRQHandler [WEAK]
EXPORT ioss_interrupts_gpio_4_IRQHandler [WEAK]
EXPORT ioss_interrupts_gpio_5_IRQHandler [WEAK]
EXPORT ioss_interrupts_gpio_6_IRQHandler [WEAK]
EXPORT ioss_interrupts_gpio_7_IRQHandler [WEAK]
EXPORT ioss_interrupts_gpio_8_IRQHandler [WEAK]
EXPORT ioss_interrupts_gpio_9_IRQHandler [WEAK]
EXPORT ioss_interrupts_gpio_10_IRQHandler [WEAK]
EXPORT ioss_interrupts_gpio_11_IRQHandler [WEAK]
EXPORT ioss_interrupts_gpio_12_IRQHandler [WEAK]
EXPORT ioss_interrupts_gpio_13_IRQHandler [WEAK]
EXPORT ioss_interrupts_gpio_14_IRQHandler [WEAK]
EXPORT ioss_interrupt_gpio_IRQHandler [WEAK]
EXPORT ioss_interrupt_vdd_IRQHandler [WEAK]
EXPORT lpcomp_interrupt_IRQHandler [WEAK]
EXPORT scb_8_interrupt_IRQHandler [WEAK]
EXPORT srss_interrupt_mcwdt_0_IRQHandler [WEAK]
EXPORT srss_interrupt_mcwdt_1_IRQHandler [WEAK]
EXPORT srss_interrupt_backup_IRQHandler [WEAK]
EXPORT srss_interrupt_IRQHandler [WEAK]
EXPORT pass_interrupt_ctbs_IRQHandler [WEAK]
EXPORT bless_interrupt_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_0_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_1_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_2_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_3_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_4_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_5_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_6_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_7_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_8_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_9_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_10_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_11_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_12_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_13_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_14_IRQHandler [WEAK]
EXPORT cpuss_interrupts_ipc_15_IRQHandler [WEAK]
EXPORT scb_0_interrupt_IRQHandler [WEAK]
EXPORT scb_1_interrupt_IRQHandler [WEAK]
EXPORT scb_2_interrupt_IRQHandler [WEAK]
EXPORT scb_3_interrupt_IRQHandler [WEAK]
EXPORT scb_4_interrupt_IRQHandler [WEAK]
EXPORT scb_5_interrupt_IRQHandler [WEAK]
EXPORT scb_6_interrupt_IRQHandler [WEAK]
EXPORT scb_7_interrupt_IRQHandler [WEAK]
EXPORT csd_interrupt_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_0_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_1_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_2_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_3_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_4_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_5_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_6_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_7_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_8_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_9_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_10_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_11_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_12_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_13_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_14_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw0_15_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_0_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_1_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_2_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_3_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_4_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_5_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_6_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_7_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_8_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_9_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_10_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_11_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_12_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_13_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_14_IRQHandler [WEAK]
EXPORT cpuss_interrupts_dw1_15_IRQHandler [WEAK]
EXPORT cpuss_interrupts_fault_0_IRQHandler [WEAK]
EXPORT cpuss_interrupts_fault_1_IRQHandler [WEAK]
EXPORT cpuss_interrupt_crypto_IRQHandler [WEAK]
EXPORT cpuss_interrupt_fm_IRQHandler [WEAK]
EXPORT cpuss_interrupts_cm0_cti_0_IRQHandler [WEAK]
EXPORT cpuss_interrupts_cm0_cti_1_IRQHandler [WEAK]
EXPORT cpuss_interrupts_cm4_cti_0_IRQHandler [WEAK]
EXPORT cpuss_interrupts_cm4_cti_1_IRQHandler [WEAK]
EXPORT tcpwm_0_interrupts_0_IRQHandler [WEAK]
EXPORT tcpwm_0_interrupts_1_IRQHandler [WEAK]
EXPORT tcpwm_0_interrupts_2_IRQHandler [WEAK]
EXPORT tcpwm_0_interrupts_3_IRQHandler [WEAK]
EXPORT tcpwm_0_interrupts_4_IRQHandler [WEAK]
EXPORT tcpwm_0_interrupts_5_IRQHandler [WEAK]
EXPORT tcpwm_0_interrupts_6_IRQHandler [WEAK]
EXPORT tcpwm_0_interrupts_7_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_0_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_1_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_2_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_3_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_4_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_5_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_6_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_7_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_8_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_9_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_10_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_11_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_12_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_13_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_14_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_15_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_16_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_17_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_18_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_19_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_20_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_21_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_22_IRQHandler [WEAK]
EXPORT tcpwm_1_interrupts_23_IRQHandler [WEAK]
EXPORT udb_interrupts_0_IRQHandler [WEAK]
EXPORT udb_interrupts_1_IRQHandler [WEAK]
EXPORT udb_interrupts_2_IRQHandler [WEAK]
EXPORT udb_interrupts_3_IRQHandler [WEAK]
EXPORT udb_interrupts_4_IRQHandler [WEAK]
EXPORT udb_interrupts_5_IRQHandler [WEAK]
EXPORT udb_interrupts_6_IRQHandler [WEAK]
EXPORT udb_interrupts_7_IRQHandler [WEAK]
EXPORT udb_interrupts_8_IRQHandler [WEAK]
EXPORT udb_interrupts_9_IRQHandler [WEAK]
EXPORT udb_interrupts_10_IRQHandler [WEAK]
EXPORT udb_interrupts_11_IRQHandler [WEAK]
EXPORT udb_interrupts_12_IRQHandler [WEAK]
EXPORT udb_interrupts_13_IRQHandler [WEAK]
EXPORT udb_interrupts_14_IRQHandler [WEAK]
EXPORT udb_interrupts_15_IRQHandler [WEAK]
EXPORT pass_interrupt_sar_IRQHandler [WEAK]
EXPORT audioss_interrupt_i2s_IRQHandler [WEAK]
EXPORT audioss_interrupt_pdm_IRQHandler [WEAK]
EXPORT profile_interrupt_IRQHandler [WEAK]
EXPORT smif_interrupt_IRQHandler [WEAK]
EXPORT usb_interrupt_hi_IRQHandler [WEAK]
EXPORT usb_interrupt_med_IRQHandler [WEAK]
EXPORT usb_interrupt_lo_IRQHandler [WEAK]
EXPORT pass_interrupt_dacs_IRQHandler [WEAK]
ioss_interrupts_gpio_0_IRQHandler
ioss_interrupts_gpio_1_IRQHandler
ioss_interrupts_gpio_2_IRQHandler
ioss_interrupts_gpio_3_IRQHandler
ioss_interrupts_gpio_4_IRQHandler
ioss_interrupts_gpio_5_IRQHandler
ioss_interrupts_gpio_6_IRQHandler
ioss_interrupts_gpio_7_IRQHandler
ioss_interrupts_gpio_8_IRQHandler
ioss_interrupts_gpio_9_IRQHandler
ioss_interrupts_gpio_10_IRQHandler
ioss_interrupts_gpio_11_IRQHandler
ioss_interrupts_gpio_12_IRQHandler
ioss_interrupts_gpio_13_IRQHandler
ioss_interrupts_gpio_14_IRQHandler
ioss_interrupt_gpio_IRQHandler
ioss_interrupt_vdd_IRQHandler
lpcomp_interrupt_IRQHandler
scb_8_interrupt_IRQHandler
srss_interrupt_mcwdt_0_IRQHandler
srss_interrupt_mcwdt_1_IRQHandler
srss_interrupt_backup_IRQHandler
srss_interrupt_IRQHandler
pass_interrupt_ctbs_IRQHandler
bless_interrupt_IRQHandler
cpuss_interrupts_ipc_0_IRQHandler
cpuss_interrupts_ipc_1_IRQHandler
cpuss_interrupts_ipc_2_IRQHandler
cpuss_interrupts_ipc_3_IRQHandler
cpuss_interrupts_ipc_4_IRQHandler
cpuss_interrupts_ipc_5_IRQHandler
cpuss_interrupts_ipc_6_IRQHandler
cpuss_interrupts_ipc_7_IRQHandler
cpuss_interrupts_ipc_8_IRQHandler
cpuss_interrupts_ipc_9_IRQHandler
cpuss_interrupts_ipc_10_IRQHandler
cpuss_interrupts_ipc_11_IRQHandler
cpuss_interrupts_ipc_12_IRQHandler
cpuss_interrupts_ipc_13_IRQHandler
cpuss_interrupts_ipc_14_IRQHandler
cpuss_interrupts_ipc_15_IRQHandler
scb_0_interrupt_IRQHandler
scb_1_interrupt_IRQHandler
scb_2_interrupt_IRQHandler
scb_3_interrupt_IRQHandler
scb_4_interrupt_IRQHandler
scb_5_interrupt_IRQHandler
scb_6_interrupt_IRQHandler
scb_7_interrupt_IRQHandler
csd_interrupt_IRQHandler
cpuss_interrupts_dw0_0_IRQHandler
cpuss_interrupts_dw0_1_IRQHandler
cpuss_interrupts_dw0_2_IRQHandler
cpuss_interrupts_dw0_3_IRQHandler
cpuss_interrupts_dw0_4_IRQHandler
cpuss_interrupts_dw0_5_IRQHandler
cpuss_interrupts_dw0_6_IRQHandler
cpuss_interrupts_dw0_7_IRQHandler
cpuss_interrupts_dw0_8_IRQHandler
cpuss_interrupts_dw0_9_IRQHandler
cpuss_interrupts_dw0_10_IRQHandler
cpuss_interrupts_dw0_11_IRQHandler
cpuss_interrupts_dw0_12_IRQHandler
cpuss_interrupts_dw0_13_IRQHandler
cpuss_interrupts_dw0_14_IRQHandler
cpuss_interrupts_dw0_15_IRQHandler
cpuss_interrupts_dw1_0_IRQHandler
cpuss_interrupts_dw1_1_IRQHandler
cpuss_interrupts_dw1_2_IRQHandler
cpuss_interrupts_dw1_3_IRQHandler
cpuss_interrupts_dw1_4_IRQHandler
cpuss_interrupts_dw1_5_IRQHandler
cpuss_interrupts_dw1_6_IRQHandler
cpuss_interrupts_dw1_7_IRQHandler
cpuss_interrupts_dw1_8_IRQHandler
cpuss_interrupts_dw1_9_IRQHandler
cpuss_interrupts_dw1_10_IRQHandler
cpuss_interrupts_dw1_11_IRQHandler
cpuss_interrupts_dw1_12_IRQHandler
cpuss_interrupts_dw1_13_IRQHandler
cpuss_interrupts_dw1_14_IRQHandler
cpuss_interrupts_dw1_15_IRQHandler
cpuss_interrupts_fault_0_IRQHandler
cpuss_interrupts_fault_1_IRQHandler
cpuss_interrupt_crypto_IRQHandler
cpuss_interrupt_fm_IRQHandler
cpuss_interrupts_cm0_cti_0_IRQHandler
cpuss_interrupts_cm0_cti_1_IRQHandler
cpuss_interrupts_cm4_cti_0_IRQHandler
cpuss_interrupts_cm4_cti_1_IRQHandler
tcpwm_0_interrupts_0_IRQHandler
tcpwm_0_interrupts_1_IRQHandler
tcpwm_0_interrupts_2_IRQHandler
tcpwm_0_interrupts_3_IRQHandler
tcpwm_0_interrupts_4_IRQHandler
tcpwm_0_interrupts_5_IRQHandler
tcpwm_0_interrupts_6_IRQHandler
tcpwm_0_interrupts_7_IRQHandler
tcpwm_1_interrupts_0_IRQHandler
tcpwm_1_interrupts_1_IRQHandler
tcpwm_1_interrupts_2_IRQHandler
tcpwm_1_interrupts_3_IRQHandler
tcpwm_1_interrupts_4_IRQHandler
tcpwm_1_interrupts_5_IRQHandler
tcpwm_1_interrupts_6_IRQHandler
tcpwm_1_interrupts_7_IRQHandler
tcpwm_1_interrupts_8_IRQHandler
tcpwm_1_interrupts_9_IRQHandler
tcpwm_1_interrupts_10_IRQHandler
tcpwm_1_interrupts_11_IRQHandler
tcpwm_1_interrupts_12_IRQHandler
tcpwm_1_interrupts_13_IRQHandler
tcpwm_1_interrupts_14_IRQHandler
tcpwm_1_interrupts_15_IRQHandler
tcpwm_1_interrupts_16_IRQHandler
tcpwm_1_interrupts_17_IRQHandler
tcpwm_1_interrupts_18_IRQHandler
tcpwm_1_interrupts_19_IRQHandler
tcpwm_1_interrupts_20_IRQHandler
tcpwm_1_interrupts_21_IRQHandler
tcpwm_1_interrupts_22_IRQHandler
tcpwm_1_interrupts_23_IRQHandler
udb_interrupts_0_IRQHandler
udb_interrupts_1_IRQHandler
udb_interrupts_2_IRQHandler
udb_interrupts_3_IRQHandler
udb_interrupts_4_IRQHandler
udb_interrupts_5_IRQHandler
udb_interrupts_6_IRQHandler
udb_interrupts_7_IRQHandler
udb_interrupts_8_IRQHandler
udb_interrupts_9_IRQHandler
udb_interrupts_10_IRQHandler
udb_interrupts_11_IRQHandler
udb_interrupts_12_IRQHandler
udb_interrupts_13_IRQHandler
udb_interrupts_14_IRQHandler
udb_interrupts_15_IRQHandler
pass_interrupt_sar_IRQHandler
audioss_interrupt_i2s_IRQHandler
audioss_interrupt_pdm_IRQHandler
profile_interrupt_IRQHandler
smif_interrupt_IRQHandler
usb_interrupt_hi_IRQHandler
usb_interrupt_med_IRQHandler
usb_interrupt_lo_IRQHandler
pass_interrupt_dacs_IRQHandler
B .
ENDP
ALIGN
END
; [] END OF FILE

View File

@ -0,0 +1,399 @@
/***************************************************************************//**
* \file cy8c6xx7_cm4_dual.ld
* \version 2.10
*
* Linker file for the GNU C compiler.
*
* The main purpose of the linker script is to describe how the sections in the
* input files should be mapped into the output file, and to control the memory
* layout of the output file.
*
* \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-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
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)
/* The MEMORY section below describes the location and size of blocks of memory in the target.
* Use this section to specify the memory regions available for allocation.
*/
MEMORY
{
/* The ram and flash regions control RAM and flash memory allocation for the CM4 core.
* You can change the memory allocation by editing the 'ram' and 'flash' regions.
* Note that 2 KB of RAM (at the end of the RAM section) are reserved for system use.
* Using this memory region for other purposes will lead to unexpected behavior.
* Your changes must be aligned with the corresponding memory regions for CM0+ core in 'xx_cm0plus.ld',
* where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.ld'.
*/
ram (rwx) : ORIGIN = 0x08010000, LENGTH = 0x37800
flash (rx) : ORIGIN = 0x10080000, LENGTH = 0x78000
/* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash.
* You can assign sections to this memory region for only one of the cores.
* Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region.
* Therefore, repurposing this memory region will prevent such middleware from operation.
*/
em_eeprom (rx) : ORIGIN = 0x14000000, LENGTH = 0x8000 /* 32 KB */
/* The following regions define device specific memory regions and must not be changed. */
sflash_user_data (rx) : ORIGIN = 0x16000800, LENGTH = 0x800 /* Supervisory flash: User data */
sflash_nar (rx) : ORIGIN = 0x16001A00, LENGTH = 0x200 /* Supervisory flash: Normal Access Restrictions (NAR) */
sflash_public_key (rx) : ORIGIN = 0x16005A00, LENGTH = 0xC00 /* Supervisory flash: Public Key */
sflash_toc_2 (rx) : ORIGIN = 0x16007C00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 */
sflash_rtoc_2 (rx) : ORIGIN = 0x16007E00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 Copy */
xip (rx) : ORIGIN = 0x18000000, LENGTH = 0x8000000 /* 128 MB */
efuse (r) : ORIGIN = 0x90700000, LENGTH = 0x100000 /* 1 MB */
}
/* 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
*/
SECTIONS
{
.text :
{
. = 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*))
/* To copy multiple ROM to RAM sections,
* uncomment copy table section and,
* define __STARTUP_COPY_MULTIPLE in startup_psoc63_cm4.S */
. = 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__ = .;
/* To clear multiple BSS sections,
* uncomment zero table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_psoc63_cm4.S */
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
__zero_table_end__ = .;
} > flash
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > flash
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > flash
__exidx_end = .;
__etext = . ;
.ramVectors (NOLOAD) : ALIGN(8)
{
__ram_vectors_start__ = .;
KEEP(*(.ram_vectors))
__ram_vectors_end__ = .;
} > ram
.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);
KEEP(*(.cy_ramfunc*))
. = ALIGN(4);
__data_end__ = .;
} > ram
/* Place variables in the section that should not be initialized during the
* device startup.
*/
.noinit (NOLOAD) : ALIGN(8)
{
KEEP(*(.noinit))
} > ram
/* 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
.heap (NOLOAD):
{
__HeapBase = .;
__end__ = .;
end = __end__;
KEEP(*(.heap*))
__HeapLimit = .;
} > ram
/* .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
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(ram) + LENGTH(ram);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
/* Used for the digital signature of the secure application and the Bootloader SDK appication.
* The size of the section depends on the required data size. */
.cy_app_signature ORIGIN(flash) + LENGTH(flash) - 256 :
{
KEEP(*(.cy_app_signature))
} > flash
/* Emulated EEPROM Flash area */
.cy_em_eeprom :
{
KEEP(*(.cy_em_eeprom))
} > em_eeprom
/* Supervisory Flash: User data */
.cy_sflash_user_data :
{
KEEP(*(.cy_sflash_user_data))
} > sflash_user_data
/* Supervisory Flash: Normal Access Restrictions (NAR) */
.cy_sflash_nar :
{
KEEP(*(.cy_sflash_nar))
} > sflash_nar
/* Supervisory Flash: Public Key */
.cy_sflash_public_key :
{
KEEP(*(.cy_sflash_public_key))
} > sflash_public_key
/* Supervisory Flash: Table of Content # 2 */
.cy_toc_part2 :
{
KEEP(*(.cy_toc_part2))
} > sflash_toc_2
/* Supervisory Flash: Table of Content # 2 Copy */
.cy_rtoc_part2 :
{
KEEP(*(.cy_rtoc_part2))
} > sflash_rtoc_2
/* Places the code in the Execute in Place (XIP) section. See the smif driver
* documentation for details.
*/
.cy_xip :
{
KEEP(*(.cy_xip))
} > xip
/* eFuse */
.cy_efuse :
{
KEEP(*(.cy_efuse))
} > efuse
/* These sections are used for additional metadata (silicon revision,
* Silicon/JTAG ID, etc.) storage.
*/
.cymeta 0x90500000 : { KEEP(*(.cymeta)) } :NONE
}
/* The following symbols used by the cymcuelftool. */
/* Flash */
__cy_memory_0_start = 0x10000000;
__cy_memory_0_length = 0x00100000;
__cy_memory_0_row_size = 0x200;
/* Emulated EEPROM Flash area */
__cy_memory_1_start = 0x14000000;
__cy_memory_1_length = 0x8000;
__cy_memory_1_row_size = 0x200;
/* Supervisory Flash */
__cy_memory_2_start = 0x16000000;
__cy_memory_2_length = 0x8000;
__cy_memory_2_row_size = 0x200;
/* XIP */
__cy_memory_3_start = 0x18000000;
__cy_memory_3_length = 0x08000000;
__cy_memory_3_row_size = 0x200;
/* eFuse */
__cy_memory_4_start = 0x90700000;
__cy_memory_4_length = 0x100000;
__cy_memory_4_row_size = 1;
/* EOF */

View File

@ -0,0 +1,641 @@
/**************************************************************************//**
* @file startup_psoc63_cm4.s
* @brief CMSIS Core Device Startup File for
* ARMCM4 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 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 armv7-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 MemManage_Handler /* MPU Fault Handler */
.long BusFault_Handler /* Bus Fault Handler */
.long UsageFault_Handler /* Usage Fault Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long DebugMon_Handler /* Debug Monitor Handler */
.long 0 /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* External interrupts Description */
.long ioss_interrupts_gpio_0_IRQHandler /* GPIO Port Interrupt #0 */
.long ioss_interrupts_gpio_1_IRQHandler /* GPIO Port Interrupt #1 */
.long ioss_interrupts_gpio_2_IRQHandler /* GPIO Port Interrupt #2 */
.long ioss_interrupts_gpio_3_IRQHandler /* GPIO Port Interrupt #3 */
.long ioss_interrupts_gpio_4_IRQHandler /* GPIO Port Interrupt #4 */
.long ioss_interrupts_gpio_5_IRQHandler /* GPIO Port Interrupt #5 */
.long ioss_interrupts_gpio_6_IRQHandler /* GPIO Port Interrupt #6 */
.long ioss_interrupts_gpio_7_IRQHandler /* GPIO Port Interrupt #7 */
.long ioss_interrupts_gpio_8_IRQHandler /* GPIO Port Interrupt #8 */
.long ioss_interrupts_gpio_9_IRQHandler /* GPIO Port Interrupt #9 */
.long ioss_interrupts_gpio_10_IRQHandler /* GPIO Port Interrupt #10 */
.long ioss_interrupts_gpio_11_IRQHandler /* GPIO Port Interrupt #11 */
.long ioss_interrupts_gpio_12_IRQHandler /* GPIO Port Interrupt #12 */
.long ioss_interrupts_gpio_13_IRQHandler /* GPIO Port Interrupt #13 */
.long ioss_interrupts_gpio_14_IRQHandler /* GPIO Port Interrupt #14 */
.long ioss_interrupt_gpio_IRQHandler /* GPIO All Ports */
.long ioss_interrupt_vdd_IRQHandler /* GPIO Supply Detect Interrupt */
.long lpcomp_interrupt_IRQHandler /* Low Power Comparator Interrupt */
.long scb_8_interrupt_IRQHandler /* Serial Communication Block #8 (DeepSleep capable) */
.long srss_interrupt_mcwdt_0_IRQHandler /* Multi Counter Watchdog Timer interrupt */
.long srss_interrupt_mcwdt_1_IRQHandler /* Multi Counter Watchdog Timer interrupt */
.long srss_interrupt_backup_IRQHandler /* Backup domain interrupt */
.long srss_interrupt_IRQHandler /* Other combined Interrupts for SRSS (LVD, WDT, CLKCAL) */
.long pass_interrupt_ctbs_IRQHandler /* CTBm Interrupt (all CTBms) */
.long bless_interrupt_IRQHandler /* Bluetooth Radio interrupt */
.long cpuss_interrupts_ipc_0_IRQHandler /* CPUSS Inter Process Communication Interrupt #0 */
.long cpuss_interrupts_ipc_1_IRQHandler /* CPUSS Inter Process Communication Interrupt #1 */
.long cpuss_interrupts_ipc_2_IRQHandler /* CPUSS Inter Process Communication Interrupt #2 */
.long cpuss_interrupts_ipc_3_IRQHandler /* CPUSS Inter Process Communication Interrupt #3 */
.long cpuss_interrupts_ipc_4_IRQHandler /* CPUSS Inter Process Communication Interrupt #4 */
.long cpuss_interrupts_ipc_5_IRQHandler /* CPUSS Inter Process Communication Interrupt #5 */
.long cpuss_interrupts_ipc_6_IRQHandler /* CPUSS Inter Process Communication Interrupt #6 */
.long cpuss_interrupts_ipc_7_IRQHandler /* CPUSS Inter Process Communication Interrupt #7 */
.long cpuss_interrupts_ipc_8_IRQHandler /* CPUSS Inter Process Communication Interrupt #8 */
.long cpuss_interrupts_ipc_9_IRQHandler /* CPUSS Inter Process Communication Interrupt #9 */
.long cpuss_interrupts_ipc_10_IRQHandler /* CPUSS Inter Process Communication Interrupt #10 */
.long cpuss_interrupts_ipc_11_IRQHandler /* CPUSS Inter Process Communication Interrupt #11 */
.long cpuss_interrupts_ipc_12_IRQHandler /* CPUSS Inter Process Communication Interrupt #12 */
.long cpuss_interrupts_ipc_13_IRQHandler /* CPUSS Inter Process Communication Interrupt #13 */
.long cpuss_interrupts_ipc_14_IRQHandler /* CPUSS Inter Process Communication Interrupt #14 */
.long cpuss_interrupts_ipc_15_IRQHandler /* CPUSS Inter Process Communication Interrupt #15 */
.long scb_0_interrupt_IRQHandler /* Serial Communication Block #0 */
.long scb_1_interrupt_IRQHandler /* Serial Communication Block #1 */
.long scb_2_interrupt_IRQHandler /* Serial Communication Block #2 */
.long scb_3_interrupt_IRQHandler /* Serial Communication Block #3 */
.long scb_4_interrupt_IRQHandler /* Serial Communication Block #4 */
.long scb_5_interrupt_IRQHandler /* Serial Communication Block #5 */
.long scb_6_interrupt_IRQHandler /* Serial Communication Block #6 */
.long scb_7_interrupt_IRQHandler /* Serial Communication Block #7 */
.long csd_interrupt_IRQHandler /* CSD (Capsense) interrupt */
.long cpuss_interrupts_dw0_0_IRQHandler /* CPUSS DataWire #0, Channel #0 */
.long cpuss_interrupts_dw0_1_IRQHandler /* CPUSS DataWire #0, Channel #1 */
.long cpuss_interrupts_dw0_2_IRQHandler /* CPUSS DataWire #0, Channel #2 */
.long cpuss_interrupts_dw0_3_IRQHandler /* CPUSS DataWire #0, Channel #3 */
.long cpuss_interrupts_dw0_4_IRQHandler /* CPUSS DataWire #0, Channel #4 */
.long cpuss_interrupts_dw0_5_IRQHandler /* CPUSS DataWire #0, Channel #5 */
.long cpuss_interrupts_dw0_6_IRQHandler /* CPUSS DataWire #0, Channel #6 */
.long cpuss_interrupts_dw0_7_IRQHandler /* CPUSS DataWire #0, Channel #7 */
.long cpuss_interrupts_dw0_8_IRQHandler /* CPUSS DataWire #0, Channel #8 */
.long cpuss_interrupts_dw0_9_IRQHandler /* CPUSS DataWire #0, Channel #9 */
.long cpuss_interrupts_dw0_10_IRQHandler /* CPUSS DataWire #0, Channel #10 */
.long cpuss_interrupts_dw0_11_IRQHandler /* CPUSS DataWire #0, Channel #11 */
.long cpuss_interrupts_dw0_12_IRQHandler /* CPUSS DataWire #0, Channel #12 */
.long cpuss_interrupts_dw0_13_IRQHandler /* CPUSS DataWire #0, Channel #13 */
.long cpuss_interrupts_dw0_14_IRQHandler /* CPUSS DataWire #0, Channel #14 */
.long cpuss_interrupts_dw0_15_IRQHandler /* CPUSS DataWire #0, Channel #15 */
.long cpuss_interrupts_dw1_0_IRQHandler /* CPUSS DataWire #1, Channel #0 */
.long cpuss_interrupts_dw1_1_IRQHandler /* CPUSS DataWire #1, Channel #1 */
.long cpuss_interrupts_dw1_2_IRQHandler /* CPUSS DataWire #1, Channel #2 */
.long cpuss_interrupts_dw1_3_IRQHandler /* CPUSS DataWire #1, Channel #3 */
.long cpuss_interrupts_dw1_4_IRQHandler /* CPUSS DataWire #1, Channel #4 */
.long cpuss_interrupts_dw1_5_IRQHandler /* CPUSS DataWire #1, Channel #5 */
.long cpuss_interrupts_dw1_6_IRQHandler /* CPUSS DataWire #1, Channel #6 */
.long cpuss_interrupts_dw1_7_IRQHandler /* CPUSS DataWire #1, Channel #7 */
.long cpuss_interrupts_dw1_8_IRQHandler /* CPUSS DataWire #1, Channel #8 */
.long cpuss_interrupts_dw1_9_IRQHandler /* CPUSS DataWire #1, Channel #9 */
.long cpuss_interrupts_dw1_10_IRQHandler /* CPUSS DataWire #1, Channel #10 */
.long cpuss_interrupts_dw1_11_IRQHandler /* CPUSS DataWire #1, Channel #11 */
.long cpuss_interrupts_dw1_12_IRQHandler /* CPUSS DataWire #1, Channel #12 */
.long cpuss_interrupts_dw1_13_IRQHandler /* CPUSS DataWire #1, Channel #13 */
.long cpuss_interrupts_dw1_14_IRQHandler /* CPUSS DataWire #1, Channel #14 */
.long cpuss_interrupts_dw1_15_IRQHandler /* CPUSS DataWire #1, Channel #15 */
.long cpuss_interrupts_fault_0_IRQHandler /* CPUSS Fault Structure Interrupt #0 */
.long cpuss_interrupts_fault_1_IRQHandler /* CPUSS Fault Structure Interrupt #1 */
.long cpuss_interrupt_crypto_IRQHandler /* CRYPTO Accelerator Interrupt */
.long cpuss_interrupt_fm_IRQHandler /* FLASH Macro Interrupt */
.long cpuss_interrupts_cm0_cti_0_IRQHandler /* CM0+ CTI #0 */
.long cpuss_interrupts_cm0_cti_1_IRQHandler /* CM0+ CTI #1 */
.long cpuss_interrupts_cm4_cti_0_IRQHandler /* CM4 CTI #0 */
.long cpuss_interrupts_cm4_cti_1_IRQHandler /* CM4 CTI #1 */
.long tcpwm_0_interrupts_0_IRQHandler /* TCPWM #0, Counter #0 */
.long tcpwm_0_interrupts_1_IRQHandler /* TCPWM #0, Counter #1 */
.long tcpwm_0_interrupts_2_IRQHandler /* TCPWM #0, Counter #2 */
.long tcpwm_0_interrupts_3_IRQHandler /* TCPWM #0, Counter #3 */
.long tcpwm_0_interrupts_4_IRQHandler /* TCPWM #0, Counter #4 */
.long tcpwm_0_interrupts_5_IRQHandler /* TCPWM #0, Counter #5 */
.long tcpwm_0_interrupts_6_IRQHandler /* TCPWM #0, Counter #6 */
.long tcpwm_0_interrupts_7_IRQHandler /* TCPWM #0, Counter #7 */
.long tcpwm_1_interrupts_0_IRQHandler /* TCPWM #1, Counter #0 */
.long tcpwm_1_interrupts_1_IRQHandler /* TCPWM #1, Counter #1 */
.long tcpwm_1_interrupts_2_IRQHandler /* TCPWM #1, Counter #2 */
.long tcpwm_1_interrupts_3_IRQHandler /* TCPWM #1, Counter #3 */
.long tcpwm_1_interrupts_4_IRQHandler /* TCPWM #1, Counter #4 */
.long tcpwm_1_interrupts_5_IRQHandler /* TCPWM #1, Counter #5 */
.long tcpwm_1_interrupts_6_IRQHandler /* TCPWM #1, Counter #6 */
.long tcpwm_1_interrupts_7_IRQHandler /* TCPWM #1, Counter #7 */
.long tcpwm_1_interrupts_8_IRQHandler /* TCPWM #1, Counter #8 */
.long tcpwm_1_interrupts_9_IRQHandler /* TCPWM #1, Counter #9 */
.long tcpwm_1_interrupts_10_IRQHandler /* TCPWM #1, Counter #10 */
.long tcpwm_1_interrupts_11_IRQHandler /* TCPWM #1, Counter #11 */
.long tcpwm_1_interrupts_12_IRQHandler /* TCPWM #1, Counter #12 */
.long tcpwm_1_interrupts_13_IRQHandler /* TCPWM #1, Counter #13 */
.long tcpwm_1_interrupts_14_IRQHandler /* TCPWM #1, Counter #14 */
.long tcpwm_1_interrupts_15_IRQHandler /* TCPWM #1, Counter #15 */
.long tcpwm_1_interrupts_16_IRQHandler /* TCPWM #1, Counter #16 */
.long tcpwm_1_interrupts_17_IRQHandler /* TCPWM #1, Counter #17 */
.long tcpwm_1_interrupts_18_IRQHandler /* TCPWM #1, Counter #18 */
.long tcpwm_1_interrupts_19_IRQHandler /* TCPWM #1, Counter #19 */
.long tcpwm_1_interrupts_20_IRQHandler /* TCPWM #1, Counter #20 */
.long tcpwm_1_interrupts_21_IRQHandler /* TCPWM #1, Counter #21 */
.long tcpwm_1_interrupts_22_IRQHandler /* TCPWM #1, Counter #22 */
.long tcpwm_1_interrupts_23_IRQHandler /* TCPWM #1, Counter #23 */
.long udb_interrupts_0_IRQHandler /* UDB Interrupt #0 */
.long udb_interrupts_1_IRQHandler /* UDB Interrupt #1 */
.long udb_interrupts_2_IRQHandler /* UDB Interrupt #2 */
.long udb_interrupts_3_IRQHandler /* UDB Interrupt #3 */
.long udb_interrupts_4_IRQHandler /* UDB Interrupt #4 */
.long udb_interrupts_5_IRQHandler /* UDB Interrupt #5 */
.long udb_interrupts_6_IRQHandler /* UDB Interrupt #6 */
.long udb_interrupts_7_IRQHandler /* UDB Interrupt #7 */
.long udb_interrupts_8_IRQHandler /* UDB Interrupt #8 */
.long udb_interrupts_9_IRQHandler /* UDB Interrupt #9 */
.long udb_interrupts_10_IRQHandler /* UDB Interrupt #10 */
.long udb_interrupts_11_IRQHandler /* UDB Interrupt #11 */
.long udb_interrupts_12_IRQHandler /* UDB Interrupt #12 */
.long udb_interrupts_13_IRQHandler /* UDB Interrupt #13 */
.long udb_interrupts_14_IRQHandler /* UDB Interrupt #14 */
.long udb_interrupts_15_IRQHandler /* UDB Interrupt #15 */
.long pass_interrupt_sar_IRQHandler /* SAR ADC interrupt */
.long audioss_interrupt_i2s_IRQHandler /* I2S Audio interrupt */
.long audioss_interrupt_pdm_IRQHandler /* PDM/PCM Audio interrupt */
.long profile_interrupt_IRQHandler /* Energy Profiler interrupt */
.long smif_interrupt_IRQHandler /* Serial Memory Interface interrupt */
.long usb_interrupt_hi_IRQHandler /* USB Interrupt */
.long usb_interrupt_med_IRQHandler /* USB Interrupt */
.long usb_interrupt_lo_IRQHandler /* USB Interrupt */
.long pass_interrupt_dacs_IRQHandler /* Consolidated interrrupt for all DACs */
.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
/* Firstly it copies data from read only memory to RAM. There are two schemes
* to copy. One can copy more than one sections. Another can only copy
* one section. The former scheme needs more instructions and read-only
* data to implement than the latter.
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
#ifdef __STARTUP_COPY_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of triplets, each of which specify:
* offset 0: LMA of start of a section to copy from
* offset 4: VMA of start of a section to copy to
* offset 8: size of the section to copy. Must be multiply of 4
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r4, =__copy_table_start__
ldr r5, =__copy_table_end__
.L_loop0:
cmp r4, r5
bge .L_loop0_done
ldr r1, [r4]
ldr r2, [r4, #4]
ldr r3, [r4, #8]
.L_loop0_0:
subs r3, #4
ittt ge
ldrge r0, [r1, r3]
strge r0, [r2, r3]
bge .L_loop0_0
adds r4, #12
b .L_loop0
.L_loop0_done:
#else
/* Single section scheme.
*
* The ranges of copy from/to are specified by following symbols
* __etext: LMA of start of the section to copy from. Usually end of text
* __data_start__: VMA of start of the section to copy to
* __data_end__: VMA of end of the section to copy to
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
.L_loop1:
cmp r2, r3
ittt lt
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt .L_loop1
#endif /*__STARTUP_COPY_MULTIPLE */
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
* There are two schemes too. One can clear multiple BSS sections. Another
* can only clear one section. The former is more size expensive than the
* latter.
*
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
* Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
*/
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of tuples specifying:
* offset 0: Start of a BSS section
* offset 4: Size of this BSS section. Must be multiply of 4
*/
ldr r3, =__zero_table_start__
ldr r4, =__zero_table_end__
.L_loop2:
cmp r3, r4
bge .L_loop2_done
ldr r1, [r3]
ldr r2, [r3, #4]
movs r0, 0
.L_loop2_0:
subs r2, #4
itt ge
strge r0, [r1, r2]
bge .L_loop2_0
adds r3, #8
b .L_loop2
.L_loop2_done:
#elif defined (__STARTUP_CLEAR_BSS)
/* Single BSS section scheme.
*
* The BSS section is specified by following symbols
* __bss_start__: start of the BSS section.
* __bss_end__: end of the BSS section.
*
* Both addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__bss_start__
ldr r2, =__bss_end__
movs r0, 0
.L_loop3:
cmp r1, r2
itt lt
strlt r0, [r1], #4
blt .L_loop3
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
/* Update Vector Table Offset Register. */
ldr r0, =__ramVectors
ldr r1, =CY_CPU_VTOR_ADDR
str r0, [r1]
dsb 0xF
/* Enable the FPU if used */
bl Cy_SystemInitFpuEnable
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_fault_Handler MemManage_Handler
def_fault_Handler BusFault_Handler
def_fault_Handler UsageFault_Handler
def_irq_handler SVC_Handler
def_irq_handler DebugMon_Handler
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
def_irq_handler ioss_interrupts_gpio_0_IRQHandler /* GPIO Port Interrupt #0 */
def_irq_handler ioss_interrupts_gpio_1_IRQHandler /* GPIO Port Interrupt #1 */
def_irq_handler ioss_interrupts_gpio_2_IRQHandler /* GPIO Port Interrupt #2 */
def_irq_handler ioss_interrupts_gpio_3_IRQHandler /* GPIO Port Interrupt #3 */
def_irq_handler ioss_interrupts_gpio_4_IRQHandler /* GPIO Port Interrupt #4 */
def_irq_handler ioss_interrupts_gpio_5_IRQHandler /* GPIO Port Interrupt #5 */
def_irq_handler ioss_interrupts_gpio_6_IRQHandler /* GPIO Port Interrupt #6 */
def_irq_handler ioss_interrupts_gpio_7_IRQHandler /* GPIO Port Interrupt #7 */
def_irq_handler ioss_interrupts_gpio_8_IRQHandler /* GPIO Port Interrupt #8 */
def_irq_handler ioss_interrupts_gpio_9_IRQHandler /* GPIO Port Interrupt #9 */
def_irq_handler ioss_interrupts_gpio_10_IRQHandler /* GPIO Port Interrupt #10 */
def_irq_handler ioss_interrupts_gpio_11_IRQHandler /* GPIO Port Interrupt #11 */
def_irq_handler ioss_interrupts_gpio_12_IRQHandler /* GPIO Port Interrupt #12 */
def_irq_handler ioss_interrupts_gpio_13_IRQHandler /* GPIO Port Interrupt #13 */
def_irq_handler ioss_interrupts_gpio_14_IRQHandler /* GPIO Port Interrupt #14 */
def_irq_handler ioss_interrupt_gpio_IRQHandler /* GPIO All Ports */
def_irq_handler ioss_interrupt_vdd_IRQHandler /* GPIO Supply Detect Interrupt */
def_irq_handler lpcomp_interrupt_IRQHandler /* Low Power Comparator Interrupt */
def_irq_handler scb_8_interrupt_IRQHandler /* Serial Communication Block #8 (DeepSleep capable) */
def_irq_handler srss_interrupt_mcwdt_0_IRQHandler /* Multi Counter Watchdog Timer interrupt */
def_irq_handler srss_interrupt_mcwdt_1_IRQHandler /* Multi Counter Watchdog Timer interrupt */
def_irq_handler srss_interrupt_backup_IRQHandler /* Backup domain interrupt */
def_irq_handler srss_interrupt_IRQHandler /* Other combined Interrupts for SRSS (LVD, WDT, CLKCAL) */
def_irq_handler pass_interrupt_ctbs_IRQHandler /* CTBm Interrupt (all CTBms) */
def_irq_handler bless_interrupt_IRQHandler /* Bluetooth Radio interrupt */
def_irq_handler cpuss_interrupts_ipc_0_IRQHandler /* CPUSS Inter Process Communication Interrupt #0 */
def_irq_handler cpuss_interrupts_ipc_1_IRQHandler /* CPUSS Inter Process Communication Interrupt #1 */
def_irq_handler cpuss_interrupts_ipc_2_IRQHandler /* CPUSS Inter Process Communication Interrupt #2 */
def_irq_handler cpuss_interrupts_ipc_3_IRQHandler /* CPUSS Inter Process Communication Interrupt #3 */
def_irq_handler cpuss_interrupts_ipc_4_IRQHandler /* CPUSS Inter Process Communication Interrupt #4 */
def_irq_handler cpuss_interrupts_ipc_5_IRQHandler /* CPUSS Inter Process Communication Interrupt #5 */
def_irq_handler cpuss_interrupts_ipc_6_IRQHandler /* CPUSS Inter Process Communication Interrupt #6 */
def_irq_handler cpuss_interrupts_ipc_7_IRQHandler /* CPUSS Inter Process Communication Interrupt #7 */
def_irq_handler cpuss_interrupts_ipc_8_IRQHandler /* CPUSS Inter Process Communication Interrupt #8 */
def_irq_handler cpuss_interrupts_ipc_9_IRQHandler /* CPUSS Inter Process Communication Interrupt #9 */
def_irq_handler cpuss_interrupts_ipc_10_IRQHandler /* CPUSS Inter Process Communication Interrupt #10 */
def_irq_handler cpuss_interrupts_ipc_11_IRQHandler /* CPUSS Inter Process Communication Interrupt #11 */
def_irq_handler cpuss_interrupts_ipc_12_IRQHandler /* CPUSS Inter Process Communication Interrupt #12 */
def_irq_handler cpuss_interrupts_ipc_13_IRQHandler /* CPUSS Inter Process Communication Interrupt #13 */
def_irq_handler cpuss_interrupts_ipc_14_IRQHandler /* CPUSS Inter Process Communication Interrupt #14 */
def_irq_handler cpuss_interrupts_ipc_15_IRQHandler /* CPUSS Inter Process Communication Interrupt #15 */
def_irq_handler scb_0_interrupt_IRQHandler /* Serial Communication Block #0 */
def_irq_handler scb_1_interrupt_IRQHandler /* Serial Communication Block #1 */
def_irq_handler scb_2_interrupt_IRQHandler /* Serial Communication Block #2 */
def_irq_handler scb_3_interrupt_IRQHandler /* Serial Communication Block #3 */
def_irq_handler scb_4_interrupt_IRQHandler /* Serial Communication Block #4 */
def_irq_handler scb_5_interrupt_IRQHandler /* Serial Communication Block #5 */
def_irq_handler scb_6_interrupt_IRQHandler /* Serial Communication Block #6 */
def_irq_handler scb_7_interrupt_IRQHandler /* Serial Communication Block #7 */
def_irq_handler csd_interrupt_IRQHandler /* CSD (Capsense) interrupt */
def_irq_handler cpuss_interrupts_dw0_0_IRQHandler /* CPUSS DataWire #0, Channel #0 */
def_irq_handler cpuss_interrupts_dw0_1_IRQHandler /* CPUSS DataWire #0, Channel #1 */
def_irq_handler cpuss_interrupts_dw0_2_IRQHandler /* CPUSS DataWire #0, Channel #2 */
def_irq_handler cpuss_interrupts_dw0_3_IRQHandler /* CPUSS DataWire #0, Channel #3 */
def_irq_handler cpuss_interrupts_dw0_4_IRQHandler /* CPUSS DataWire #0, Channel #4 */
def_irq_handler cpuss_interrupts_dw0_5_IRQHandler /* CPUSS DataWire #0, Channel #5 */
def_irq_handler cpuss_interrupts_dw0_6_IRQHandler /* CPUSS DataWire #0, Channel #6 */
def_irq_handler cpuss_interrupts_dw0_7_IRQHandler /* CPUSS DataWire #0, Channel #7 */
def_irq_handler cpuss_interrupts_dw0_8_IRQHandler /* CPUSS DataWire #0, Channel #8 */
def_irq_handler cpuss_interrupts_dw0_9_IRQHandler /* CPUSS DataWire #0, Channel #9 */
def_irq_handler cpuss_interrupts_dw0_10_IRQHandler /* CPUSS DataWire #0, Channel #10 */
def_irq_handler cpuss_interrupts_dw0_11_IRQHandler /* CPUSS DataWire #0, Channel #11 */
def_irq_handler cpuss_interrupts_dw0_12_IRQHandler /* CPUSS DataWire #0, Channel #12 */
def_irq_handler cpuss_interrupts_dw0_13_IRQHandler /* CPUSS DataWire #0, Channel #13 */
def_irq_handler cpuss_interrupts_dw0_14_IRQHandler /* CPUSS DataWire #0, Channel #14 */
def_irq_handler cpuss_interrupts_dw0_15_IRQHandler /* CPUSS DataWire #0, Channel #15 */
def_irq_handler cpuss_interrupts_dw1_0_IRQHandler /* CPUSS DataWire #1, Channel #0 */
def_irq_handler cpuss_interrupts_dw1_1_IRQHandler /* CPUSS DataWire #1, Channel #1 */
def_irq_handler cpuss_interrupts_dw1_2_IRQHandler /* CPUSS DataWire #1, Channel #2 */
def_irq_handler cpuss_interrupts_dw1_3_IRQHandler /* CPUSS DataWire #1, Channel #3 */
def_irq_handler cpuss_interrupts_dw1_4_IRQHandler /* CPUSS DataWire #1, Channel #4 */
def_irq_handler cpuss_interrupts_dw1_5_IRQHandler /* CPUSS DataWire #1, Channel #5 */
def_irq_handler cpuss_interrupts_dw1_6_IRQHandler /* CPUSS DataWire #1, Channel #6 */
def_irq_handler cpuss_interrupts_dw1_7_IRQHandler /* CPUSS DataWire #1, Channel #7 */
def_irq_handler cpuss_interrupts_dw1_8_IRQHandler /* CPUSS DataWire #1, Channel #8 */
def_irq_handler cpuss_interrupts_dw1_9_IRQHandler /* CPUSS DataWire #1, Channel #9 */
def_irq_handler cpuss_interrupts_dw1_10_IRQHandler /* CPUSS DataWire #1, Channel #10 */
def_irq_handler cpuss_interrupts_dw1_11_IRQHandler /* CPUSS DataWire #1, Channel #11 */
def_irq_handler cpuss_interrupts_dw1_12_IRQHandler /* CPUSS DataWire #1, Channel #12 */
def_irq_handler cpuss_interrupts_dw1_13_IRQHandler /* CPUSS DataWire #1, Channel #13 */
def_irq_handler cpuss_interrupts_dw1_14_IRQHandler /* CPUSS DataWire #1, Channel #14 */
def_irq_handler cpuss_interrupts_dw1_15_IRQHandler /* CPUSS DataWire #1, Channel #15 */
def_irq_handler cpuss_interrupts_fault_0_IRQHandler /* CPUSS Fault Structure Interrupt #0 */
def_irq_handler cpuss_interrupts_fault_1_IRQHandler /* CPUSS Fault Structure Interrupt #1 */
def_irq_handler cpuss_interrupt_crypto_IRQHandler /* CRYPTO Accelerator Interrupt */
def_irq_handler cpuss_interrupt_fm_IRQHandler /* FLASH Macro Interrupt */
def_irq_handler cpuss_interrupts_cm0_cti_0_IRQHandler /* CM0+ CTI #0 */
def_irq_handler cpuss_interrupts_cm0_cti_1_IRQHandler /* CM0+ CTI #1 */
def_irq_handler cpuss_interrupts_cm4_cti_0_IRQHandler /* CM4 CTI #0 */
def_irq_handler cpuss_interrupts_cm4_cti_1_IRQHandler /* CM4 CTI #1 */
def_irq_handler tcpwm_0_interrupts_0_IRQHandler /* TCPWM #0, Counter #0 */
def_irq_handler tcpwm_0_interrupts_1_IRQHandler /* TCPWM #0, Counter #1 */
def_irq_handler tcpwm_0_interrupts_2_IRQHandler /* TCPWM #0, Counter #2 */
def_irq_handler tcpwm_0_interrupts_3_IRQHandler /* TCPWM #0, Counter #3 */
def_irq_handler tcpwm_0_interrupts_4_IRQHandler /* TCPWM #0, Counter #4 */
def_irq_handler tcpwm_0_interrupts_5_IRQHandler /* TCPWM #0, Counter #5 */
def_irq_handler tcpwm_0_interrupts_6_IRQHandler /* TCPWM #0, Counter #6 */
def_irq_handler tcpwm_0_interrupts_7_IRQHandler /* TCPWM #0, Counter #7 */
def_irq_handler tcpwm_1_interrupts_0_IRQHandler /* TCPWM #1, Counter #0 */
def_irq_handler tcpwm_1_interrupts_1_IRQHandler /* TCPWM #1, Counter #1 */
def_irq_handler tcpwm_1_interrupts_2_IRQHandler /* TCPWM #1, Counter #2 */
def_irq_handler tcpwm_1_interrupts_3_IRQHandler /* TCPWM #1, Counter #3 */
def_irq_handler tcpwm_1_interrupts_4_IRQHandler /* TCPWM #1, Counter #4 */
def_irq_handler tcpwm_1_interrupts_5_IRQHandler /* TCPWM #1, Counter #5 */
def_irq_handler tcpwm_1_interrupts_6_IRQHandler /* TCPWM #1, Counter #6 */
def_irq_handler tcpwm_1_interrupts_7_IRQHandler /* TCPWM #1, Counter #7 */
def_irq_handler tcpwm_1_interrupts_8_IRQHandler /* TCPWM #1, Counter #8 */
def_irq_handler tcpwm_1_interrupts_9_IRQHandler /* TCPWM #1, Counter #9 */
def_irq_handler tcpwm_1_interrupts_10_IRQHandler /* TCPWM #1, Counter #10 */
def_irq_handler tcpwm_1_interrupts_11_IRQHandler /* TCPWM #1, Counter #11 */
def_irq_handler tcpwm_1_interrupts_12_IRQHandler /* TCPWM #1, Counter #12 */
def_irq_handler tcpwm_1_interrupts_13_IRQHandler /* TCPWM #1, Counter #13 */
def_irq_handler tcpwm_1_interrupts_14_IRQHandler /* TCPWM #1, Counter #14 */
def_irq_handler tcpwm_1_interrupts_15_IRQHandler /* TCPWM #1, Counter #15 */
def_irq_handler tcpwm_1_interrupts_16_IRQHandler /* TCPWM #1, Counter #16 */
def_irq_handler tcpwm_1_interrupts_17_IRQHandler /* TCPWM #1, Counter #17 */
def_irq_handler tcpwm_1_interrupts_18_IRQHandler /* TCPWM #1, Counter #18 */
def_irq_handler tcpwm_1_interrupts_19_IRQHandler /* TCPWM #1, Counter #19 */
def_irq_handler tcpwm_1_interrupts_20_IRQHandler /* TCPWM #1, Counter #20 */
def_irq_handler tcpwm_1_interrupts_21_IRQHandler /* TCPWM #1, Counter #21 */
def_irq_handler tcpwm_1_interrupts_22_IRQHandler /* TCPWM #1, Counter #22 */
def_irq_handler tcpwm_1_interrupts_23_IRQHandler /* TCPWM #1, Counter #23 */
def_irq_handler udb_interrupts_0_IRQHandler /* UDB Interrupt #0 */
def_irq_handler udb_interrupts_1_IRQHandler /* UDB Interrupt #1 */
def_irq_handler udb_interrupts_2_IRQHandler /* UDB Interrupt #2 */
def_irq_handler udb_interrupts_3_IRQHandler /* UDB Interrupt #3 */
def_irq_handler udb_interrupts_4_IRQHandler /* UDB Interrupt #4 */
def_irq_handler udb_interrupts_5_IRQHandler /* UDB Interrupt #5 */
def_irq_handler udb_interrupts_6_IRQHandler /* UDB Interrupt #6 */
def_irq_handler udb_interrupts_7_IRQHandler /* UDB Interrupt #7 */
def_irq_handler udb_interrupts_8_IRQHandler /* UDB Interrupt #8 */
def_irq_handler udb_interrupts_9_IRQHandler /* UDB Interrupt #9 */
def_irq_handler udb_interrupts_10_IRQHandler /* UDB Interrupt #10 */
def_irq_handler udb_interrupts_11_IRQHandler /* UDB Interrupt #11 */
def_irq_handler udb_interrupts_12_IRQHandler /* UDB Interrupt #12 */
def_irq_handler udb_interrupts_13_IRQHandler /* UDB Interrupt #13 */
def_irq_handler udb_interrupts_14_IRQHandler /* UDB Interrupt #14 */
def_irq_handler udb_interrupts_15_IRQHandler /* UDB Interrupt #15 */
def_irq_handler pass_interrupt_sar_IRQHandler /* SAR ADC interrupt */
def_irq_handler audioss_interrupt_i2s_IRQHandler /* I2S Audio interrupt */
def_irq_handler audioss_interrupt_pdm_IRQHandler /* PDM/PCM Audio interrupt */
def_irq_handler profile_interrupt_IRQHandler /* Energy Profiler interrupt */
def_irq_handler smif_interrupt_IRQHandler /* Serial Memory Interface interrupt */
def_irq_handler usb_interrupt_hi_IRQHandler /* USB Interrupt */
def_irq_handler usb_interrupt_med_IRQHandler /* USB Interrupt */
def_irq_handler usb_interrupt_lo_IRQHandler /* USB Interrupt */
def_irq_handler pass_interrupt_dacs_IRQHandler /* Consolidated interrrupt for all DACs */
.end
/* [] END OF FILE */

View File

@ -0,0 +1,217 @@
/***************************************************************************//**
* \file cy8c6xx7_cm4_dual.icf
* \version 2.10
*
* Linker file for the IAR compiler.
*
* The main purpose of the linker script is to describe how the sections in the
* input files should be mapped into the output file, and to control the memory
* layout of the output file.
*
* \note The entry point 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-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/* The symbols below define the location and size of blocks of memory in the target.
* Use these symbols to specify the memory regions available for allocation.
*/
/* The following symbols control RAM and flash memory allocation for the CM4 core.
* You can change the memory allocation by editing RAM and Flash symbols.
* Note that 2 KB of RAM (at the end of the RAM section) are reserved for system use.
* Using this memory region for other purposes will lead to unexpected behavior.
* Your changes must be aligned with the corresponding symbols for CM0+ core in 'xx_cm0plus.icf',
* where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.icf'.
*/
/* RAM */
define symbol __ICFEDIT_region_IRAM1_start__ = 0x08010000;
define symbol __ICFEDIT_region_IRAM1_end__ = 0x08047800;
/* Flash */
define symbol __ICFEDIT_region_IROM1_start__ = 0x10080000;
define symbol __ICFEDIT_region_IROM1_end__ = 0x100F8000;
/* The following symbols define a 32K flash region used for EEPROM emulation.
* This region can also be used as the general purpose flash.
* You can assign sections to this memory region for only one of the cores.
* Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region.
* Therefore, repurposing this memory region will prevent such middleware from operation.
*/
define symbol __ICFEDIT_region_IROM2_start__ = 0x14000000;
define symbol __ICFEDIT_region_IROM2_end__ = 0x14007FFF;
/* The following symbols define device specific memory regions and must not be changed. */
/* Supervisory FLASH - User Data */
define symbol __ICFEDIT_region_IROM3_start__ = 0x16000800;
define symbol __ICFEDIT_region_IROM3_end__ = 0x160007FF;
/* Supervisory FLASH - Normal Access Restrictions (NAR) */
define symbol __ICFEDIT_region_IROM4_start__ = 0x16001A00;
define symbol __ICFEDIT_region_IROM4_end__ = 0x16001BFF;
/* Supervisory FLASH - Public Key */
define symbol __ICFEDIT_region_IROM5_start__ = 0x16005A00;
define symbol __ICFEDIT_region_IROM5_end__ = 0x160065FF;
/* Supervisory FLASH - Table of Content # 2 */
define symbol __ICFEDIT_region_IROM6_start__ = 0x16007C00;
define symbol __ICFEDIT_region_IROM6_end__ = 0x16007DFF;
/* Supervisory FLASH - Table of Content # 2 Copy */
define symbol __ICFEDIT_region_IROM7_start__ = 0x16007E00;
define symbol __ICFEDIT_region_IROM7_end__ = 0x16007FFF;
/* eFuse */
define symbol __ICFEDIT_region_IROM8_start__ = 0x90700000;
define symbol __ICFEDIT_region_IROM8_end__ = 0x907FFFFF;
/* XIP */
define symbol __ICFEDIT_region_EROM1_start__ = 0x18000000;
define symbol __ICFEDIT_region_EROM1_end__ = 0x1FFFFFFF;
define symbol __ICFEDIT_region_EROM2_start__ = 0x0;
define symbol __ICFEDIT_region_EROM2_end__ = 0x0;
define symbol __ICFEDIT_region_EROM3_start__ = 0x0;
define symbol __ICFEDIT_region_EROM3_end__ = 0x0;
define symbol __ICFEDIT_region_IRAM2_start__ = 0x0;
define symbol __ICFEDIT_region_IRAM2_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM1_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM1_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM2_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM2_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM3_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM3_end__ = 0x0;
/*-Sizes-*/
if (!isdefinedsymbol(__STACK_SIZE)) {
define symbol __ICFEDIT_size_cstack__ = 0x1000;
} else {
define symbol __ICFEDIT_size_cstack__ = __STACK_SIZE;
}
define symbol __ICFEDIT_size_proc_stack__ = 0x0;
if (!isdefinedsymbol(__HEAP_SIZE)) {
define symbol __ICFEDIT_size_heap__ = 0x3800;
} else {
define symbol __ICFEDIT_size_heap__ = __HEAP_SIZE;
}
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__];
define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__];
define region IROM3_region = mem:[from __ICFEDIT_region_IROM3_start__ to __ICFEDIT_region_IROM3_end__];
define region IROM4_region = mem:[from __ICFEDIT_region_IROM4_start__ to __ICFEDIT_region_IROM4_end__];
define region IROM5_region = mem:[from __ICFEDIT_region_IROM5_start__ to __ICFEDIT_region_IROM5_end__];
define region IROM6_region = mem:[from __ICFEDIT_region_IROM6_start__ to __ICFEDIT_region_IROM6_end__];
define region IROM7_region = mem:[from __ICFEDIT_region_IROM7_start__ to __ICFEDIT_region_IROM7_end__];
define region IROM8_region = mem:[from __ICFEDIT_region_IROM8_start__ to __ICFEDIT_region_IROM8_end__];
define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__];
define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
define block HSTACK {block HEAP, block PROC_STACK, last block CSTACK};
define block RO {first section .intvec, readonly};
/*-Initializations-*/
initialize by copy { readwrite };
do not initialize { section .noinit, section .intvec_ram };
/*-Placement-*/
/* Flash */
place at start of IROM1_region { block RO };
".cy_app_signature" : place at address (__ICFEDIT_region_IROM1_end__ - 0x200) { section .cy_app_signature };
/* Emulated EEPROM Flash area */
".cy_em_eeprom" : place at start of IROM2_region { section .cy_em_eeprom };
/* Supervisory Flash - User Data */
".cy_sflash_user_data" : place at start of IROM3_region { section .cy_sflash_user_data };
/* Supervisory Flash - NAR */
".cy_sflash_nar" : place at start of IROM4_region { section .cy_sflash_nar };
/* Supervisory Flash - Public Key */
".cy_sflash_public_key" : place at start of IROM5_region { section .cy_sflash_public_key };
/* Supervisory Flash - TOC2 */
".cy_toc_part2" : place at start of IROM6_region { section .cy_toc_part2 };
/* Supervisory Flash - RTOC2 */
".cy_rtoc_part2" : place at start of IROM7_region { section .cy_rtoc_part2 };
/* eFuse */
".cy_efuse" : place at start of IROM8_region { section .cy_efuse };
/* Execute in Place (XIP). See the smif driver documentation for details. */
".cy_xip" : place at start of EROM1_region { section .cy_xip };
/* RAM */
place at start of IRAM1_region { readwrite section .intvec_ram};
place in IRAM1_region { readwrite };
place at end of IRAM1_region { block HSTACK };
/* These sections are used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. */
".cymeta" : place at address mem : 0x90500000 { readonly section .cymeta };
keep { section .cy_app_signature,
section .cy_em_eeprom,
section .cy_sflash_user_data,
section .cy_sflash_nar,
section .cy_sflash_public_key,
section .cy_toc_part2,
section .cy_rtoc_part2,
section .cy_efuse,
section .cy_xip,
section .cymeta,
};
/* The following symbols used by the cymcuelftool. */
/* Flash */
define exported symbol __cy_memory_0_start = 0x10000000;
define exported symbol __cy_memory_0_length = 0x00100000;
define exported symbol __cy_memory_0_row_size = 0x200;
/* Emulated EEPROM Flash area */
define exported symbol __cy_memory_1_start = 0x14000000;
define exported symbol __cy_memory_1_length = 0x8000;
define exported symbol __cy_memory_1_row_size = 0x200;
/* Supervisory Flash */
define exported symbol __cy_memory_2_start = 0x16000000;
define exported symbol __cy_memory_2_length = 0x8000;
define exported symbol __cy_memory_2_row_size = 0x200;
/* XIP */
define exported symbol __cy_memory_3_start = 0x18000000;
define exported symbol __cy_memory_3_length = 0x08000000;
define exported symbol __cy_memory_3_row_size = 0x200;
/* eFuse */
define exported symbol __cy_memory_4_start = 0x90700000;
define exported symbol __cy_memory_4_length = 0x100000;
define exported symbol __cy_memory_4_row_size = 1;
/* EOF */

View File

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

View File

@ -0,0 +1,16 @@
README for pre-compiled PSoC 6 Cortex M0+ core images
=====================================================
This folder contains precompiled program images for the CM0+ core of the PSoC 6(63xx) MCU suitable for use with MBed OS applications running on CM4 core. Two images are available:
* `psoc63_m0_default_1.01.hex`
This image contains basic code, that brings up the chip, starts CM4 core and puts CM0+ core into a deep sleep. It is suitable for use with all Mbed applications except those intendif to use BLE feature.
* `psoc63_m0_ble_controller_1.01.hex`
This image brings up the chip, starts CM4 core and runs BLE HCI controller for the build-in BLE device. This image is suitable for use with Mbed BLE applications.
The images are 'bare metal' code prepared with Cypress PSoC Creator IDE and are toolchain agnostic, i.e. can be used with CM4 Mbed applications build with any supported toolchain.
**These images were prepared by Future Electronics and are made available under the conditions of Permissive Binary Licence, see file LICENSE.txt**

View File

@ -0,0 +1,150 @@
:020000041000EA
:4000000000000108310100100D00000095010010000000000000000000000000000000000000000000000000000000009101001000000000000000009101001091010010DC
:4000400091010010F10700109101001091010010910100109101001091010010910100109101001091010010910100109101001091010010910100109101001091010010FA
:400080009101001091010010910100109101001091010010910100109101001091010010910100109101001091010010910100109101001091010010910100109101001020
:4000C00010B5064C2378002B07D1054B002B02D0044800E000BF0123237010BD4804000800000000541F0010084B10B5002B03D00749084800E000BF07480368002B00D1AD
:4001000010BD064B002BFBD09847F9E7000000004C040008541F001044010008000000007047EFF3108072B6704780F310887047FFF7F6FF72B6104C104DAC4209DA2168D4
:400140006268A368043B02DBC858D050FAE70C34F3E70B490B4A0020521A02DD043A8850FCDC094809490860BFF34F8F00F0ECF800F01EF8FEE70000581F0010701F0010D1
:4001800048040008380700080000000808ED00E0FEE7FEE700B504207146084202D0EFF3098001E0EFF30880043001F08DFAFEE710B500F0A5F962B6064B5B689B0301D517
:4001C00001F044FA044800F02FF9002001F090F9FBE7C0460000264000000810F8B5E023504C9B00E2580F231340D022990092000919885807224C4D0240032A05D0042A73
:4002000005D0002A0FD0494811E028680FE0C022920089581F220A40112A01D0132A04D18020000203E0424801E0FA20C001002B27D1B223B1210322DB00C900E65863588A
:4002400067581B0F3F0F1340174205D0354F7958090F0A40012A01D1F20701D4032B3AD1B023344ADB00E658A158E758C904C90C01F050FDB603F901B60BC90F7043013158
:4002800027E0012B27D1C823C0210322DB00C900E658635867583F0F174205D0214F7958090F0A40012A01D1F20703D49B009B0F032B10D1C0227F23D200A758A1583B40BD
:4002C0001F27A658090A3940584301F023FD310C394001F01FFDE0239B00E3589B069B0FD840154B68601C691969240A090E013101F010FDE1B2A860013101F00BFD0F4BBF
:40030000E860286104000E49C01801F003FDFA210C4B28758900E01801F0FCFCA861C003E861F8BD00002640C000000800366E0100127A0084050000000021403F420F00AC
:4003400040420F00E7030000B021E02010B530241F4BC9005A588000520052085A501A58A2431A50802252045A501A491A4A80209950A021043289019950FF21174AC005FA
:40038000995081315A5892009208024380205A505A580006024301205A505A5882435A5000F054FAFFF71AFF00F02AFA00F032FA00F0B8FEB0235B055A78002A02D05B7855
:4003C000212B03D10022064BDA605A6010BDC0460000264001000200840500008C050000E0002340024BD86F032318407047C0460400214010B5FFF794FE074A074BD16F79
:400400000B4007490B43D367102306490A681A42FCD0FFF78AFE10BD04002140FCFF00000100FA058800214070B50F4C0600FFF778FEE36F0500DB439B0701D1FFF7DAFF3F
:40044000B0230A4A9B00D650E26F094B09491340094A1343E36710230A681A42FCD02800FFF763FE70BDC0460400214000002140FCFF0000880021400300FA0510B5040063
:40048000007B00F0F3F8606010BD10B50400007B216900F0B5F8606010BD10B5037B0169180000F0CDF810BD10B50400C06800F009F9606010BD10B5C06800F017F910BDF0
:4004C00010B50400C06800F023F9606010BD10B5C06800F037F910BD10B504000C23C05E00F056F8606010BD10B50C23C05E00F06FF810BD10B5C06800F036F910BD0000A8
:4005000010B500221849042000F0A4FC01221749042000F09FFC02221549042000F09AFC03221449042000F095FC04221249100000F090FC05221149042000F08BFC0622E9
:400540000F49042000F086FC07220E49042000F081FC08220C49042000F07CFC09220B49042000F077FC10BD7D0400108B0400109B040010A9040010B7040010C104001062
:40058000CF040010D9040010E9040010F504001070B507260512EDB206400D2D11D801F0F8F80A4901224B5D1C003441144003D1B24013434B5501E00124644201F0EDF8D2
:4005C00001E001246442200070BDC0466404000870B50412E4B20D2C0FD80725054001F0D8F8064901220B5D1E002E41164202D0AA4093430B5501F0D0F870BD6404000862
:40060000F8B50C00050001F0C4F80C2301225D431300A3401A00094E71198F683A4008D13B43AD598B60631C4B60AB4202D94A6000E0FF2401F0B1F82000F8BDE0000008BD
:4006400070B50C00050001F0A4F801210C23A1406B43054AD3189A680A4201D08A439A6001F09BF870BDC046E0000008F0B50C2485B0019001F08DF8019B114D5C432B192A
:400680005B68029003932E1971680198FFF7B8FF0700FF280DD173682A59934201D9002373602A1953680399994202D001335360E9E7029801F071F8380005B0F0BDC04648
:4006C000E000000810B5040007280AD801F061F8054B0E331A5D002A01D101321A5501F05CF80120404210BD6404000810B5040007280AD801F04DF8044B0E331A5D012AE1
:4007000001D100221A5501F048F810BD6404000870B505001F280ED801F03BF8084B30335C5D002C02D101225A5501E00124644201F033F801E001246442200070BDC04666
:40074000E000000810B504001F280AD801F021F8044B30331A5D012A01D100221A5501F01CF810BDE000000870B5B024C025144B144A15496405ED00E35CA25C615C665D18
:400780003F251F242A400C4024039201224311002B407F2219430B003240520413430B4A1C0A110050310B701B0C8B7000234C7011005031595CC1540133062BF8D170BDDB
:4007C000040600000506000003060000E000000810B50248583000F051FB10BDFC04000810B50248B03000F049FB10BDFC04000810B5024800F042FB10BDC046FC0400083C
:4008000010B5034A80216032042000F001FA10BDFC05000870B500F0BCFF0500094800F08BFA094C200000F0B9FA2000343000F0B5FA2000683000F0B1FA280000F0ADFFA1
:4008400070BDC046FC040008881E0010F0B5962191B0002000F050FF00F026FF002801D100F014FF012000F09FFDE821724C734B626C89011A400A436264626C0193120A04
:40088000D2B23A2A04D1636C6D4A13400B4363643422002103A801F0D2FA03AA0021694800F06EFC3422002103A801F0C8FA03AA0121644800F064FC082204262368624DA7
:4008C000134323602369334207D1002D04D0012000F0D2FE013DF5E701E0002D00D1FEE7A02603220127594CF600A35903AD93433B43A351D2195649280001F097FA280088
:4009000000F0FAFF534901980B68534A03400B608021136949041B021B0A0B4313611369019902200B401361E0230F219B00E2588A433A43E250E25821318A438021E250C6
:40094000E25809060A43E250002100F0D3FA0021032000F0CFFA0021042000F0CBFA0321002000F0C7FA0321380000F0C3FA384B0522191D280001F059FA2900380000F03F
:40098000DBFA002800D0FEE73449380000F026FB002800D0FEE7324B324AE1580A403A43E250E158304A0A408021E250E25809060A43E250A2592D4B1340A351A2592C4BF3
:4009C00013408022920113438022A351A35912021343A351184B1A68264B1340164A136000F0DEFEC0235B00E3583B4204D1224AA3585B005B08A3506421002000F07CFEEF
:400A000024220021280001F01AFA29000D4800F031FC2A000E4B0C3313CB13C213CB13C213CB13C22900154800F024FC144A154B1A6011B0F0BDC04600002740FF00FFFF06
:400A4000FFC5FFDF0000324020A1070000002640241F001090002140000021401027000004050000FEFCFFFFFFFF00FFFFF0FFFFFF8FFFFFFFFCFFFF0C0500000003324062
:400A800001001180000E1F41030010B5FF24800882009B1ADB009C409940E243214007282DD8174B01F02CF904090E13181D2227186A02401143196221E0586A0240114332
:400AC00059621CE0986A02401143996217E0D86A02401143D96212E0186B0240114319630DE0586B02401143596308E0986B02401143996303E0D86B02401143D96310BDD7
:400B000000002140064B10309A68064B9A4203D183009858995002E0034B8000C058704700ED00E00000000800000010F7B5051E01913DD00023C05E002802DBA978FFF735
:400B4000A3FF6A680023E85E9201002812DB1A4B81088900C918FF2303271C00C0250740FF00BC401A40BA40AD004E59A64332434A5113E003250F2381B20B402940A9404B
:400B8000FC352F002A408F408A40083B9B080B4C9B001B19DE69BE433243DA61074B00259A68074B9A4204D10199FFF7ABFF00E0044D2800FEBDC04600E100E000ED00E070
:400BC00000000008010056000369002B03DA89B24160002000E001487047C04601008A000368002B01DB034803E089B2C26081600020704701008A000369002B03DAC368D6
:400C000000200B6000E001487047C04601008A0070B5040010000F2C2BD8002A07D1002927D1154B6401E418144B1C6022E000291FD01F260E401CD1104D0F4B6401E418D0
:400C40006960AA60CA0831002C6001F0F8F831002000FFF7B9FF31002A1D2868FFF7C0FF011E04D12868FFF7AFFF011E02D0044900E00449080070BD00002340EC06000850
:400C800001018A0003018A00194BF7B51A680193D76804003B680E00834223D90025A94202D100F076FD0500019B18680368002B01DB104C10E063095A01A41A0122A24090
:400CC00079689B00CB18196811420DD00024914319600021FFF778FF002E07D1280000F05CFD03E0044C01E0044CF2E72000FEBDEC0600080301880004018A0002018800B6
:400D00000A4B1B68DA68136883420DD9430999005B01C31A0120984052688B581840431E9841034BC01800E002487047EC0600080001880004018A00024B1A68002A00D14A
:400D400018607047F8060008F0B52C246043104C1E0024681F0A2018FF2426403C400D4F06607601F61906610B4E1B0C44606401A4191E04836033434461A3600023059D5D
:400D8000C261016283619D4201D02B888381F0BDF80600080000234000102340F0B5038985B002AD2B800368066A1933AB704368476A0095826AC16A040003930369C068A1
:400DC000FFF7C2FF00213B000A0000913000FFF7BBFF216B2800FFF7A9FE0023EA5E002A05DB1F231A401E3B9340024A136005B0F0BDC04600E100E0F7B52C25124C6843E9
:400E0000276801933C182669002E08D04D4379198869002805D13568002D02DA03E00B4811E00B480FE06768012425004B689D4013882D041D431560F2608C61BC40019B65
:400E4000A4B24B62B460FEBDF806000804028A0007028A002C235843064B1B681818C369934204D9036A9200D150002000E002487047C046F80600080A028A0073B500269A
:400E800042690400D56801962B0CB3421CD01B040069136013680369B34215DA01A9FFF7ABFEB0420CD10198E26903681E0C0378934205D2226A9B009B58002B00D0984725
:400EC00031002069FFF780FEADB2002D0ED063691D6000251B68636AAB4202D09847656203E0A36A002B00D09847A56163691B6873BD0000042819D804290FD94B1EFF3B13
:400F0000132B13D81F231940094B8000C018C02304229B00C1504033C25005E00723D0301940034B8000C150002000E0014870470000264001004A00F0B5012819D1C02275
:400F4000224BD2009A58002A0CDB8A78901E0E280FD84C78601E11280BD8C8780D7800282FD101E01A4830E07026152D01D9AE4201D2184829E00E79022E14D0F82124020C
:400F80004901F8270C4021007F2412047F033A4011432C4021438024C022C006240520400143D2009950C020C0248005360706403200E4001D590849002029400A431A51C4
:400FC00003E03826122DD4D9D1E7F0BD0000264003004A0001004A00FFFFFFCFF8B50D00012819D1C02180240D4BC9005A582406C826224307001C005A50F600A3593B42B7
:4010000006D1002D0AD0012000F036FB013DF5E70020002D03D101E0024800E00248F8BD0000264001004A0002004A001E4A0300904238D010D840282ED005D8002831D0B5
:4010400010282DD119482EE0802827D08021100049008B4227D023E0154A904214D008D8A022120690421DD0124AA020934211D016E0114A904209D0104A904208D0104AB1
:4010800090420DD10F480EE0A42003E00E480AE00E4808E0C00306E00D4804E00D4802E00D4800E0002070470600520001005000010000F0090000A0040000F0050000F0C5
:4010C000030000F00100520002005200030052000200500005005200FF0052000B4B10B51B69002B10DB0A4B0A4C1868FFF79EFF0121094B094A995099580029FCD10649AC
:4011000009590029F8D100E0054810BD00002340FC0600088C040000000025400C0400000200500010B5022202490020FFF792FE10BDC046450200080F4B30B5C0180F4B30
:40114000C009C01800011F23032909D81D00C9008D4013408B400468AC432343036009E01D000439C9008D4013408B404468AC432343436030BDC0460000CEBF0010030457
:40118000F7B504000E00150000286ED0002A6CD0012312688B40002A01D1436000E08360B30001930F231900B0008140A26A8A4369680B4083401343A3622A7A31002000BA
:4011C000FFF7BAFF0320710088400322636A83431800EB6813408B400343636201231F00B7400097FF43BC462F6962461F40B740A0691031104038436F69A0611F40B740A9
:40120000E06A10403843E062A86903221840B0400600E869276B10408A408840009930430A4397436A6A384356000222206304201640AA6A616B92000240286A3243034017
:401240001A43EB6AD80018230340FF2013432A6B019D520102401343FE2292002A40934081430B436363002000E00148FEBDC04601005A0000281BD0002919D00D4B0E4AD2
:40128000C318DB099B180A681B010260CA6882620A69C2624A6902638A6842624A6882618A694263CA6900201A600A6A5A6000E0024870470000CEBF0010030401005A0069
:4012C00010B50F2402200649064BCA58A2430243CA50F02212028B58A34303438B5010BD0000214004F0000010B50F2403200649064BCA58A2430243CA50F02212028B5872
:40130000A34303438B5010BD0000214004F000000449054A054B88580340C020C00103438B5070470000214004F00000FF8FFFFF0449054A054B885803408020C001034365
:401340008B5070470000214004F00000FF8FFFFF031E03D1084B5869C00F0CE00020012B09D1054918008A69920F1A4201D18869C00F01231840704700002640072370B540
:40138000084CA2691A4090420BD0A5699D4303402B43A361002904D0904202D9C82000F06BF970BD00002640F7B5060000F0F1F9B022E8211F27244D244C01902B595205B1
:4013C000C900525C3B409B1A5A1E9341B34236D0002E13D180211E4A490493690B439361FFF76EFF0B222B59BB4313432B51FFF78FFFB023E8225B05D2000CE00B222B5945
:401400000920BB4313432B5100F036F9FFF790FFB022104B5205D35C2959DAB21F23994313400B432B51012E09D1092000F024F9FFF75AFF064A084B91690B409361019810
:4014400000F0ABF9F7BDC046000026401CFF000000F0254041070000FFFFFFFEF0B5060085B00D00204F042901D001291AD100207C68002C35D01D4B984232D02379B3428C
:401480000ED1A368002B01D02B4209D1E36801A85A689B6842608360057023689847BC606469E6E7BC68022902D1002C00D024690020002C15D00D4B984212D02379B342AB
:4014C0000DD1A368002B01D02B4208D1E36801A85A689B68426083600570236898472469E7E705B0F0BDC0460C070008FF004200F7B5484C06002368002B0AD100F049F97C
:4015000023680700002B10D004210120FFF7A6FF0BE001210800FFF7A1FF0028EED002210120FFF79BFF3C4C72E03C4D2B680195DB061AD5F2223A4BD2019A58E260F022BA
:40154000D2019A582261374A9A586261364A9A58A261364A9A58E261354A9A582262354A9A586262344A9B58A362B02252055378002B02D05378212B03D1300000F07CFCAF
:401580001DE02E4B2E492F4859588C46E821C900515CC9B20091196809020AD41F2165460D402900009DA94203D0274952581A5002E00023214A1350300000F055FC019B2F
:4015C0001B68DB0619D5F0222169154BD20199506169144A9950A169134A9950E169134A9950216A124A9950616A124A9950A16A114A9950E168E8329950380000F0CDF888
:4016000023680024A34203D008210120FFF726FF2000FEBD0C070008FF004200E00001400000344004780000087800000C7800001078000014780000187800000000264088
:401640001CFF0000307F00001018000010B5E82400F09FF8064B07495A68A4010A4022435A605A68114059605B6800F096F810BD00002640FF00FC0F10B5034B1B78584324
:4016800000F07EF810BDC046D400000880220020034B12069A649B6C834200DA0148704700002740030046008022054B120198585B68DBB2002B02D08023DB0218437047C5
:4016C00000002640FEE7000002680A4B10B51A6042685A6082689A60C268DA6002691A6142695A6182699A61C269DA61FFF7EAFF10BDC04628040008F0B51922002800D19E
:401700004B32E82403258A429241194E640033595242AB43134333513359164F3B403351154B5C68AC4322435A605A6817405F60002808D00023102913D921338B429B4167
:401740005B4201330DE003001D290AD901233A2907D9DB18572904D976338B4240410422131A0F21054A1068884303431360F0BD00002140FFFCFFFFFC002140000025403A
:401780000230800803D001300238FCD1C046C0467047EFF3108072B6704780F310887047094B042803D11A68104318600BE0C02200069204104090220449920088500421A6
:4017C0001A688A431A60704710E000E000002140F8B58023FA250C0001271B0218430D4E0004F061AD00326C0A4B01203A4205D1002D0CD0013DFFF73FFFF4E7002D06D001
:401800001A6C10431864DB6A0020238000E00248F8BDC04600003C400400160070B5FA2401260D4B000418400C4D0143E961A4002B6C0A4A0120334205D1002C0AD0013C8D
:40184000FFF71AFFF4E7002C04D0136C18431064002000E0024870BD0000FF7F00003C400400160030B524259DB02A00002101A800F0E5FA154B164C0493164B2A00002162
:401880000AA808930993069400F0D9FA124B2A000D93124B00211193114B13A812930F9400F0CDFA0F4B01A916930F4B0F481A931894FFF7DFFC0AA90D48FFF7DBFC13A96A
:4018C0000C48FFF7D7FC1DB030BDC046666666660000FFFF1C1C1C1C66E6EE661C1A1A1A1A1A000066E666661A1A001C000132408001324000023240F0B585B000900028F3
:4019000000D147E1BE4F7B689B0301D5FFF79EFE0122BC4BBC4C1D001959114204D0BB495B58134200D037E1FFF79CFFB84AB94BEA508022009BD2021B781343B64AAB5016
:40194000B64AB74BEA50B74B5A6801231A4200D024E1B54A116F08220A4008D1B34BB44918681300884202D900F0D4F9431E2A68002B03D0AF485B03034300E0AE4B13439B
:401980002B607B699F499E4E01275B000DD539000320FFF7F3FC73699B0F3B420AD08022B369D2051343B36104E00320A34A8B5803438B502B5940200193019AA04BA14E7D
:4019C00013432B51FFF758FE0123AA598D4F1A4208D1BB514020FFF74FFE03234020BB51FFF74AFEFA27019A974B984E1A4016430192FF002E51964A964BD3581022134257
:401A000007D1002F00D1CBE00120013FFFF734FEF1E7002F00D1C3E008218F4A0120AB580B43AB50FFF794FC002802D18B4E019B1E438B4B1E4001231E432E511E00894C2E
:401A4000724BEB58334207D1002C00D1A8E00120013CFFF711FEF3E7002C00D1A0E00B27C02181484901FFF7D9FE041E05D102AB991D7D48FFF7ACFE0400013F002F00D1E3
:401A800096E0002C25D1C02202AB9E1D338852019342E5D131007548FFF79AFE041E18D180233288DB001A4200D083E00B27019380216E48C900FFF7B1FE041E04D13100AA
:401AC0006A48FFF785FE0400013F002F70D0002C68D0B0256D056B78002B44D06B78212B41D0634FEB5B002B3DD0002C00D0FEE002AB9E1D31005F48FFF76AFE041E00D061
:401B0000F5E0C021E85B3488084060398C434008594920430140F020EA5BC000EB5BD201024011439B05554A9B0F1140DB02194350483180FFF772FE041E00D0D7E03100F2
:401B40004F48FFF745FE041E00D0D0E0C022EB5B31889B069B0F9B019143194348483180FFF75CFE0400002C00D0C0E0009B454859781D78444B49001943FFF74FFE041EA3
:401B800004D142494248FFF749FE04006801FFF773FDACE03F4CAAE03F4CA8E03F4CA6E03F4CA4E03388019A934200D080E701E03B4C8EE731003B48FFF70AFE041E00D074
:401BC00087E732883F2310009843009B36499F78DB78012F0ED10222012B04D89FB2D21B92B2019201E0170001947022104330802E4A66E0002B5BD0019401275BE0C04668
:401C00000000264000003C40A0F00100B4F0010006000001A4F00100A8F0010001000100ACF00100FC003C4000F03D40C800000800093D00041A0080040A0080C4F00100DC
:401C400030000300B0F00100EFFFFEFF20000200000032401040000068F0010028000200FFFFFBFFF07E0E00021E0000031E000016180000071E00007FF8FFFFFFE7FFFFDD
:401C8000061E0000081E000001100000376800000F1E000001001600030016000200160004001600091E0000C00000080048E80101201F0001907F2082436F3802433280A8
:401CC0000C4ADA400A6031880B4839433180FFF7A5FD009B0400DB78DF1B03231F40019B9B001F43054BBFB23780EF50F1E6200005B0F0BD0024F400091E000064F001008B
:401D000002B4714649084900095C49008E4402BC7047C046002243088B4274D303098B425FD3030A8B4244D3030B8B4228D3030C8B420DD3FF22090212BA030C8B4202D3E9
:401D40001212090265D0030B8B4219D300E0090AC30B8B4201D3CB03C01A5241830B8B4201D38B03C01A5241430B8B4201D34B03C01A5241030B8B4201D30B03C01A52419D
:401D8000C30A8B4201D3CB02C01A5241830A8B4201D38B02C01A5241430A8B4201D34B02C01A5241030A8B4201D30B02C01A5241CDD2C3098B4201D3CB01C01A52418309B2
:401DC0008B4201D38B01C01A524143098B4201D34B01C01A524103098B4201D30B01C01A5241C3088B4201D3CB00C01A524183088B4201D38B00C01A524143088B4201D3C9
:401E00004B00C01A5241411A00D20146524110467047FFE701B5002000F006F802BDC0460029F7D076E770477047C046002310B59A4203D0CC5CC4540133F9E710BD0300EB
:401E40008218934202D019700133FAE770470000F8B5C046F8BC08BC9E467047F8B5C046F8BC08BC9E46704701B40248844601BC604700BF3503000801B40248844601BC8E
:401E8000604700BF7102000803000000010000000100000000000000050360000400000001000000000000000100000006046000080000006C060008F107001008000000D2
:401EC000010000000200000002000000080800030900000001000000000000000300000009090003080000008C060008D10700100A0000000100000004000000040000000B
:401F00000A0A000C0B0000000100000000000000050000000B0B000C10000000AC060008E1070010192001021901020000000000000000000000000000000000000000BA7A
:401F40000000000000000000000000000000000000001D1D000000000000001000000008C0000000781F0010C00000086803000048040008F002000000127A0000127A0017
:401F800000093D0000093D0000093D0004000000A00F00000000D0070700000002000000030000000F000000000000000000000003000000000000000000000000000000A7
:401FC0000000000000000000030000000000000000000000000000000000000000000000000000000000000019000050A000000002FF0000E9000010C1000010000000000A
:40200000F7B50D00019000F04BF9060003281FD12D4B1B69002B19DB002000F021F92B4FB84213D000232A4A1900012000F048F9041E0BD1002000F013F9264BB84203D00B
:402040009C4203D00134F5E79C4201D1224D39E000F01EF9214A04000121214800F028F900282DD1019B002B16D1ADB2ED0001D11C4D18E03E221C4B06211A601B4A1C4BCD
:402080001A60A3221B4BD20099501B4A9D50995899580029FCDAEBE7114A1369002BFCDB00F0E6F80500032E03D0200000F010F908E00121002000F0E3F80028F9D1F4E730
:4020C000054DF0E72800FEBDC00023400101880038010008F049020005005200FC0600080000234001005000040126401E1F000008012640000026401C05000010B5437878
:40210000FF2B0DD100F0C4F8064BDB685A68012311681943116011681942FCD100F0D8F810BDC0468000234070B52B490A682A4B002AFBDA0221DA680A43DA60DA68D2078E
:402140001BD5264D264CD9682A69266889B2360A36060E43FF21120209040A4032439026DA6029691F4A360111403143296121680A40324322602A692268002204241A491B
:402180005A605A680A6922430A61012801D030BF00E020BF1A68104D002AFBDAEA68D20712D5FF240D4E0F4A3069E9682402090A1040214001430A4831610668E9683240C4
:4021C000090C0C40224302600221DA688A43DA6000225A6070BDC046E00023400000214090002140FF00FFFF00ED00E00421134A13690B431361012801D030BF00E020BF75
:402200000F4A1368002BFCDA0E4B19691A00002910D10D490D4B196006210D4B19600D4B383119600C4B0631196019680029FCDA0A4B13610022024B5A60704700ED00E074
:40224000E0002340FC0025401E1F00000801264018052640040126401C052640AAAAAAAA01B40248844601BC604700BF010D001001B40248844601BC604700BFDD100010FE
:4022800001B40248844601BC604700BF890C001001B40248844601BC604700BF9317001001B40248844601BC604700BFE503001001B40248844601BC604700BFE10B00101B
:4022C00001B40248844601BC604700BFF90D001001B40248844601BC604700BF9B17001000000000000000000000000000000000000000000000000000000000000000002E
:40230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009D
:40234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005D
:40238000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D
:4023C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DD
:0200000490303A
:02000000121CD0
:0200000490501A
:0C0000000005E20721002101E212331C80
:00000001FF

View File

@ -0,0 +1,108 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ipc_rpc.h"
#include "Mutex.h"
#include "Semaphore.h"
#include "mbed_assert.h"
#include "cy_ipc_config.h"
#include "ipc/cy_ipc_pipe.h"
#include <stdarg.h>
#include "platform/SingletonPtr.h"
using namespace rtos;
static SingletonPtr<Mutex> msg_mutex;
static SingletonPtr<Semaphore> msg_semaphore;
#define RPC_GEN RPC_GEN_INTERFACE_IDS
#include "rpc_api.h"
#undef RPC_GEN
// This function uses a "C" linkage as it is a callback called from Cypress library
// which is C-only.
extern "C" void ipcrpc_release(void);
void ipcrpc_release(void)
{
// Just signal on semaphore that we are done with a call.
msg_semaphore->release();
}
// Encapsulate call arguments and send a message over IPC pipe to the
// other core for execution.
uint32_t ipcrpc_call(uint32_t call_id, uint32_t args_num, ...)
{
va_list ap;
static IpcRpcMessage message;
cy_en_ipc_pipe_status_t status;
ScopedMutexLock lock(*msg_mutex.get());
// Make sure semaphore is initialized.
(void)msg_semaphore.get();
// Copy data to the buffer.
message.client_id = call_id;
message.args_num = args_num;
message.result = 0; // default result
va_start(ap, args_num);
for (uint32_t i = 0; i < args_num; ++i) {
message.args[i] = va_arg (ap, uint32_t);
}
va_end (ap);
// send message
status = Cy_IPC_Pipe_SendMessage(CY_IPC_EP_RPCPIPE_DEST,
CY_IPC_EP_RPCPIPE_ADDR,
&message,
ipcrpc_release);
// We are using dedicated IPC channel here and have locked global mutex
// so this had to succeed.
MBED_ASSERT(status == CY_IPC_PIPE_SUCCESS);
// Now wait for the response;
msg_semaphore->wait();
return message.result;
}
extern "C" {
void ipcrpc_init(void)
{
uint32_t rpc_counter = 0;
#define RPC_GEN RPC_GEN_INTERFACE_IDS_INIT
#include "rpc_api.h"
#undef RPC_GEN
}
#define RPC_GEN RPC_GEN_INTERFACE
#include "rpc_api.h"
#undef RPC_GEN
#define RPC_GEN RPC_GEN_IMPLEMENTATION
#include "rpc_api.h"
#undef RPC_GEN
} /* extern "C" */
/* [] END OF FILE */

View File

@ -0,0 +1,461 @@
/***************************************************************************//**
* \file system_psoc63_cm4.c
* \version 2.10
*
* The device system-source file.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* Copyright 2017-2018, Future Electronics
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "device.h"
#include "system_psoc63.h"
#include "cy_device_headers.h"
#include "ipc_rpc.h"
#include "psoc6_utils.h"
#if defined(CY_DEVICE_PSOC6ABLE2) && !defined(CY_IPC_DEFAULT_CFG_DISABLE)
#include "ipc/cy_ipc_drv.h"
#include "flash/cy_flash.h"
#endif /* defined(CY_DEVICE_PSOC6ABLE2) && !defined(CY_IPC_DEFAULT_CFG_DISABLE) */
/*******************************************************************************
* SystemCoreClockUpdate()
*******************************************************************************/
/** Default HFClk frequency in Hz */
#define CY_CLK_HFCLK0_FREQ_HZ_DEFAULT CY_CLK_HFCLK0_FREQ_HZ
/** Default PeriClk frequency in Hz */
#define CY_CLK_PERICLK_FREQ_HZ_DEFAULT CY_CLK_PERICLK_FREQ_HZ
/** Default SlowClk system core frequency in Hz */
#define CY_CLK_SYSTEM_FREQ_HZ_DEFAULT CY_CLK_HFCLK0_FREQ_HZ
/*
* Holds the FastClk system core clock, which is the system clock frequency
* supplied to the SysTick timer and the processor core clock.
* This variable implements CMSIS Core global variable.
* Refer to the [CMSIS documentation]
* (http://www.keil.com/pack/doc/CMSIS/Core/html/group__system__init__gr.html "System and Clock Configuration")
* for more details.
* 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_CLK_SYSTEM_FREQ_HZ_DEFAULT;
/** Holds the HFClk0 clock frequency. Updated by \ref SystemCoreClockUpdate(). */
uint32_t cy_Hfclk0FreqHz = CY_CLK_HFCLK0_FREQ_HZ_DEFAULT;
/** Holds the PeriClk clock frequency. Updated by \ref SystemCoreClockUpdate(). */
uint32_t cy_PeriClkFreqHz = CY_CLK_PERICLK_FREQ_HZ_DEFAULT;
#if (defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL)) || defined (CY_DOXYGEN)
/** Holds the Alternate high frequency clock in Hz. Updated by \ref SystemCoreClockUpdate(). */
uint32_t cy_BleEcoClockFreqHz = CY_CLK_ALTHF_FREQ_HZ;
#endif /* (defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL)) || defined (CY_DOXYGEN) */
/* SCB->CPACR */
#define SCB_CPACR_CP10_CP11_ENABLE (0xFUL << 20u)
/*******************************************************************************
* SystemInit()
*******************************************************************************/
/* WDT lock bits */
#define CY_WDT_LOCK_BIT0 ((uint32_t)0x01u << 30u)
#define CY_WDT_LOCK_BIT1 ((uint32_t)0x01u << 31u)
#if (__CM0P_PRESENT == 0)
/* CLK_FLL_CONFIG default values */
#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)
#endif /* (__CM0P_PRESENT == 0) */
/*******************************************************************************
* SystemCoreClockUpdate (void)
*******************************************************************************/
/* 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_CLK_SYSTEM_FREQ_HZ_DEFAULT;
uint32_t cy_delayFreqKhz = (CY_CLK_SYSTEM_FREQ_HZ_DEFAULT + CY_DELAY_1K_MINUS_1_THRESHOLD) /
CY_DELAY_1K_THRESHOLD;
uint8_t cy_delayFreqMhz = (uint8_t)((CY_CLK_SYSTEM_FREQ_HZ_DEFAULT + CY_DELAY_1M_MINUS_1_THRESHOLD) /
CY_DELAY_1M_THRESHOLD);
uint32_t cy_delay32kMs = CY_DELAY_MS_OVERFLOW_THRESHOLD *
((CY_CLK_SYSTEM_FREQ_HZ_DEFAULT + CY_DELAY_1K_MINUS_1_THRESHOLD) / CY_DELAY_1K_THRESHOLD);
#define CY_ROOT_PATH_SRC_IMO (0UL)
#define CY_ROOT_PATH_SRC_EXT (1UL)
#if (SRSS_ECO_PRESENT == 1U)
#define CY_ROOT_PATH_SRC_ECO (2UL)
#endif /* (SRSS_ECO_PRESENT == 1U) */
#if (SRSS_ALTHF_PRESENT == 1U)
#define CY_ROOT_PATH_SRC_ALTHF (3UL)
#endif /* (SRSS_ALTHF_PRESENT == 1U) */
#define CY_ROOT_PATH_SRC_DSI_MUX (4UL)
#define CY_ROOT_PATH_SRC_DSI_MUX_HVILO (16UL)
#define CY_ROOT_PATH_SRC_DSI_MUX_WCO (17UL)
#if (SRSS_ALTLF_PRESENT == 1U)
#define CY_ROOT_PATH_SRC_DSI_MUX_ALTLF (18UL)
#endif /* (SRSS_ALTLF_PRESENT == 1U) */
#if (SRSS_PILO_PRESENT == 1U)
#define CY_ROOT_PATH_SRC_DSI_MUX_PILO (19UL)
#endif /* (SRSS_PILO_PRESENT == 1U) */
/*******************************************************************************
* Function Name: SystemInit
****************************************************************************//**
* \cond
* Initializes the system:
* - Restores FLL registers to the default state for single core devices.
* - Unlocks and disables WDT.
* - Calls the Cy_SystemInit() function, if compiled from PSoC Creator.
* - Calls \ref SystemCoreClockUpdate().
* \endcond
*******************************************************************************/
void SystemInit(void)
{
#if (__CM0P_PRESENT == 0)
/* Restore FLL registers to the default state as they are not restored by the 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;
#endif /* (__CM0P_PRESENT == 0) */
/* 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();
}
/*******************************************************************************
* Function Name: mbed_sdk_init
****************************************************************************//**
*
* Mbed's post-memory-initialization function.
* Used here to initialize common parts of the Cypress libraries.
*
*******************************************************************************/
void mbed_sdk_init(void)
{
/* Initialize shared resource manager */
cy_srm_initialize();
/* Initialize system and clocks. */
/* Placed here as it must be done after proper LIBC initialization. */
SystemInit();
/* Allocate and initialize semaphores for the system operations. */
Cy_IPC_SystemSemaInit();
Cy_IPC_SystemPipeInit();
Cy_Flash_Init();
ipcrpc_init();
}
/*******************************************************************************
* 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: SystemCoreClockUpdate
****************************************************************************//**
*
* Gets core clock frequency and updates \ref SystemCoreClock, \ref
* cy_Hfclk0FreqHz, and \ref cy_PeriClkFreqHz.
*
* Updates global variables used by the \ref Cy_SysLib_Delay(), \ref
* Cy_SysLib_DelayUs(), and \ref Cy_SysLib_DelayCycles().
*
*******************************************************************************/
void SystemCoreClockUpdate (void)
{
uint32_t srcFreqHz;
uint32_t pathFreqHz;
uint32_t fastClkDiv;
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_CLK_IMO_FREQ_HZ;
break;
case CY_ROOT_PATH_SRC_EXT:
srcFreqHz = CY_CLK_EXT_FREQ_HZ;
break;
#if (SRSS_ECO_PRESENT == 1U)
case CY_ROOT_PATH_SRC_ECO:
srcFreqHz = CY_CLK_ECO_FREQ_HZ;
break;
#endif /* (SRSS_ECO_PRESENT == 1U) */
#if defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL) && (SRSS_ALTHF_PRESENT == 1U)
case CY_ROOT_PATH_SRC_ALTHF:
srcFreqHz = cy_BleEcoClockFreqHz;
break;
#endif /* defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL) && (SRSS_ALTHF_PRESENT == 1U) */
case CY_ROOT_PATH_SRC_DSI_MUX:
{
uint32_t dsi_src;
dsi_src = _FLD2VAL(SRSS_CLK_DSI_SELECT_DSI_MUX, SRSS->CLK_DSI_SELECT[rootPath]);
switch (dsi_src)
{
case CY_ROOT_PATH_SRC_DSI_MUX_HVILO:
srcFreqHz = CY_CLK_HVILO_FREQ_HZ;
break;
case CY_ROOT_PATH_SRC_DSI_MUX_WCO:
srcFreqHz = CY_CLK_WCO_FREQ_HZ;
break;
#if (SRSS_ALTLF_PRESENT == 1U)
case CY_ROOT_PATH_SRC_DSI_MUX_ALTLF:
srcFreqHz = CY_CLK_ALTLF_FREQ_HZ;
break;
#endif /* (SRSS_ALTLF_PRESENT == 1U) */
#if (SRSS_PILO_PRESENT == 1U)
case CY_ROOT_PATH_SRC_DSI_MUX_PILO:
srcFreqHz = CY_CLK_PILO_FREQ_HZ;
break;
#endif /* (SRSS_PILO_PRESENT == 1U) */
default:
srcFreqHz = CY_CLK_HVILO_FREQ_HZ;
break;
}
}
break;
default:
srcFreqHz = CY_CLK_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;
/* Fast Clock Divider */
fastClkDiv = 1u + _FLD2VAL(CPUSS_CM4_CLOCK_CTL_FAST_INT_DIV, CPUSS->CM4_CLOCK_CTL);
/* Peripheral Clock Divider */
periClkDiv = 1u + _FLD2VAL(CPUSS_CM0_CLOCK_CTL_PERI_INT_DIV, CPUSS->CM0_CLOCK_CTL);
cy_PeriClkFreqHz = pathFreqHz / periClkDiv;
pathFreqHz = pathFreqHz / fastClkDiv;
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_SystemInitFpuEnable
****************************************************************************//**
*
* Enables the FPU if it is used. The function is called from the startup file.
*
*******************************************************************************/
void Cy_SystemInitFpuEnable(void)
{
#if defined (__FPU_USED) && (__FPU_USED == 1U)
uint32_t interruptState;
interruptState = Cy_SaveIRQ();
SCB->CPACR |= SCB_CPACR_CP10_CP11_ENABLE;
__DSB();
__ISB();
Cy_RestoreIRQ(interruptState);
#endif /* (__FPU_USED) && (__FPU_USED == 1U) */
}
/*******************************************************************************
* Function Name: Cy_MemorySymbols
****************************************************************************//**
*
* The intention of the function is to declare boundaries of the memories for the
* MDK compilers. For the rest of the supported compilers, this is done using
* linker configuration files. The following symbols used by the cymcuelftool.
*
*******************************************************************************/
#if defined (__ARMCC_VERSION)
__asm void Cy_MemorySymbols(void)
{
/* Flash */
EXPORT __cy_memory_0_start
EXPORT __cy_memory_0_length
EXPORT __cy_memory_0_row_size
/* Working Flash */
EXPORT __cy_memory_1_start
EXPORT __cy_memory_1_length
EXPORT __cy_memory_1_row_size
/* Supervisory Flash */
EXPORT __cy_memory_2_start
EXPORT __cy_memory_2_length
EXPORT __cy_memory_2_row_size
/* XIP */
EXPORT __cy_memory_3_start
EXPORT __cy_memory_3_length
EXPORT __cy_memory_3_row_size
/* eFuse */
EXPORT __cy_memory_4_start
EXPORT __cy_memory_4_length
EXPORT __cy_memory_4_row_size
/* Flash */
__cy_memory_0_start EQU __cpp(CY_FLASH_BASE)
__cy_memory_0_length EQU __cpp(CY_FLASH_SIZE)
__cy_memory_0_row_size EQU 0x200
/* Flash region for EEPROM emulation */
__cy_memory_1_start EQU __cpp(CY_EM_EEPROM_BASE)
__cy_memory_1_length EQU __cpp(CY_EM_EEPROM_SIZE)
__cy_memory_1_row_size EQU 0x200
/* Supervisory Flash */
__cy_memory_2_start EQU __cpp(CY_SFLASH_BASE)
__cy_memory_2_length EQU __cpp(CY_SFLASH_SIZE)
__cy_memory_2_row_size EQU 0x200
/* XIP */
__cy_memory_3_start EQU __cpp(CY_XIP_BASE)
__cy_memory_3_length EQU __cpp(CY_XIP_SIZE)
__cy_memory_3_row_size EQU 0x200
/* eFuse */
__cy_memory_4_start EQU __cpp(0x90700000)
__cy_memory_4_length EQU __cpp(0x100000)
__cy_memory_4_row_size EQU __cpp(1)
}
#endif /* defined (__ARMCC_VERSION) */
/* [] END OF FILE */

View File

@ -0,0 +1,81 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_DEVICE_H
#define MBED_DEVICE_H
/*----------------------------------------------------------------------------*/
/** Config options. */
/*----------------------------------------------------------------------------*/
/** ALTHF (BLE ECO) frequency in Hz */
#define CYDEV_CLK_ALTHF__HZ ( 8000000UL)
/*----------------------------------------------------------------------------*/
#include "cmsis.h"
#include "objects.h"
/*
* Board clocks.
*/
/** IMO frequency in Hz */
#define CY_CLK_IMO_FREQ_HZ ( 8000000UL)
/** PILO frequency in Hz */
#define CY_CLK_PILO_FREQ_HZ ( 32768UL)
/** WCO frequency in Hz */
#define CY_CLK_WCO_FREQ_HZ ( 32768UL)
/** HVILO frequency in Hz */
#define CY_CLK_HVILO_FREQ_HZ ( 32000UL)
/** ALTLF frequency in Hz */
#define CY_CLK_ALTLF_FREQ_HZ ( 32768UL)
/** Default HFClk frequency in Hz */
#ifndef CY_CLK_HFCLK0_FREQ_HZ
#define CY_CLK_HFCLK0_FREQ_HZ (100000000UL)
#endif
/** Default PeriClk frequency in Hz */
#ifndef CY_CLK_PERICLK_FREQ_HZ
#define CY_CLK_PERICLK_FREQ_HZ (CY_CLK_HFCLK0_FREQ_HZ / 2)
#endif
/** Default SlowClk system core frequency in Hz */
#ifndef CY_CLK_SYSTEM_FREQ_HZ
#define CY_CLK_SYSTEM_FREQ_HZ (CY_CLK_PERICLK_FREQ_HZ)
#endif
/** Interrupt assignment for CM0+ core.
* On PSoC6 CM0+ core physical interrupt are routed into NVIC through a programmable
* multiplexer. This requires that we define which of the 32 NVIC channels is used
* by which interrupt. This is done here.
*/
#define CY_M0_CORE_IRQ_CHANNEL_US_TICKER ((IRQn_Type)0)
#define CY_M0_CORE_IRQ_CHANNEL_SERIAL ((IRQn_Type)4)
#define CY_M0_CORE_IRQ_CHANNEL_BLE ((IRQn_Type)3)
/** Identifiers used in allocation of NVIC channels.
*/
#define CY_US_TICKER_IRQN_ID (0x100)
#define CY_SERIAL_IRQN_ID (0x200)
#define CY_BLE_IRQN_ID (0x300)
#define CY_GPIO_IRQN_ID (0x400)
#define CY_LP_TICKER_IRQN_ID (0x500)
#endif

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
/***************************************************************************//**
* \file cy_device_headers.h
*
* \brief
* Common header file to be included by the drivers.
*
* \note
* Generator version: 1.2.0.117
* Database revision: rev#1034984
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#ifndef _CY_DEVICE_HEADERS_H_
#define _CY_DEVICE_HEADERS_H_
#if defined (CY8C6336BZI_BLF03)
#include "cy8c6336bzi_blf03.h"
#elif defined (CY8C6316BZI_BLF03)
#include "cy8c6316bzi_blf03.h"
#elif defined (CY8C6316BZI_BLF53)
#include "cy8c6316bzi_blf53.h"
#elif defined (CY8C6336BZI_BLD13)
#include "cy8c6336bzi_bld13.h"
#elif defined (CY8C6347BZI_BLD43)
#include "cy8c6347bzi_bld43.h"
#elif defined (CY8C6347BZI_BLD33)
#include "cy8c6347bzi_bld33.h"
#elif defined (CY8C6347BZI_BLD53)
#include "cy8c6347bzi_bld53.h"
#elif defined (CY8C6347FMI_BLD13)
#include "cy8c6347fmi_bld13.h"
#elif defined (CY8C6347FMI_BLD43)
#include "cy8c6347fmi_bld43.h"
#elif defined (CY8C6347FMI_BLD33)
#include "cy8c6347fmi_bld33.h"
#elif defined (CY8C6347FMI_BLD53)
#include "cy8c6347fmi_bld53.h"
#elif defined (CY8C637BZI_MD76)
#include "cy8c637bzi_md76.h"
#elif defined (CY8C637BZI_BLD74)
#include "cy8c637bzi_bld74.h"
#elif defined (CY8C637FMI_BLD73)
#include "cy8c637fmi_bld73.h"
#elif defined (CY8C68237BZ_BLE)
#include "cy8c68237bz_ble.h"
#elif defined (CY8C68237FM_BLE)
#include "cy8c68237fm_ble.h"
#elif defined (CY8C6336BZI_BUD13)
#include "cy8c6336bzi_bud13.h"
#elif defined (CY8C6347BZI_BUD43)
#include "cy8c6347bzi_bud43.h"
#elif defined (CY8C6347BZI_BUD33)
#include "cy8c6347bzi_bud33.h"
#elif defined (CY8C6347BZI_BUD53)
#include "cy8c6347bzi_bud53.h"
#elif defined (CY8C6337BZI_BLF13)
#include "cy8c6337bzi_blf13.h"
#else
#error Undefined part number
#endif
#endif /* _CY_DEVICE_HEADERS_H_ */
/* [] END OF FILE */

View File

@ -0,0 +1,190 @@
/***************************************************************************//**
* \file cy_ipc_config.c
* \version 1.10.1
*
* Description:
* This C file is not intended to be part of the IPC driver. It is the code
* required to configure the device specific IPC channels for semaphores
* and pipes.
*
********************************************************************************
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "ipc/cy_ipc_drv.h"
#include "ipc/cy_ipc_pipe.h"
#include "ipc/cy_ipc_sema.h"
#include "cy_ipc_config.h"
/* Create an array of endpoint structures */
static cy_stc_ipc_pipe_ep_t cy_ipc_pipe_sysEpArray[CY_IPC_MAX_ENDPOINTS];
#define CY_CYPIPE_DEFAULT_CONFIG \
{\
/* .ep0ConfigData */ {\
/* .ipcNotifierNumber */ CY_IPC_INTR_CYPIPE_EP0,\
/* .ipcNotifierPriority */ CY_IPC_INTR_CYPIPE_PRIOR_EP0,\
/* .ipcNotifierMuxNumber */ CY_IPC_INTR_CYPIPE_MUX_EP0,\
/* .epAddress */ CY_IPC_EP_CYPIPE_CM0_ADDR,\
/* .epConfig */ CY_IPC_CYPIPE_CONFIG_EP0\
},\
/* .ep1ConfigData */ {\
/* .ipcNotifierNumber */ CY_IPC_INTR_CYPIPE_EP1,\
/* .ipcNotifierPriority */ CY_IPC_INTR_CYPIPE_PRIOR_EP1,\
/* .ipcNotifierMuxNumber */ 0u,\
/* .epAddress */ CY_IPC_EP_CYPIPE_CM4_ADDR,\
/* .epConfig */ CY_IPC_CYPIPE_CONFIG_EP1\
},\
/* .endpointClientsCount */ CY_IPC_CYPIPE_CLIENT_CNT,\
/* .endpointsCallbacksArray */ cy_ipc_pipe_sysCbArray,\
/* .userPipeIsrHandler */ &Cy_IPC_SystemPipeIsr\
}
/*******************************************************************************
* Function Name: Cy_IPC_SystemSemaInit
****************************************************************************//**
*
* Initializes the system semaphores. The system semaphores are used by Flash.
*
* This function is called in the SystemInit() function. If the default startup
* file is not used, or SystemInit() is not called in your project,
* call the following three functions prior to executing any flash or EmEEPROM
* write or erase operation:
* -# Cy_IPC_SystemSemaInit()
* -# Cy_IPC_SystemPipeInit()
* -# Cy_Flash_Init()
*
*******************************************************************************/
void Cy_IPC_SystemSemaInit(void)
{
/* Create array used for semaphores */
#if !(CY_CPU_CORTEX_M0P)
(void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, 0ul, NULL);
#else
static uint32_t ipcSemaArray[CY_IPC_SEMA_COUNT / CY_IPC_SEMA_PER_WORD];
(void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, CY_IPC_SEMA_COUNT, ipcSemaArray);
#endif
}
/*******************************************************************************
* Function Name: Cy_IPC_UserPipeIsr
****************************************************************************//**
*
* This is the interrupt service routine for the user pipe.
*
*******************************************************************************/
void Cy_IPC_UserPipeIsr(void)
{
Cy_IPC_Pipe_ExecCallback(&cy_ipc_pipe_sysEpArray[CY_IPC_EP_USRPIPE_ADDR]);
}
/*******************************************************************************
* Function Name: Cy_IPC_RpcPipeIsr
****************************************************************************//**
*
* This is the interrupt service routine for the RPC pipe.
*
*******************************************************************************/
void Cy_IPC_RpcPipeIsr(void)
{
Cy_IPC_Pipe_ExecCallback(&cy_ipc_pipe_sysEpArray[CY_IPC_EP_RPCPIPE_ADDR]);
}
/*******************************************************************************
* Function Name: Cy_IPC_SystemPipeInit
****************************************************************************//**
*
* Initializes the system pipes. The system pipes are used by BLE and Flash.
* \note The function should be called on all CPUs.
*
* This function is called in the SystemInit() function. If the default startup
* file is not used, or SystemInit() is not called in your project,
* call the following three functions prior to executing any flash or EmEEPROM
* write or erase operation:
* -# Cy_IPC_SystemSemaInit()
* -# Cy_IPC_SystemPipeInit()
* -# Cy_Flash_Init()
*
* Also this function is called to support BLE host/controller communication.
*
*******************************************************************************/
void Cy_IPC_SystemPipeInit(void)
{
uint32_t intr;
intr = Cy_SysLib_EnterCriticalSection();
static cy_ipc_pipe_callback_ptr_t cy_ipc_pipe_sysCbArray[CY_IPC_CYPIPE_CLIENT_CNT];
static cy_ipc_pipe_callback_ptr_t cy_ipc_pipe_userCbArray[CY_IPC_USRPIPE_CLIENT_CNT];
static cy_ipc_pipe_callback_ptr_t cy_ipc_pipe_rpcCbArray[CY_IPC_RPCPIPE_CLIENT_CNT];
static const cy_stc_ipc_pipe_config_t systemPipeConfig = CY_CYPIPE_DEFAULT_CONFIG;
static const cy_stc_ipc_pipe_config_t userPipeConfig = {
.ep0ConfigData = {
.ipcNotifierNumber = CY_IPC_INTR_USRPIPE_CM0,
.ipcNotifierPriority = CY_IPC_INTR_USRPIPE_PRIOR_EP0,
.ipcNotifierMuxNumber = CY_IPC_INTR_USRPIPE_MUX_EP0,
.epAddress = CY_IPC_EP_USRPIPE_CM0_ADDR,
.epConfig = CY_IPC_USRPIPE_CONFIG_EP0
},
.ep1ConfigData = {
.ipcNotifierNumber = CY_IPC_INTR_USRPIPE_CM4,
.ipcNotifierPriority = CY_IPC_INTR_USRPIPE_PRIOR_EP1,
.ipcNotifierMuxNumber = 0u,
.epAddress = CY_IPC_EP_USRPIPE_CM4_ADDR,
.epConfig = CY_IPC_USRPIPE_CONFIG_EP1
},
.endpointClientsCount = CY_IPC_USRPIPE_CLIENT_CNT,
.endpointsCallbacksArray = cy_ipc_pipe_userCbArray,
.userPipeIsrHandler = &Cy_IPC_UserPipeIsr
};
static const cy_stc_ipc_pipe_config_t rpcPipeConfig = {
.ep0ConfigData = {
.ipcNotifierNumber = CY_IPC_INTR_RPCPIPE_CM0,
.ipcNotifierPriority = CY_IPC_INTR_RPCPIPE_PRIOR_EP0,
.ipcNotifierMuxNumber = CY_IPC_INTR_RPCPIPE_MUX_EP0,
.epAddress = CY_IPC_EP_RPCPIPE_CM0_ADDR,
.epConfig = CY_IPC_RPCPIPE_CONFIG_EP0
},
.ep1ConfigData = {
.ipcNotifierNumber = CY_IPC_INTR_RPCPIPE_CM4,
.ipcNotifierPriority = CY_IPC_INTR_RPCPIPE_PRIOR_EP1,
.ipcNotifierMuxNumber = 0u,
.epAddress = CY_IPC_EP_RPCPIPE_CM4_ADDR,
.epConfig = CY_IPC_RPCPIPE_CONFIG_EP1
},
.endpointClientsCount = CY_IPC_RPCPIPE_CLIENT_CNT,
.endpointsCallbacksArray = cy_ipc_pipe_rpcCbArray,
.userPipeIsrHandler = &Cy_IPC_RpcPipeIsr
};
Cy_IPC_Pipe_Config(cy_ipc_pipe_sysEpArray);
Cy_IPC_Pipe_Init(&systemPipeConfig);
Cy_IPC_Pipe_Init(&userPipeConfig);
Cy_IPC_Pipe_Init(&rpcPipeConfig);
Cy_SysLib_ExitCriticalSection(intr);
}
/*******************************************************************************
* Function Name: Cy_IPC_SystemPipeIsr
****************************************************************************//**
*
* This is the interrupt service routine for the system pipe.
*
*******************************************************************************/
void Cy_IPC_SystemPipeIsr(void)
{
Cy_IPC_Pipe_ExecCallback(&cy_ipc_pipe_sysEpArray[CY_IPC_EP_CYPIPE_ADDR]);
}
/* [] END OF FILE */

View File

@ -0,0 +1,219 @@
/***************************************************************************//**
* \file cy_ipc_config.h
* \version 1.10.1
*
* \brief
* This header file is not intended to be part of the IPC driver since it defines
* a device specific configuration for the IPC channels and pipes.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#ifndef CY_IPC_CONFIG_H
#define CY_IPC_CONFIG_H
/* IPC Resources */
#define CY_IPC_CHANNELS (uint32_t)(CPUSS_IPC_IPC_NR)
#define CY_IPC_INTERRUPTS (uint32_t)(CPUSS_IPC_IPC_IRQ_NR)
/* IPC channel definitions */
#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_CPU_CORTEX_M0P)
#define CY_IPC_CHAN_SYSCALL CY_IPC_CHAN_SYSCALL_CM0
#define Cy_IPC_SystemPipeIsr NvicMux1_IRQHandler
#else
#define CY_IPC_CHAN_SYSCALL CY_IPC_CHAN_SYSCALL_CM4
#define Cy_IPC_SystemPipeIsr cpuss_interrupts_ipc_4_IRQHandler
#endif /* (CY_CPU_CORTEX_M0P) */
#define CY_IPC_CHAN_SYSCALL_DAP (uint32_t)(2u) /**< System calls for the DAP */
#define CY_IPC_CHAN_CRYPTO (uint32_t)(3u) /**< IPC data channel for the Crypto */
#define CY_IPC_CHAN_SEMA (uint32_t)(4u) /**< IPC data channel for the Semaphores */
#define CY_IPC_CHAN_CYPIPE_EP0 (uint32_t)(5u) /**< IPC data channel for CYPIPE EP0 */
#define CY_IPC_CHAN_CYPIPE_EP1 (uint32_t)(6u) /**< IPC data channel for CYPIPE EP1 */
/* IPC Notify interrupts definitions */
#define CY_IPC_INTR_SYSCALL1 (uint32_t)(0u)
#define CY_IPC_INTR_CRYPTO_SRV (uint32_t)(1u) /**< IPC interrupt structure for the Crypto server */
#define CY_IPC_INTR_CRYPTO_CLI (uint32_t)(2u) /**< IPC interrupt structure for the Crypto client */
#define CY_IPC_INTR_SPARE (uint32_t)(7u)
/* IPC Semaphores allocation
This will allow 128 (4*32) semaphores */
#define CY_IPC_SEMA_COUNT (uint32_t)(128u)
/* IPC Pipe definitions */
#define CY_IPC_MAX_ENDPOINTS (uint32_t)(8u)
/*******************************************************************************
** CY_PIPE default configuration
*******************************************************************************/
#define CY_IPC_CYPIPE_CLIENT_CNT (uint32_t)(8u)
#define CY_IPC_USRPIPE_CLIENT_CNT (uint32_t)(8u)
#define CY_IPC_RPCPIPE_CLIENT_CNT (uint32_t)(16u)
#if (CY_CPU_CORTEX_M0P)
#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_CPU_CORTEX_M0P) */
#define CY_IPC_INTR_CYPIPE_MUX_EP0 (uint32_t)(1u) /* IPC CYPRESS PIPE */
#define CY_IPC_INTR_CYPIPE_EP0 (uint32_t)(3u) /* Notifier EP0 */
#define CY_IPC_INTR_CYPIPE_PRIOR_EP0 (uint32_t)(1u) /* Notifier Priority */
#define CY_IPC_INTR_CYPIPE_EP1 (uint32_t)(4u) /* Notifier EP1 */
#define CY_IPC_INTR_CYPIPE_PRIOR_EP1 (uint32_t)(1u) /* Notifier Priority */
#define CY_IPC_CYPIPE_CHAN_MASK_EP0 (uint32_t)(0x0001ul << CY_IPC_CHAN_CYPIPE_EP0)
#define CY_IPC_CYPIPE_CHAN_MASK_EP1 (uint32_t)(0x0001ul << CY_IPC_CHAN_CYPIPE_EP1)
/* Endpoint indexes in the pipe array */
#define CY_IPC_EP_CYPIPE_CM0_ADDR (uint32_t)(0u)
#define CY_IPC_EP_CYPIPE_CM4_ADDR (uint32_t)(1u)
/******************************************************************************/
/*
* The System pipe configuration defines the IPC channel number, interrupt
* number, and the pipe interrupt mask for the endpoint.
*
* The format of the endPoint configuration
* Bits[31:16] Interrupt Mask
* Bits[15:8 ] IPC interrupt
* Bits[ 7:0 ] IPC channel
*/
/* System Pipe addresses */
/* CyPipe defines */
#define CY_IPC_CYPIPE_CONFIG_EP0 (uint32_t)( (CY_IPC_CYPIPE_INTR_MASK << CY_IPC_PIPE_CFG_IMASK_Pos) \
| (CY_IPC_INTR_CYPIPE_EP0 << CY_IPC_PIPE_CFG_INTR_Pos) \
| CY_IPC_CHAN_CYPIPE_EP0)
#define CY_IPC_CYPIPE_CONFIG_EP1 (uint32_t)( (CY_IPC_CYPIPE_INTR_MASK << CY_IPC_PIPE_CFG_IMASK_Pos) \
| (CY_IPC_INTR_CYPIPE_EP1 << CY_IPC_PIPE_CFG_INTR_Pos) \
| CY_IPC_CHAN_CYPIPE_EP1)
#define CY_IPC_CYPIPE_INTR_MASK (uint32_t)( CY_IPC_CYPIPE_CHAN_MASK_EP0 | CY_IPC_CYPIPE_CHAN_MASK_EP1 )
/******************************************************************************/
#define CY_IPC_CHAN_USRPIPE_CM0 (uint32_t)(8u)
#define CY_IPC_CHAN_USRPIPE_CM4 (uint32_t)(9u)
#define CY_IPC_INTR_USRPIPE_CM0 (uint32_t)(8u)
#define CY_IPC_INTR_USRPIPE_CM4 (uint32_t)(9u)
#define CY_IPC_EP_USRPIPE_ADDR_EP0 (uint32_t)(2u)
#define CY_IPC_EP_USRPIPE_ADDR_EP1 (uint32_t)(3u)
/* Endpoint indexes in the pipe array */
#define CY_IPC_EP_USRPIPE_CM0_ADDR (uint32_t)(2u)
#define CY_IPC_EP_USRPIPE_CM4_ADDR (uint32_t)(3u)
#if (CY_CPU_CORTEX_M0P)
#define CY_IPC_EP_USRPIPE_ADDR CY_IPC_EP_USRPIPE_CM0_ADDR
#define CY_IPC_EP_USRPIPE_DEST CY_IPC_EP_USRPIPE_CM4_ADDR
#else
#define CY_IPC_EP_USRPIPE_ADDR CY_IPC_EP_USRPIPE_CM4_ADDR
#define CY_IPC_EP_USRPIPE_DEST CY_IPC_EP_USRPIPE_CM0_ADDR
#endif /* (CY_CPU_CORTEX_M0P) */
#define CY_IPC_INTR_USRPIPE_MUX_EP0 (uint32_t)(2u)
#define CY_IPC_INTR_USRPIPE_EP0 CY_IPC_INTR_USRPIPE_CM0
#define CY_IPC_INTR_USRPIPE_PRIOR_EP0 (uint32_t)(1u) /* Notifier Priority */
#define CY_IPC_INTR_USRPIPE_EP1 CY_IPC_INTR_USRPIPE_CM4
#define CY_IPC_INTR_USRPIPE_PRIOR_EP1 (uint32_t)(1u) /* Notifier Priority */
#define CY_IPC_USRPIPE_CHAN_MASK_EP0 (uint32_t)(0x0001ul << CY_IPC_CHAN_USRPIPE_CM0)
#define CY_IPC_USRPIPE_CHAN_MASK_EP1 (uint32_t)(0x0001ul << CY_IPC_CHAN_USRPIPE_CM4)
#define CY_IPC_USRPIPE_CONFIG_EP0 (uint32_t)( (CY_IPC_USRPIPE_INTR_MASK << CY_IPC_PIPE_CFG_IMASK_Pos) \
| (CY_IPC_INTR_USRPIPE_EP0 << CY_IPC_PIPE_CFG_INTR_Pos) \
| CY_IPC_CHAN_USRPIPE_CM0)
#define CY_IPC_USRPIPE_CONFIG_EP1 (uint32_t)( (CY_IPC_USRPIPE_INTR_MASK << CY_IPC_PIPE_CFG_IMASK_Pos) \
| (CY_IPC_INTR_USRPIPE_EP1 << CY_IPC_PIPE_CFG_INTR_Pos) \
| CY_IPC_CHAN_USRPIPE_CM4)
#define CY_IPC_USRPIPE_INTR_MASK (uint32_t)( CY_IPC_USRPIPE_CHAN_MASK_EP0 | CY_IPC_USRPIPE_CHAN_MASK_EP1 )
/******************************************************************************/
#define CY_IPC_CHAN_RPCPIPE_CM0 (uint32_t)(10u)
#define CY_IPC_CHAN_RPCPIPE_CM4 (uint32_t)(11u)
#define CY_IPC_INTR_RPCPIPE_CM0 (uint32_t)(10u)
#define CY_IPC_INTR_RPCPIPE_CM4 (uint32_t)(11u)
#define CY_IPC_EP_RPCPIPE_ADDR_EP0 (uint32_t)(4u)
#define CY_IPC_EP_RPCPIPE_ADDR_EP1 (uint32_t)(5u)
/* Endpoint indexes in the pipe array */
#define CY_IPC_EP_RPCPIPE_CM0_ADDR (uint32_t)(4u)
#define CY_IPC_EP_RPCPIPE_CM4_ADDR (uint32_t)(5u)
#if (CY_CPU_CORTEX_M0P)
#define CY_IPC_EP_RPCPIPE_ADDR CY_IPC_EP_RPCPIPE_CM0_ADDR
#define CY_IPC_EP_RPCPIPE_DEST CY_IPC_EP_RPCPIPE_CM4_ADDR
#else
#define CY_IPC_EP_RPCPIPE_ADDR CY_IPC_EP_RPCPIPE_CM4_ADDR
#define CY_IPC_EP_RPCPIPE_DEST CY_IPC_EP_RPCPIPE_CM0_ADDR
#endif /* (CY_CPU_CORTEX_M0P) */
#define CY_IPC_INTR_RPCPIPE_MUX_EP0 (uint32_t)(4u)
#define CY_IPC_INTR_RPCPIPE_EP0 CY_IPC_INTR_RPCPIPE_CM0
#define CY_IPC_INTR_RPCPIPE_PRIOR_EP0 (uint32_t)(1u) /* Notifier Priority */
#define CY_IPC_INTR_RPCPIPE_EP1 CY_IPC_INTR_RPCPIPE_CM4
#define CY_IPC_INTR_RPCPIPE_PRIOR_EP1 (uint32_t)(1u) /* Notifier Priority */
#define CY_IPC_RPCPIPE_CHAN_MASK_EP0 (uint32_t)(0x0001ul << CY_IPC_CHAN_RPCPIPE_CM0)
#define CY_IPC_RPCPIPE_CHAN_MASK_EP1 (uint32_t)(0x0001ul << CY_IPC_CHAN_RPCPIPE_CM4)
#define CY_IPC_RPCPIPE_CONFIG_EP0 (uint32_t)( (CY_IPC_RPCPIPE_INTR_MASK << CY_IPC_PIPE_CFG_IMASK_Pos) \
| (CY_IPC_INTR_RPCPIPE_EP0 << CY_IPC_PIPE_CFG_INTR_Pos) \
| CY_IPC_CHAN_RPCPIPE_CM0)
#define CY_IPC_RPCPIPE_CONFIG_EP1 (uint32_t)( (CY_IPC_RPCPIPE_INTR_MASK << CY_IPC_PIPE_CFG_IMASK_Pos) \
| (CY_IPC_INTR_RPCPIPE_EP1 << CY_IPC_PIPE_CFG_INTR_Pos) \
| CY_IPC_CHAN_RPCPIPE_CM4)
#define CY_IPC_RPCPIPE_INTR_MASK (uint32_t)( CY_IPC_RPCPIPE_CHAN_MASK_EP0 | CY_IPC_RPCPIPE_CHAN_MASK_EP1 )
#ifdef __cplusplus
extern "C" {
#endif
/*
* \addtogroup group_ipc_configuration_sema
* \{
*/
void Cy_IPC_SystemSemaInit(void);
/* \} group_ipc_configuration_sema */
/*
* \addtogroup group_ipc_configuration_cypipe
* \{
*/
void Cy_IPC_SystemPipeInit(void);
/* \} group_ipc_configuration_cypipe */
void Cy_IPC_SystemPipeIsr(void);
#ifdef __cplusplus
}
#endif
#endif /* CY_IPC_CONFIG_H */
/* [] END OF FILE */

View File

@ -0,0 +1,56 @@
/*******************************************************************************
* 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 2007-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
#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[] = {
#if defined(CY8C637BZI_BLD74)
0x00u, 0x05u, 0xE2u, 0x01u, 0x11u, 0x00u, 0x00u, 0x01u,
0x00u, 0x00u, 0x00u, 0x00u
#elif defined(CY8C6347BZI_BLD53)
0x00u, 0x05u, 0xE2u, 0x07u, 0x21u, 0x00u, 0x21u, 0x01u,
0x00u, 0x00u, 0x00u, 0x00u
#else
#error "Unknown target device"
#endif
};
#if defined(CY8C637BZI_BLD74)
#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
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,556 @@
/***************************************************************************//**
* \file system_psoc63.h
* \version 2.10
*
* \brief Device system header file.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#ifndef _SYSTEM_PSOC63_H_
#define _SYSTEM_PSOC63_H_
/**
* \defgroup group_system_config System Configuration Files (Startup)
* \{
* Provides device startup, system configuration, and linker script files.
* The system startup provides the followings features:
* - See \ref group_system_config_device_initialization for the:
* * \ref group_system_config_dual_core_device_initialization
* * \ref group_system_config_single_core_device_initialization
* - \ref group_system_config_device_memory_definition
* - \ref group_system_config_heap_stack_config
* - \ref group_system_config_merge_apps
* - Default interrupt handlers definition
* - \ref group_system_config_device_vector_table
* - \ref group_system_config_cm4_functions
*
* \section group_system_config_configuration Configuration Considerations
*
* \subsection group_system_config_device_memory_definition Device Memory Definition
* The flash and RAM allocation for each CPU is defined by the linker scripts.
* For dual-core devices, the physical flash and RAM memory is shared between the CPU cores.
* 2 KB of RAM (allocated at the end of RAM) are reserved for system use.
* For Single-Core devices the system reserves additional 80 bytes of RAM.
* Using the reserved memory area for other purposes will lead to unexpected behavior.
*
* \note The linker files provided with the PDL are 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. To eliminate build
* warnings in your project, you can simply comment out or remove the relevant
* code in the linker file.
*
* <b>ARM GCC</b>\n
* The flash and RAM sections for the CPU are defined in the linker files:
* 'xx_yy.ld', where 'xx' is the device group, and 'yy' is the target CPU; for example,
* 'cy8c6xx7_cm0plus.ld' and 'cy8c6xx7_cm4_dual.ld'.
* \note If the start of the Cortex-M4 application image is changed, the value
* of the of the \ref CY_CORTEX_M4_APPL_ADDR should also be changed. The
* \ref CY_CORTEX_M4_APPL_ADDR macro should be used as the parameter for the
* Cy_SysEnableCM4() function call.
*
* Change the flash and RAM sizes by editing the macros value in the
* linker files for both CPUs:
* - 'xx_cm0plus.ld', where 'xx' is the device group:
* \code
* flash (rx) : ORIGIN = 0x10000000, LENGTH = 0x00080000
* ram (rwx) : ORIGIN = 0x08000000, LENGTH = 0x00024000
* \endcode
* - 'xx_cm4_dual.ld', where 'xx' is the device group:
* \code
* flash (rx) : ORIGIN = 0x10080000, LENGTH = 0x00080000
* ram (rwx) : ORIGIN = 0x08024000, LENGTH = 0x00023800
* \endcode
*
* Change the value of the \ref CY_CORTEX_M4_APPL_ADDR macro to the rom ORIGIN's
* value in the 'xx_cm4_dual.ld' file, where 'xx' is the device group. Do this
* by either:
* - Passing the following commands to the compiler:\n
* \code -D CY_CORTEX_M4_APPL_ADDR=0x10080000 \endcode
* - Editing the \ref CY_CORTEX_M4_APPL_ADDR value in the 'system_xx.h', where 'xx' is device family:\n
* \code #define CY_CORTEX_M4_APPL_ADDR (0x10080000u) \endcode
*
* <b>ARM MDK</b>\n
* The flash and RAM sections for the CPU are defined in the linker files:
* 'xx_yy.scat', where 'xx' is the device group, and 'yy' is the target CPU; for example,
* 'cy8c6xx7_cm0plus.scat' and 'cy8c6xx7_cm4_dual.scat'.
* \note If the start of the Cortex-M4 application image is changed, the value
* of the of the \ref CY_CORTEX_M4_APPL_ADDR should also be changed. The
* \ref CY_CORTEX_M4_APPL_ADDR macro should be used as the parameter for the \ref
* Cy_SysEnableCM4() function call.
*
* \note The linker files provided with the PDL are 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 the warnings during the build process:
* L6314W (no section matches pattern) and/or L6329W
* (pattern only matches removed unused sections). In your project, you can
* suppress the warning by passing the "--diag_suppress=L6314W,L6329W" option to
* the linker. You can also comment out or remove the relevant code in the linker
* file.
*
* Change the flash and RAM sizes by editing the macros value in the
* linker files for both CPUs:
* - 'xx_cm0plus.scat', where 'xx' is the device group:
* \code
* #define FLASH_START 0x10000000
* #define FLASH_SIZE 0x00080000
* #define RAM_START 0x08000000
* #define RAM_SIZE 0x00024000
* \endcode
* - 'xx_cm4_dual.scat', where 'xx' is the device group:
* \code
* #define FLASH_START 0x10080000
* #define FLASH_SIZE 0x00080000
* #define RAM_START 0x08024000
* #define RAM_SIZE 0x00023800
* \endcode
*
* Change the value of the \ref CY_CORTEX_M4_APPL_ADDR macro to the FLASH_START
* value in the 'xx_cm4_dual.scat' file,
* where 'xx' is the device group. Do this by either:
* - Passing the following commands to the compiler:\n
* \code -D CY_CORTEX_M4_APPL_ADDR=0x10080000 \endcode
* - Editing the \ref CY_CORTEX_M4_APPL_ADDR value in the 'system_xx.h', where
* 'xx' is device family:\n
* \code #define CY_CORTEX_M4_APPL_ADDR (0x10080000u) \endcode
*
* <b>IAR</b>\n
* The flash and RAM sections for the CPU are defined in the linker files:
* 'xx_yy.icf', where 'xx' is the device group, and 'yy' is the target CPU; for example,
* 'cy8c6xx7_cm0plus.icf' and 'cy8c6xx7_cm4_dual.icf'.
* \note If the start of the Cortex-M4 application image is changed, the value
* of the of the \ref CY_CORTEX_M4_APPL_ADDR should also be changed. The
* \ref CY_CORTEX_M4_APPL_ADDR macro should be used as the parameter for the \ref
* Cy_SysEnableCM4() function call.
*
* Change the flash and RAM sizes by editing the macros value in the
* linker files for both CPUs:
* - 'xx_cm0plus.icf', where 'xx' is the device group:
* \code
* define symbol __ICFEDIT_region_IROM1_start__ = 0x10000000;
* define symbol __ICFEDIT_region_IROM1_end__ = 0x10080000;
* define symbol __ICFEDIT_region_IRAM1_start__ = 0x08000000;
* define symbol __ICFEDIT_region_IRAM1_end__ = 0x08024000;
* \endcode
* - 'xx_cm4_dual.icf', where 'xx' is the device group:
* \code
* define symbol __ICFEDIT_region_IROM1_start__ = 0x10080000;
* define symbol __ICFEDIT_region_IROM1_end__ = 0x10100000;
* define symbol __ICFEDIT_region_IRAM1_start__ = 0x08024000;
* define symbol __ICFEDIT_region_IRAM1_end__ = 0x08047800;
* \endcode
*
* Change the value of the \ref CY_CORTEX_M4_APPL_ADDR macro to the
* __ICFEDIT_region_IROM1_start__ value in the 'xx_cm4_dual.icf' file, where 'xx'
* is the device group. Do this by either:
* - Passing the following commands to the compiler:\n
* \code -D CY_CORTEX_M4_APPL_ADDR=0x10080000 \endcode
* - Editing the \ref CY_CORTEX_M4_APPL_ADDR value in the 'system_xx.h', where
* 'xx' is device family:\n
* \code #define CY_CORTEX_M4_APPL_ADDR (0x10080000u) \endcode
*
* \subsection group_system_config_device_initialization Device Initialization
* After a power-on-reset (POR), the boot process is handled by the boot code
* from the on-chip ROM that is always executed by the Cortex-M0+ core. The boot
* code passes the control to the Cortex-M0+ startup code located in flash.
*
* \subsubsection group_system_config_dual_core_device_initialization Dual-Core Devices
* The Cortex-M0+ startup code performs the device initialization by a call to
* SystemInit() and then calls the main() function. The Cortex-M4 core is disabled
* by default. Enable the core using the \ref Cy_SysEnableCM4() function.
* See \ref group_system_config_cm4_functions for more details.
* \note Startup code executes SystemInit() function for the both Cortex-M0+ and Cortex-M4 cores.
* The function has a separate implementation on each core.
* Both function implementations unlock and disable the WDT.
* Therefore enable the WDT after both cores have been initialized.
*
* \subsubsection group_system_config_single_core_device_initialization Single-Core Devices
* The Cortex-M0+ core is not user-accessible on these devices. In this case the
* Flash Boot handles setup of the CM0+ core and starts the Cortex-M4 core.
*
* \subsection group_system_config_heap_stack_config Heap and Stack Configuration
* There are two ways to adjust heap and stack configurations:
* -# Editing source code files
* -# Specifying via command line
*
* By default, the stack size is set to 0x00001000 and the heap size is set to 0x00000400.
*
* \subsubsection group_system_config_heap_stack_config_gcc ARM GCC
* - <b>Editing source code files</b>\n
* The heap and stack sizes are defined in the assembler startup files:
* 'startup_xx_yy.S', where 'xx' is the device family, and 'yy' is the target CPU;
* for example, startup_psoc63_cm0plus.s and startup_psoc63_cm4.s.
* Change the heap and stack sizes by modifying the following lines:\n
* \code .equ Stack_Size, 0x00001000 \endcode
* \code .equ Heap_Size, 0x00000400 \endcode
*
* - <b>Specifying via command line</b>\n
* Change the heap and stack sizes passing the following commands to the compiler:\n
* \code -D __STACK_SIZE=0x000000400 \endcode
* \code -D __HEAP_SIZE=0x000000100 \endcode
*
* \subsubsection group_system_config_heap_stack_config_mdk ARM MDK
* - <b>Editing source code files</b>\n
* The heap and stack sizes are defined in the assembler startup files:
* 'startup_xx_yy.s', where 'xx' is the device family, and 'yy' is the target
* CPU; for example, startup_psoc63_cm0plus.s and startup_psoc63_cm4.s.
* Change the heap and stack sizes by modifying the following lines:\n
* \code Stack_Size EQU 0x00001000 \endcode
* \code Heap_Size EQU 0x00000400 \endcode
*
* - <b>Specifying via command line</b>\n
* Change the heap and stack sizes passing the following commands to the assembler:\n
* \code "--predefine=___STACK_SIZE SETA 0x000000400" \endcode
* \code "--predefine=__HEAP_SIZE SETA 0x000000100" \endcode
*
* \subsubsection group_system_config_heap_stack_config_iar IAR
* - <b>Editing source code files</b>\n
* The heap and stack sizes are defined in the linker scatter files: 'xx_yy.icf',
* where 'xx' is the device family, and 'yy' is the target CPU; for example,
* cy8c6xx7_cm0plus.icf and cy8c6xx7_cm4_dual.icf.
* Change the heap and stack sizes by modifying the following lines:\n
* \code Stack_Size EQU 0x00001000 \endcode
* \code Heap_Size EQU 0x00000400 \endcode
*
* - <b>Specifying via command line</b>\n
* Change the heap and stack sizes passing the following commands to the
* linker (including quotation marks):\n
* \code --define_symbol __STACK_SIZE=0x000000400 \endcode
* \code --define_symbol __HEAP_SIZE=0x000000100 \endcode
*
* \subsection group_system_config_merge_apps Merging CM0+ and CM4 Executables
* The CM0+ project and linker script build the CM0+ application image. Similarly,
* the CM4 linker script builds the CM4 application image. Each specifies
* locations, sizes, and contents of sections in memory. See
* \ref group_system_config_device_memory_definition for the symbols and default
* values.
*
* The cymcuelftool is invoked by a post-build command. The precise project
* setting is IDE-specific.
*
* The cymcuelftool combines the two executables. The tool examines the
* executables to ensure that memory regions either do not overlap, or contain
* identical bytes (shared). If there are no problems, it creates a new ELF file
* with the merged image, without changing any of the addresses or data.
*
* \subsection group_system_config_device_vector_table Vectors Table Copy from Flash to RAM
* This process uses memory sections defined in the linker script. The startup
* code actually defines the contents of the vector table and performs the copy.
* \subsubsection group_system_config_device_vector_table_gcc ARM GCC
* The linker script file is 'xx_yy.ld', where 'xx' is the device family, and
* 'yy' is the target CPU; for example, cy8c6xx7_cm0plus.ld and cy8c6xx7_cm4_dual.ld.
* It defines sections and locations in memory.\n
* Copy interrupt vectors from flash to RAM: \n
* From: \code LONG (__Vectors) \endcode
* To: \code LONG (__ram_vectors_start__) \endcode
* Size: \code LONG (__Vectors_End - __Vectors) \endcode
* The vector table address (and the vector table itself) are defined in the
* assembler startup files: 'startup_xx_yy.S', where 'xx' is the device family,
* and 'yy' is the target CPU; for example, startup_psoc63_cm0plus.S and
* startup_psoc63_cm4.S. The code in these files copies the vector table from
* Flash to RAM.
* \subsubsection group_system_config_device_vector_table_mdk ARM MDK
* The linker script file is 'xx_yy.scat', where 'xx' is the device family,
* and 'yy' is the target CPU; for example, cy8c6xx7_cm0plus.scat and
* cy8c6xx7_cm4_dual.scat. The linker script specifies that the vector table
* (RESET_RAM) shall be first in the RAM section.\n
* RESET_RAM represents the vector table. It is defined in the assembler startup
* files: 'startup_xx_yy.s', where 'xx' is the device family, and 'yy' is the
* target CPU; for example, startup_psoc63_cm0plus.s and startup_psoc63_cm4.s.
* The code in these files copies the vector table from Flash to RAM.
*
* \subsubsection group_system_config_device_vector_table_iar IAR
* The linker script file is 'xx_yy.icf', where 'xx' is the device family, and
* 'yy' is the target CPU; for example, cy8c6xx7_cm0plus.icf and cy8c6xx7_cm4_dual.icf.
* This file defines the .intvec_ram section and its location.
* \code place at start of IRAM1_region { readwrite section .intvec_ram}; \endcode
* The vector table address (and the vector table itself) are defined in the
* assembler startup files: 'startup_xx_yy.s', where 'xx' is the device family,
* and 'yy' is the target CPU; for example, startup_psoc63_cm0plus.s and
* startup_psoc63_cm4.s. The code in these files copies the vector table
* from Flash to RAM.
*
* \section group_system_config_more_information More Information
* Refer to the <a href="..\..\pdl_user_guide.pdf">PDL User Guide</a> for the
* more details.
*
* \section group_system_config_MISRA MISRA 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>2.3</td>
* <td>R</td>
* <td>The character sequence // shall not be used within a comment.</td>
* <td>The comments provide a useful WEB link to the documentation.</td>
* </tr>
* </table>
*
* \section group_system_config_changelog Changelog
* <table class="doxtable">
* <tr>
* <th>Version</th>
* <th>Changes</th>
* <th>Reason for Change</th>
* </tr>
* <tr>
* <td rowspan="2"> 2.10</td>
* <td>Added constructor attribute to SystemInit() function declaration for ARM MDK compiler. \n
* Removed $Sub$$main symbol for ARM MDK compiler.
* </td>
* <td>uVision Debugger support.</td>
* </tr>
* <tr>
* <td>Updated description of the Startup behavior for Single-Core Devices. \n
* Added note about WDT disabling by SystemInit() function.
* </td>
* <td>Documentation improvement.</td>
* </tr>
* <tr>
* <td rowspan="4"> 2.0</td>
* <td>Added restoring of FLL registers to the default state in SystemInit() API for single core devices.
* Single core device support.
* </td>
* </tr>
* <tr>
* <td>Added Normal Access Restrictions, Public Key, TOC part2 and TOC part2 copy to Supervisory flash linker memory regions. \n
* Renamed 'wflash' memory region to 'em_eeprom'.
* </td>
* <td>Linker scripts usability improvement.</td>
* </tr>
* <tr>
* <td>Added Cy_IPC_SystemSemaInit(), Cy_IPC_SystemPipeInit(), Cy_Flash_Init() functions call to SystemInit() API.</td>
* <td>Reserved system resources for internal operations.</td>
* </tr>
* <tr>
* <td>Added clearing and releasing of IPC structure #7 (reserved for the Deep-Sleep operations) to SystemInit() API.</td>
* <td>To avoid deadlocks in case of SW or WDT reset during Deep-Sleep entering.</td>
* </tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
*
* \defgroup group_system_config_macro Macro
* \{
* \defgroup group_system_config_system_macro System
* \defgroup group_system_config_cm4_status_macro Cortex-M4 Status
* \defgroup group_system_config_user_settings_macro User Settings
* \}
* \defgroup group_system_config_functions Functions
* \{
* \defgroup group_system_config_system_functions System
* \defgroup group_system_config_cm4_functions Cortex-M4 Control
* \}
* \defgroup group_system_config_globals Global Variables
*
* \}
*/
/**
* \addtogroup group_system_config_system_functions
* \{
* \details
* The following system functions implement CMSIS Core functions.
* Refer to the [CMSIS documentation]
* (http://www.keil.com/pack/doc/CMSIS/Core/html/group__system__init__gr.html "System and Clock Configuration")
* for more details.
* \}
*/
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Include files
*******************************************************************************/
#include <stdint.h>
/*******************************************************************************
* Global preprocessor symbols/macros ('define')
*******************************************************************************/
#if ((defined(__GNUC__) && (__ARM_ARCH == 6) && (__ARM_ARCH_6M__ == 1)) || \
(defined (__ICCARM__) && (__CORE__ == __ARM6M__)) || \
(defined(__ARMCC_VERSION) && (__TARGET_ARCH_THUMB == 3)))
#define CY_SYSTEM_CPU_CM0P 1UL
#else
#define CY_SYSTEM_CPU_CM0P 0UL
#endif
#if defined (CY_PSOC_CREATOR_USED) && (CY_PSOC_CREATOR_USED == 1U)
#include "cyfitter.h"
#endif /* (CY_PSOC_CREATOR_USED) && (CY_PSOC_CREATOR_USED == 1U) */
/*******************************************************************************
*
* START OF USER SETTINGS HERE
* ===========================
*
* All lines with '<<<' can be set by user.
*
*******************************************************************************/
/**
* \addtogroup group_system_config_user_settings_macro
* \{
*/
#if defined (CYDEV_CLK_EXTCLK__HZ)
#define CY_CLK_EXT_FREQ_HZ (CYDEV_CLK_EXTCLK__HZ)
#else
/***************************************************************************//**
* External Clock Frequency (in Hz, [value]UL). If compiled within
* PSoC Creator and the clock is enabled in the DWR, the value from DWR used.
* Otherwise, edit the value below.
* <i>(USER SETTING)</i>
*******************************************************************************/
#define CY_CLK_EXT_FREQ_HZ (24000000UL) /* <<< 24 MHz */
#endif /* (CYDEV_CLK_EXTCLK__HZ) */
#if defined (CYDEV_CLK_ECO__HZ)
#define CY_CLK_ECO_FREQ_HZ (CYDEV_CLK_ECO__HZ)
#else
/***************************************************************************//**
* \brief External crystal oscillator frequency (in Hz, [value]UL). If compiled
* within PSoC Creator and the clock is enabled in the DWR, the value from DWR
* used.
* <i>(USER SETTING)</i>
*******************************************************************************/
#define CY_CLK_ECO_FREQ_HZ (24000000UL) /* <<< 24 MHz */
#endif /* (CYDEV_CLK_ECO__HZ) */
#if defined (CYDEV_CLK_ALTHF__HZ)
#define CY_CLK_ALTHF_FREQ_HZ (CYDEV_CLK_ALTHF__HZ)
#else
/***************************************************************************//**
* \brief Alternate high frequency (in Hz, [value]UL). If compiled within
* PSoC Creator and the clock is enabled in the DWR, the value from DWR used.
* Otherwise, edit the value below.
* <i>(USER SETTING)</i>
*******************************************************************************/
#define CY_CLK_ALTHF_FREQ_HZ (32000000UL) /* <<< 32 MHz */
#endif /* (CYDEV_CLK_ALTHF__HZ) */
/***************************************************************************//**
* \brief Start address of the Cortex-M4 application ([address]UL)
* <i>(USER SETTING)</i>
*******************************************************************************/
#define CY_CORTEX_M4_APPL_ADDR (0x10080000UL) /* <<< 512 KB reserved for the Cortex-M0+ application */
/*******************************************************************************
*
* END OF USER SETTINGS HERE
* =========================
*
*******************************************************************************/
/** \} group_system_config_user_settings_macro */
/**
* \addtogroup group_system_config_system_macro
* \{
*/
#if (CY_SYSTEM_CPU_CM0P == 1UL) || defined(CY_DOXYGEN)
/** The Cortex-M0+ startup driver identifier */
#define CY_STARTUP_M0P_ID ((uint32_t)((uint32_t)((0x0Eu) & 0x3FFFu) << 18u))
#endif /* (CY_SYSTEM_CPU_CM0P == 1UL) */
#if (CY_SYSTEM_CPU_CM0P != 1UL) || defined(CY_DOXYGEN)
/** The Cortex-M4 startup driver identifier */
#define CY_STARTUP_M4_ID ((uint32_t)((uint32_t)((0x0Fu) & 0x3FFFu) << 18u))
#endif /* (CY_SYSTEM_CPU_CM0P != 1UL) */
/** \} group_system_config_system_macro */
/**
* \addtogroup group_system_config_system_functions
* \{
*/
extern void SystemInit(void);
extern void SystemCoreClockUpdate(void);
/** \} group_system_config_system_functions */
/**
* \addtogroup group_system_config_cm4_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_system_config_cm4_functions */
/** \cond */
extern void Default_Handler (void);
extern uint32_t Cy_SaveIRQ(void);
extern void Cy_RestoreIRQ(uint32_t saved);
extern void Cy_SystemInit(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;
/** \endcond */
#if (CY_SYSTEM_CPU_CM0P == 1UL) || defined(CY_DOXYGEN)
/**
* \addtogroup group_system_config_cm4_status_macro
* \{
*/
#define CY_SYS_CM4_STATUS_ENABLED (3u) /**< The Cortex-M4 core is enabled: power on, clock on, no isolate, no reset and no retain. */
#define CY_SYS_CM4_STATUS_DISABLED (0u) /**< The Cortex-M4 core is disabled: power off, clock off, isolate, reset and no retain. */
#define CY_SYS_CM4_STATUS_RETAINED (2u) /**< The Cortex-M4 core is retained. power off, clock off, isolate, no reset and retain. */
#define CY_SYS_CM4_STATUS_RESET (1u) /**< The Cortex-M4 core is in the Reset mode: clock off, no isolated, no retain and reset. */
/** \} group_system_config_cm4_status_macro */
#endif /* (CY_SYSTEM_CPU_CM0P == 1UL) */
/** \addtogroup group_system_config_globals
* \{
*/
extern uint32_t SystemCoreClock;
extern uint32_t cy_BleEcoClockFreqHz;
extern uint32_t cy_Hfclk0FreqHz;
extern uint32_t cy_PeriClkFreqHz;
/** \} group_system_config_globals */
#ifdef __cplusplus
}
#endif
#endif /* _SYSTEM_PSOC63_H_ */
/* [] END OF FILE */

View File

@ -0,0 +1,77 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IPC_RPC_H
#define IPC_RPC_H
#include <stdint.h>
#if defined(__MBED__)
#define IPCPIPE_ASSERT MBED_ASSERT
#include "mbed_assert.h"
#else
#include "project.h"
#define IPCPIPE_ASSERT CY_ASSERT
#endif
#define IPCRPC_MAX_ARGUMENTS 8
/** IPC RPC message data structure
* Used to pass RPC call arguments to M0 core for execution
*/
typedef struct {
uint32_t client_id; ///< Client ID of the RPC client
uint32_t result; ///< Function execution result returned from callee to caller
uint32_t args_num; ///< Number of arguments to RPC function call
uint32_t args[IPCRPC_MAX_ARGUMENTS]; ///< Arguments of RPC function call
} IpcRpcMessage;
/** IPC RPC message buffer
* Used to hold and transfer RPC message
*/
typedef struct {
volatile uint8_t busy_flag; ///< Indicates whether the RPC call using this buffer is in progress
IpcRpcMessage message; ///< RPC message associated with a call
} IpcRpcBuffer;
/** Function handling the RPC call
* It packs its arguments into the RPC message buffer, initializes transfer
* and waits for completion.
*
* @param call_id unique identifier of the RPC API function to be executed
* @param args_num number of call arguments
* @param ... call arguments
*
* @return call result (as returned by executed function)
*/
uint32_t ipcrpc_call(uint32_t call_id, uint32_t args_num, ...);
#if defined(__cplusplus)
extern "C" {
#endif
/** Initialization function for RPC mechanism.
* Generated automatically during wrapper generation; needs to be called from startup code.
*/
void ipcrpc_init(void);
#if defined(__cplusplus)
}
#endif
#endif /* IPC_RPC_H */
/* [] END OF FILE */

View File

@ -0,0 +1,74 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This file defines hardware resources statically allocated to M0 core
* when static resource managemnt is used.
*
* There are 4 classes of resources that must be declared here:
* - M0_ASSIGNED_PORTS macro defines which ports and pins are reserved
* for M0 core use.
* You define these as a colon separated list of ports and pins reserved
* using macro SRM_PORT(port_num, pins), one time for each reserved port.
* SRM_PORT macro arguments are port number, in the range 0 .. 14 and
* pins is a hex value with a bit set for each reserved pin on a port.
*
* - M0_ASSIGNED_DIVIDERS macro defines which clock dividers are reserved
* for M0 core use.
* You define these as a colon separated list of dividers reserved
* using macro SRM_DIVIDER(type, reservations), one time for each required
* devider type.
* SRM_DIVIDER arguments are divider type, one of cy_en_divider_types_t
* values and reservations is a hex mask value with a bit set for each
* reserved divider of a given type.
*
* - M0_ASSIGNED_SCBS macro defines which SCB blocks are reserved
* for M0 core use.
* You define these as a colon separated list of SCBs reserved using
* macro SRM_SCB(n), which argument is SCB number in a range 0 .. 7.
*
* - M0_ASSIGNED_TCPWM macro defines which TCPWM blocks are reserved
* for M0 core use.
* You define these as a colon separated list of TCPWMs reserved using
* macro SRM_TCPWM(n), which argument is TCPWM number in a range 0 .. 31.
*
* If a particular resource class is not used at all by M0 core you can
* skip defining relevant M0_ASSIGNED_* macro or define it as an empty one.
*
* Examples:
* #define M0_ASSIGNED_PORTS SRM_PORT(0, 0x30), SRM_PORT(5, 0x03)
*
* #define M0_ASSIGNED_DIVIDERS SRM_DIVIDER(CY_SYSCLK_DIV_8_BIT, 0x01)
*
* #define M0_ASSIGNED_SCBS SRM_SCB(2)
*
* #define M0_ASSIGNED_TCPWMS
*
*/
// Reservations below apply to default M0 hex image.
// P0_0 and p0_1 reserved for WCO, P6-6 and P6_7 reserved for SWD
#define M0_ASSIGNED_PORTS SRM_PORT(0, 0x03), SRM_PORT(6, 0xc0), SRM_PORT(11, 0x02)
// 8-bit divider 0 reserved for us ticker.
#define M0_ASSIGNED_DIVIDERS SRM_DIVIDER(CY_SYSCLK_DIV_8_BIT, 0x01), \
SRM_DIVIDER(CY_SYSCLK_DIV_16_BIT, 0x01)
#define M0_ASSIGNED_SCBS
#define M0_ASSIGNED_TCPWMS
/* End of File */

View File

@ -0,0 +1,253 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PINNAMES_H
#define MBED_PINNAMES_H
#include "cmsis.h"
#include "PinNamesTypes.h"
#include "PortNames.h"
#if PSOC6_ENABLE_M0_M4_DEBUG
#define CY_STDIO_UART_RX P9_0
#define CY_STDIO_UART_TX P9_1
#define CY_STDIO_UART_CTS P9_2
#define CY_STDIO_UART_RTS P9_3
#else
#define CY_STDIO_UART_RX P5_0
#define CY_STDIO_UART_TX P5_1
#define CY_STDIO_UART_CTS P5_2
#define CY_STDIO_UART_RTS P5_3
#endif // PSOC6_ENABLE_M0_M4_DEBUG
// 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,
// Arduino connector namings
A0 = P10_4,
A1 = P10_5,
A2 = P10_2,
A3 = P10_3,
A4 = P10_1,
A5 = P10_0,
D0 = P6_4,
D1 = P6_5,
D2 = P10_6,
D3 = P12_6,
D4 = P12_7,
D5 = P6_2,
D6 = P6_3,
D7 = P7_2,
D8 = P7_1,
D9 = P7_7,
D10 = P9_4,
D11 = P9_0,
D12 = P9_1,
D13 = P9_2,
D14 = P10_1,
D15 = P10_0,
// Generic signal names
I2C_SCL = P10_0,
I2C_SDA = P10_1,
SPI_MOSI = P9_0,
SPI_MISO = P9_1,
SPI_CLK = P9_2,
SPI_CS = P9_3,
UART_RX = P6_4,
UART_TX = P6_5,
SWITCH2 = P0_4,
LED1 = P6_2,
LED2 = P6_3,
LED3 = P7_2,
LED4 = P6_2,
LED_RED = LED1,
USER_BUTTON = SWITCH2,
BUTTON1 = USER_BUTTON,
// Standardized interfaces names
STDIO_UART_TX = CY_STDIO_UART_TX,
STDIO_UART_RX = CY_STDIO_UART_RX,
STDIO_UART_CTS = CY_STDIO_UART_CTS,
STDIO_UART_RTS = CY_STDIO_UART_RTS,
USBTX = CY_STDIO_UART_TX,
USBRX = CY_STDIO_UART_RX,
// Not connected
NC = (int)0xFFFFFFFF
} PinName;
// PinName[15-0] = Port[15-8] + Pin[4-0]
static inline unsigned CY_PIN(PinName pin)
{
return pin & 0x07;
}
static inline unsigned CY_PORT(PinName pin)
{
return (pin >> 8) & 0xFF;
}
// Because MBED pin mapping API does not allow to map multiple instances of the PWM
// to be mapped to the same pin, we create special pin names to force 32-bit PWM unit
// usage instead of standard 16-bit PWM.
#define PWM32(pin) CY_PIN_FORCE_PWM_32(pin)
#endif

View File

@ -0,0 +1,330 @@
/*******************************************************************************
* File Name: board_config.c (formerly cyfitter_cfg.c)
*
* PSoC Creator 4.2
*
* 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 2007-2018, Cypress Semiconductor Corporation. All rights reserved.
* Copyright 2017-2018, Future Electronics
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
#include <string.h>
#include "device.h"
#include "gpio/cy_gpio.h"
#include "syslib/cy_syslib.h"
#include "sysclk/cy_sysclk.h"
#include "systick/cy_systick.h"
#include "sysanalog/cy_sysanalog.h"
#if FEATURE_BLE
#include "ble/cy_ble_clk.h"
#endif // FEATURE_BLE
#define CY_NEED_CYCLOCKSTARTUPERROR 1
#include "syspm/cy_syspm.h"
#include "psoc6_utils.h"
#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
#define CYCLOCKSTART_WCO_ERROR 5u
#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
static void ClockInit(void)
{
uint32_t status;
/* Enable all source clocks */
status = Cy_SysClk_WcoEnable(500000u);
if (CY_RET_SUCCESS != status) {
CyClockStartupError(CYCLOCKSTART_WCO_ERROR);
}
Cy_SysClk_ClkLfSetSource(CY_SYSCLK_CLKLF_IN_WCO);
#if FEATURE_BLE
{
cy_stc_ble_bless_eco_cfg_params_t bleCfg = {
.ecoXtalStartUpTime = (785 / 31.25),
.loadCap = ((9.9 - 7.5) / 0.075),
.ecoFreq = CY_BLE_BLESS_ECO_FREQ_32MHZ,
.ecoSysDiv = CY_BLE_SYS_ECO_CLK_DIV_4
};
Cy_BLE_EcoStart(&bleCfg);
}
#endif // FEATURE_BLE
/* Configure CPU clock dividers */
Cy_SysClk_ClkFastSetDivider(0u);
Cy_SysClk_ClkPeriSetDivider((CY_CLK_HFCLK0_FREQ_HZ / CY_CLK_PERICLK_FREQ_HZ) - 1);
Cy_SysClk_ClkSlowSetDivider((CY_CLK_PERICLK_FREQ_HZ / CY_CLK_SYSTEM_FREQ_HZ) - 1);
/* Configure LF & HF clocks */
Cy_SysClk_ClkHfSetSource(0u, CY_SYSCLK_CLKHF_IN_CLKPATH1);
Cy_SysClk_ClkHfSetDivider(0u, CY_SYSCLK_CLKHF_NO_DIVIDE);
Cy_SysClk_ClkHfEnable(0u);
/* Configure Path Clocks */
/* PLL path is used to clock HF domain from BLE ECO */
Cy_SysClk_ClkPathSetSource(2, CY_SYSCLK_CLKPATH_IN_IMO);
Cy_SysClk_ClkPathSetSource(3, CY_SYSCLK_CLKPATH_IN_IMO);
Cy_SysClk_ClkPathSetSource(4, CY_SYSCLK_CLKPATH_IN_IMO);
#if FEATURE_BLE
Cy_SysClk_ClkPathSetSource(0, CY_SYSCLK_CLKPATH_IN_ALTHF);
Cy_SysClk_ClkPathSetSource(1, CY_SYSCLK_CLKPATH_IN_ALTHF);
{
const cy_stc_pll_config_t pllConfig = {
.inputFreq = CY_CLK_ALTHF_FREQ_HZ,
.outputFreq = CY_CLK_HFCLK0_FREQ_HZ,
.lfMode = false,
.outputMode = CY_SYSCLK_FLLPLL_OUTPUT_AUTO
};
#else
Cy_SysClk_ClkPathSetSource(0, CY_SYSCLK_CLKPATH_IN_IMO);
Cy_SysClk_ClkPathSetSource(1, CY_SYSCLK_CLKPATH_IN_IMO);
{
const cy_stc_pll_config_t pllConfig = {
.inputFreq = CY_CLK_IMO_FREQ_HZ,
.outputFreq = CY_CLK_HFCLK0_FREQ_HZ,
.lfMode = false,
.outputMode = CY_SYSCLK_FLLPLL_OUTPUT_AUTO
};
#endif // FEATURE_BLE
status = Cy_SysClk_PllConfigure(1u, &pllConfig);
if (CY_SYSCLK_SUCCESS != status) {
CyClockStartupError(CYCLOCKSTART_PLL_ERROR);
}
}
status = Cy_SysClk_PllEnable(1u, 10000u);
if (CY_SYSCLK_SUCCESS != status) {
CyClockStartupError(CYCLOCKSTART_PLL_ERROR);
}
/* Configure miscellaneous clocks */
Cy_SysClk_ClkTimerSetSource(CY_SYSCLK_CLKTIMER_IN_HF0_NODIV);
Cy_SysClk_ClkTimerSetDivider(0);
Cy_SysClk_ClkTimerEnable();
Cy_SysClk_ClkPumpSetSource(CY_SYSCLK_PUMP_IN_CLKPATH0);
Cy_SysClk_ClkPumpSetDivider(CY_SYSCLK_PUMP_DIV_4);
Cy_SysClk_ClkPumpEnable();
Cy_SysClk_ClkBakSetSource(CY_SYSCLK_BAK_IN_WCO);
/* Disable unused clocks started by default */
Cy_SysClk_IloDisable();
/* Set memory wait states based on HFClk[0] */
Cy_SysLib_SetWaitStates(false, (CY_CLK_HFCLK0_FREQ_HZ + 990000) / 1000000UL);
}
/* 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)
{
const cy_stc_sysanalog_config_t config = {
.startup = CY_SYSANALOG_STARTUP_NORMAL,
.iztat = CY_SYSANALOG_IZTAT_SOURCE_LOCAL,
.vref = CY_SYSANALOG_VREF_SOURCE_LOCAL_1_2V,
.deepSleep = CY_SYSANALOG_DEEPSLEEP_IPTAT_1
};
Cy_SysAnalog_Init(&config);
Cy_SysAnalog_Enable();
}
/*******************************************************************************
* 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);
if(0u == Cy_SysLib_GetResetReason()) { /* POR, XRES, or BOD */
Cy_SysLib_ResetBackupDomain();
}
/* Power Mode */
Cy_SysPm_LdoSetVoltage(CY_SYSPM_LDO_VOLTAGE_1_1V);
/* PMIC Control */
Cy_SysPm_UnlockPmic();
Cy_SysPm_DisablePmicOutput();
/* Pin0_0 and Pin0_1 drive WCO, configure as analog before configuring clock */
cy_reserve_io_pin(P0_0);
cy_reserve_io_pin(P0_1);
Cy_GPIO_Pin_FastInit(GPIO_PRT0, 0, CY_GPIO_DM_ANALOG, 0, P0_0_GPIO);
Cy_GPIO_Pin_FastInit(GPIO_PRT0, 1, CY_GPIO_DM_ANALOG, 0, P0_1_GPIO);
/* Clock */
ClockInit();
/******* Pre-defined port configuration section ********/
{
/* RGB LED is P_0_3 (R), P_1_1 (G) and P_11_1 (B) */
const uint32_t led_off = 1;
Cy_GPIO_Pin_FastInit(GPIO_PRT0, 3, CY_GPIO_DM_STRONG_IN_OFF, led_off, P0_3_GPIO);
Cy_GPIO_Pin_FastInit(GPIO_PRT1, 1, CY_GPIO_DM_STRONG_IN_OFF, led_off, P1_1_GPIO);
Cy_GPIO_Pin_FastInit(GPIO_PRT11, 1, CY_GPIO_DM_STRONG_IN_OFF, led_off, P11_1_GPIO);
/* USER BUTTON is P_0_4 */
Cy_GPIO_Pin_FastInit(GPIO_PRT0, 4, CY_GPIO_DM_PULLUP, 1, P0_4_GPIO);
/* Configure hw debug interface on port 6 */
cy_reserve_io_pin(P6_6);
cy_reserve_io_pin(P6_7);
Cy_GPIO_Pin_FastInit(GPIO_PRT6, 6, CY_GPIO_DM_PULLUP, 0, P6_6_CPUSS_SWJ_SWDIO_TMS);
Cy_GPIO_Pin_FastInit(GPIO_PRT6, 7, CY_GPIO_DM_PULLDOWN, 0, P6_7_CPUSS_SWJ_SWCLK_TCLK);
}
/* Perform basic analog initialization to defaults */
AnalogSetDefault();
}

View File

@ -0,0 +1,30 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed.h"
/*
* This makes sure, stdio serial is initialized on M4 core at the very beginning
* and outside of any critical context, so printf is usable anywhere, including
* interrupt and fault handlers.
* Hardware devices cannot be initialized in the interrupt or critical section context
* on PSoC 6 M4 core.
*/
#if DEVICE_STDIO_MESSAGES && !defined(TARGET_MCU_PSOC6_M0)
Serial _stdio_uart_object(STDIO_UART_TX, STDIO_UART_RX);
#endif

View File

@ -0,0 +1,171 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "device.h"
#include "analogin_api.h"
#include "cy_sar.h"
#include "psoc6_utils.h"
#include "mbed_assert.h"
#include "mbed_error.h"
#include "pinmap.h"
#include "PeripheralPins.h"
#include "platform/mbed_error.h"
#if DEVICE_ANALOGIN
const uint16_t ADC_MAX_VALUE = 0x0fff;
const uint32_t SAR_BASE_CLOCK_HZ = 18000000; // 18 MHz or less
/** Default SAR channel configuration.
* Notice, that because dynamic SAR MUX switching is disabled,
* per-channel MUX configuration is ignored, thus not configured here.
*/
#define DEFAULT_CHANNEL_CONFIG ( \
CY_SAR_CHAN_SINGLE_ENDED | \
CY_SAR_CHAN_AVG_ENABLE | \
CY_SAR_CHAN_SAMPLE_TIME_0 \
)
/** Global SAR configuration data, modified as channels are configured.
*/
static cy_stc_sar_config_t sar_config = {
.ctrl = CY_SAR_VREF_SEL_VDDA_DIV_2 |
CY_SAR_NEG_SEL_VREF |
CY_SAR_CTRL_COMP_DLY_12 |
CY_SAR_COMP_PWR_50 |
CY_SAR_SARSEQ_SWITCH_DISABLE, /**< Control register */
.sampleCtrl = CY_SAR_RIGHT_ALIGN |
CY_SAR_SINGLE_ENDED_UNSIGNED |
CY_SAR_AVG_CNT_16 |
CY_SAR_AVG_MODE_SEQUENTIAL_FIXED |
CY_SAR_TRIGGER_MODE_FW_ONLY, /**< Sample control register */
.sampleTime01 = (4uL << CY_SAR_SAMPLE_TIME0_SHIFT) |
(4uL << CY_SAR_SAMPLE_TIME1_SHIFT), /**< Sample time in ADC clocks for ST0 and ST1 */
.sampleTime23 = (4uL << CY_SAR_SAMPLE_TIME2_SHIFT) |
(4uL << CY_SAR_SAMPLE_TIME3_SHIFT), /**< Sample time in ADC clocks for ST2 and ST3 */
.rangeThres = 0, /**< Range detect threshold register for all channels (unused)*/
.rangeCond = 0, /**< Range detect mode for all channels (unused)*/
.chanEn = 0, /**< Enable bits for the channels */
.chanConfig = { /**< Channel configuration registers */
DEFAULT_CHANNEL_CONFIG, // chn 0
DEFAULT_CHANNEL_CONFIG, // chn 1
DEFAULT_CHANNEL_CONFIG, // chn 2
DEFAULT_CHANNEL_CONFIG, // chn 3
DEFAULT_CHANNEL_CONFIG, // chn 4
DEFAULT_CHANNEL_CONFIG, // chn 5
DEFAULT_CHANNEL_CONFIG, // chn 6
DEFAULT_CHANNEL_CONFIG, // chn 7
DEFAULT_CHANNEL_CONFIG, // chn 8
DEFAULT_CHANNEL_CONFIG, // chn 9
DEFAULT_CHANNEL_CONFIG, // chn 10
DEFAULT_CHANNEL_CONFIG, // chn 11
DEFAULT_CHANNEL_CONFIG, // chn 12
DEFAULT_CHANNEL_CONFIG, // chn 13
DEFAULT_CHANNEL_CONFIG, // chn 14
DEFAULT_CHANNEL_CONFIG, // chn 15
},
.intrMask = 0, /**< Interrupt enable mask */
.satIntrMask = 0, /**< Saturate interrupt mask register */
.rangeIntrMask = 0, /**< Range interrupt mask register */
.muxSwitch = 0, /**< SARMUX firmware switches to connect analog signals to SAR */
.muxSwitchSqCtrl = 0, /**< SARMUX Switch SAR sequencer control */
.configRouting = false, /**< Configure or ignore routing related registers (muxSwitch, muxSwitchSqCtrl) */
.vrefMvValue = 0, /**< Reference voltage in millivolts used in counts to volts conversion */
};
static bool sar_initialized = false;
static void sar_init(analogin_t *obj)
{
if (!sar_initialized) {
uint32_t sar_clock_divider = CY_INVALID_DIVIDER;
sar_initialized = true;
// Allocate and setup clock.
sar_clock_divider = cy_clk_allocate_divider(CY_SYSCLK_DIV_8_BIT);
if (sar_clock_divider == CY_INVALID_DIVIDER) {
error("SAR clock divider allocation failed.");
return;
}
Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT,
sar_clock_divider,
((CY_CLK_PERICLK_FREQ_HZ + SAR_BASE_CLOCK_HZ / 2) / SAR_BASE_CLOCK_HZ) - 1);
Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, sar_clock_divider);
Cy_SysClk_PeriphAssignDivider(obj->clock, CY_SYSCLK_DIV_8_BIT, sar_clock_divider);
Cy_SAR_Init(obj->base, &sar_config);
Cy_SAR_Enable(obj->base);
}
}
void analogin_init(analogin_t *obj, PinName pin)
{
uint32_t sar = 0;
uint32_t sar_function = 0;
MBED_ASSERT(obj);
MBED_ASSERT(pin != (PinName)NC);
sar = pinmap_peripheral(pin, PinMap_ADC);
if (sar != (uint32_t)NC) {
if (cy_reserve_io_pin(pin)) {
error("ANALOG IN pin reservation conflict.");
}
obj->base = (SAR_Type*)CY_PERIPHERAL_BASE(sar);
obj->pin = pin;
obj->channel_mask = 1 << CY_PIN(pin);
// Configure clock.
sar_function = pinmap_function(pin, PinMap_ADC);
obj->clock = CY_PIN_CLOCK(sar_function);
sar_init(obj);
pin_function(pin, sar_function);
} else {
error("ANALOG IN pinout mismatch.");
}
}
float analogin_read(analogin_t *obj)
{
uint16_t result = analogin_read_u16(obj);
return (float)result * (1.0 / ADC_MAX_VALUE);
}
uint16_t analogin_read_u16(analogin_t *obj)
{
uint32_t result = 0;
Cy_SAR_SetChanMask(obj->base, obj->channel_mask);
Cy_SAR_SetAnalogSwitch(obj->base, CY_SAR_MUX_SWITCH0, obj->channel_mask, CY_SAR_SWITCH_CLOSE);
Cy_SAR_StartConvert(obj->base, CY_SAR_START_CONVERT_SINGLE_SHOT);
if (Cy_SAR_IsEndConversion(obj->base, CY_SAR_WAIT_FOR_RESULT) == CY_SAR_SUCCESS) {
result = Cy_SAR_GetResult32(obj->base, CY_PIN(obj->pin));
} else {
error("ANALOG IN: measurement failed!");
}
Cy_SAR_SetAnalogSwitch(obj->base, CY_SAR_MUX_SWITCH0, obj->channel_mask, CY_SAR_SWITCH_OPEN);
// We are running 16x oversampling extending results to 16 bits.
return (uint16_t)(result);
}
#endif // DEVICE_ANALOGIN

View File

@ -0,0 +1,150 @@
/*
* mbed Microcontroller Library
* Copyright (c) 2017-2018 Future Electronics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "device.h"
#include "analogout_api.h"
#include "cy_ctdac.h"
#include "psoc6_utils.h"
#include "mbed_assert.h"
#include "mbed_error.h"
#include "pinmap.h"
#include "PeripheralPins.h"
#include "platform/mbed_error.h"
#if DEVICE_ANALOGOUT
#define CTDAC_NUM_BITS 12
const uint16_t CTDAC_MAX_VALUE = (uint16_t)((1UL << CTDAC_NUM_BITS) - 1);
const uint32_t CTDAC_BASE_CLOCK_HZ = 500000; // 500 kHz or less
#define CTDAC_DEGLITCH_CYCLES 35
/** Global CTDAC configuration data.
*/
static cy_stc_ctdac_config_t ctdac_config = {
.refSource = CY_CTDAC_REFSOURCE_VDDA, /**< Reference source: Vdda or externally through Opamp1 of CTB */
.formatMode = CY_CTDAC_FORMAT_UNSIGNED, /**< Format of DAC value: signed or unsigned */
.updateMode = CY_CTDAC_UPDATE_BUFFERED_WRITE, /**< Update mode: direct or buffered writes or hardware, edge or level */
.deglitchMode = CY_CTDAC_DEGLITCHMODE_UNBUFFERED, /**< Deglitch mode: disabled, buffered, unbuffered, or both */
.outputMode = CY_CTDAC_OUTPUT_VALUE, /**< Output mode: enabled (value or value + 1), high-z, Vssa, or Vdda */
.outputBuffer = CY_CTDAC_OUTPUT_UNBUFFERED, /**< Output path: Buffered through Opamp0 of CTB or connected directly to Pin 6 */
.deepSleep = CY_CTDAC_DEEPSLEEP_DISABLE, /**< Enable or disable the CTDAC during Deep Sleep */
.deglitchCycles = CTDAC_DEGLITCH_CYCLES, /**< Number of deglitch cycles from 0 to 63 */
.value = 0, /**< Current DAC value */
.nextValue = 0, /**< Next DAC value for double buffering */
.enableInterrupt = false, /**< If true, enable interrupt when next value register is transferred to value register */
.configClock = false, /**< Configure or ignore clock information */
};
static bool ctdac_initialized = 0;
static void ctdac_init(dac_t *obj)
{
if (!ctdac_initialized) {
uint32_t dac_clock_divider = CY_INVALID_DIVIDER;
ctdac_initialized = true;
// Allocate and setup clock.
dac_clock_divider = cy_clk_allocate_divider(CY_SYSCLK_DIV_8_BIT);
if (dac_clock_divider == CY_INVALID_DIVIDER) {
error("CTDAC clock divider allocation failed.");
return;
}
Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT,
dac_clock_divider,
((CY_CLK_PERICLK_FREQ_HZ + CTDAC_BASE_CLOCK_HZ / 2) / CTDAC_BASE_CLOCK_HZ) - 1);
Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, dac_clock_divider);
Cy_SysClk_PeriphAssignDivider(obj->clock, CY_SYSCLK_DIV_8_BIT, dac_clock_divider);
Cy_CTDAC_Init(obj->base, &ctdac_config);
Cy_CTDAC_Enable(obj->base);
}
}
void analogout_init(dac_t *obj, PinName pin)
{
uint32_t dac = 0;
uint32_t dac_function = 0;
MBED_ASSERT(obj);
MBED_ASSERT(pin != (PinName)NC);
dac = pinmap_peripheral(pin, PinMap_DAC);
if (dac != (uint32_t)NC) {
if (cy_reserve_io_pin(pin)) {
error("ANALOG OUT pin reservation conflict.");
}
obj->base = (CTDAC_Type*)CY_PERIPHERAL_BASE(dac);
obj->pin = pin;
// Configure clock.
dac_function = pinmap_function(pin, PinMap_DAC);
obj->clock = CY_PIN_CLOCK(dac_function);
pin_function(pin, dac_function);
ctdac_init(obj);
} else {
error("ANALOG OUT pinout mismatch.");
}
}
void analogout_free(dac_t *obj)
{
// Not supported yet.
}
void analogout_write(dac_t *obj, float value)
{
uint32_t val = 0;
if (value > 1.0) {
val = CTDAC_MAX_VALUE;
} else if (value > 0.0) {
val = value * CTDAC_MAX_VALUE;
}
Cy_CTDAC_SetValueBuffered(obj->base, val);
}
void analogout_write_u16(dac_t *obj, uint16_t value)
{
uint32_t val = 0;
val = (value >> (16 - CTDAC_NUM_BITS)); // Convert from 16-bit range.
Cy_CTDAC_SetValueBuffered(obj->base, val);
}
float analogout_read(dac_t *obj)
{
return (float)analogout_read_u16(obj) / 0xffff;
}
uint16_t analogout_read_u16(dac_t *obj)
{
uint16_t value = (obj->base->CTDAC_VAL_NXT >> CTDAC_CTDAC_VAL_NXT_VALUE_Pos) & CTDAC_CTDAC_VAL_NXT_VALUE_Msk;
value <<= (16 - CTDAC_NUM_BITS); // Convert to 16-bit range.
return value;
}
#endif // DEVICE_ANALOGIN

View File

@ -0,0 +1,2 @@
version 3.0.1

View File

@ -0,0 +1,4 @@
README for Cypress Peripheral Driver Library
============================================
This folder tree contains parts of Cypress Peripheral Driver Library (PDL) necessary to support PSoC 6 MCUs. See [Cypress PDL page](http://www.cypress.com/documentation/software-and-drivers/peripheral-driver-library-pdl) for details.

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,721 @@
/***************************************************************************//**
* \file cy_ctdac.c
* \version 1.0.1
*
* Provides the public functions for the API for the CTDAC driver.
*
********************************************************************************
* \copyright
* Copyright 2017-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "ctdac/cy_ctdac.h"
#if defined(__cplusplus)
extern "C" {
#endif
/** Static function to configure the clock */
static void Cy_CTDAC_ConfigureClock(cy_en_ctdac_update_t updateMode, cy_en_divider_types_t dividerType,
uint32_t dividerNum, uint32_t dividerIntValue, uint32_t dividerFracValue);
const cy_stc_ctdac_fast_config_t Cy_CTDAC_Fast_VddaRef_UnbufferedOut =
{
/*.refSource */ CY_CTDAC_REFSOURCE_VDDA,
/*.outputBuffer */ CY_CTDAC_OUTPUT_UNBUFFERED,
};
const cy_stc_ctdac_fast_config_t Cy_CTDAC_Fast_VddaRef_BufferedOut =
{
/*.refSource */ CY_CTDAC_REFSOURCE_VDDA,
/*.outputBuffer */ CY_CTDAC_OUTPUT_BUFFERED,
};
const cy_stc_ctdac_fast_config_t Cy_CTDAC_Fast_OA1Ref_UnbufferedOut =
{
/*.refSource */ CY_CTDAC_REFSOURCE_EXTERNAL,
/*.outputBuffer */ CY_CTDAC_OUTPUT_UNBUFFERED,
};
const cy_stc_ctdac_fast_config_t Cy_CTDAC_Fast_OA1Ref_BufferedOut =
{
/*.refSource */ CY_CTDAC_REFSOURCE_EXTERNAL,
/*.outputBuffer */ CY_CTDAC_OUTPUT_BUFFERED,
};
/*******************************************************************************
* Function Name: Cy_CTDAC_Init
****************************************************************************//**
*
* Initialize all CTDAC configuration registers
*
* \param base
* Pointer to structure describing registers
*
* \param config
* Pointer to structure containing configuration data
*
* \return
* Status of initialization, \ref CY_CTDAC_SUCCESS or \ref CY_CTDAC_BAD_PARAM
*
* \funcusage
*
* \snippet ctdac_sut_01.cydsn/main_cm4.c CTDAC_SNIPPET_INIT_CUSTOM
*
*******************************************************************************/
cy_en_ctdac_status_t Cy_CTDAC_Init(CTDAC_Type *base, const cy_stc_ctdac_config_t *config)
{
CY_ASSERT_L1(NULL != base);
CY_ASSERT_L1(NULL != config);
cy_en_ctdac_status_t result;
uint32_t ctdacCtrl = CY_CTDAC_DEINIT;
uint32_t setSwitch = CY_CTDAC_DEINIT;
uint32_t clearSwitch = CY_CTDAC_DEINIT;
if ((NULL == base) || (NULL == config))
{
result = CY_CTDAC_BAD_PARAM;
}
else
{
CY_ASSERT_L3(CY_CTDAC_REFSOURCE(config->refSource));
CY_ASSERT_L3(CY_CTDAC_FORMAT(config->formatMode));
CY_ASSERT_L3(CY_CTDAC_UPDATE(config->updateMode));
CY_ASSERT_L3(CY_CTDAC_DEGLITCH(config->deglitchMode));
CY_ASSERT_L3(CY_CTDAC_OUTPUTMODE(config->outputMode));
CY_ASSERT_L3(CY_CTDAC_OUTPUTBUFFER(config->outputBuffer));
CY_ASSERT_L3(CY_CTDAC_DEEPSLEEP(config->deepSleep));
CY_ASSERT_L2(CY_CTDAC_DEGLITCHCYCLES(config->deglitchCycles));
/* Handle the deglitch counts */
ctdacCtrl |= (config->deglitchCycles << CTDAC_CTDAC_CTRL_DEGLITCH_CNT_Pos) & CTDAC_CTDAC_CTRL_DEGLITCH_CNT_Msk;
/* Handle the deglitch mode */
ctdacCtrl |= (uint32_t)config->deglitchMode;
/* Handle the update mode */
if ((config->updateMode == CY_CTDAC_UPDATE_STROBE_EDGE_IMMEDIATE) \
|| (config->updateMode == CY_CTDAC_UPDATE_STROBE_EDGE_SYNC) \
|| (config->updateMode == CY_CTDAC_UPDATE_STROBE_LEVEL))
{
ctdacCtrl |= CTDAC_CTDAC_CTRL_DSI_STROBE_EN_Msk;
}
if (config->updateMode == CY_CTDAC_UPDATE_STROBE_LEVEL)
{
ctdacCtrl |= CTDAC_CTDAC_CTRL_DSI_STROBE_LEVEL_Msk;
}
/* Handle the sign format */
ctdacCtrl |= (uint32_t)config->formatMode;
/* Handle the Deep Sleep mode */
ctdacCtrl |= (uint32_t)config->deepSleep;
/* Handle the output mode */
ctdacCtrl |= (uint32_t)config->outputMode;
/* Handle the reference source */
switch(config->refSource)
{
case CY_CTDAC_REFSOURCE_VDDA:
/* Close the CVD switch to use Vdda as the reference source */
setSwitch |= CTDAC_CTDAC_SW_CTDD_CVD_Msk;
break;
case CY_CTDAC_REFSOURCE_EXTERNAL:
default:
clearSwitch |= CTDAC_CTDAC_SW_CLEAR_CTDD_CVD_Msk;
break;
}
/* Handle the output buffer switch CO6 */
switch(config->outputBuffer)
{
case CY_CTDAC_OUTPUT_UNBUFFERED:
/* Close the CO6 switch to send output to a direct pin unbuffered */
setSwitch |= CTDAC_CTDAC_SW_CTDO_CO6_Msk;
break;
case CY_CTDAC_OUTPUT_BUFFERED:
default:
clearSwitch |= CTDAC_CTDAC_SW_CTDO_CO6_Msk;
break;
}
base->INTR_MASK = (uint32_t)config->enableInterrupt << CTDAC_INTR_VDAC_EMPTY_Pos;
base->CTDAC_SW = setSwitch;
base->CTDAC_SW_CLEAR = clearSwitch;
base->CTDAC_VAL = (((uint32_t)config->value) << CTDAC_CTDAC_VAL_VALUE_Pos) & CTDAC_CTDAC_VAL_VALUE_Msk;
base->CTDAC_VAL_NXT = (((uint32_t)config->nextValue) << CTDAC_CTDAC_VAL_NXT_VALUE_Pos) & CTDAC_CTDAC_VAL_NXT_VALUE_Msk;
if (config->configClock)
{
Cy_CTDAC_ConfigureClock(config->updateMode, config->dividerType, config->dividerNum, config->dividerIntValue, config->dividerFracValue);
}
base->CTDAC_CTRL = ctdacCtrl;
result = CY_CTDAC_SUCCESS;
}
return result;
}
/*******************************************************************************
* Function Name: Cy_CTDAC_DeInit
****************************************************************************//**
*
* Reset CTDAC registers back to power on reset defaults.
*
* \note
* Does not disable the clock.
*
* \param base
* Pointer to structure describing registers
*
* \param deInitRouting
* If true, all switches are reset to their default state.
* If false, switch registers are untouched.
*
* \return
* Status of initialization, \ref CY_CTDAC_SUCCESS, or \ref CY_CTDAC_BAD_PARAM
*
* \funcusage
*
* \snippet ctdac_sut_01.cydsn/main_cm4.c CTDAC_SNIPPET_DEINIT
*
*******************************************************************************/
cy_en_ctdac_status_t Cy_CTDAC_DeInit(CTDAC_Type *base, bool deInitRouting)
{
CY_ASSERT_L1(NULL != base);
cy_en_ctdac_status_t result;
if (NULL == base)
{
result = CY_CTDAC_BAD_PARAM;
}
else
{
base->CTDAC_CTRL = CY_CTDAC_DEINIT;
base->INTR_MASK = CY_CTDAC_DEINIT;
base->CTDAC_VAL = CY_CTDAC_DEINIT;
base->CTDAC_VAL_NXT = CY_CTDAC_DEINIT;
if (deInitRouting)
{
base->CTDAC_SW_CLEAR = CY_CTDAC_DEINIT;
}
result = CY_CTDAC_SUCCESS;
}
return result;
}
/*******************************************************************************
* Function Name: Cy_CTDAC_FastInit
****************************************************************************//**
*
* Initialize the CTDAC to one of the common use modes.
* This function provides a quick and easy method of configuring the CTDAC when using
* the PDL driver for device configuration.
*
* The other configuration options are set to:
* - .formatMode = \ref CY_CTDAC_FORMAT_UNSIGNED
* - .updateMode = \ref CY_CTDAC_UPDATE_BUFFERED_WRITE
* - .deglitchMode = \ref CY_CTDAC_DEGLITCHMODE_NONE
* - .outputMode = \ref CY_CTDAC_OUTPUT_VALUE
* - .deepSleep = \ref CY_CTDAC_DEEPSLEEP_DISABLE
* - .deglitchCycles = \ref CY_CTDAC_DEINIT
* - .value = \ref CY_CTDAC_UNSIGNED_MID_CODE_VALUE
* - .nextValue = \ref CY_CTDAC_UNSIGNED_MID_CODE_VALUE
* - .enableInterrupt = true
* - .configClock = true
* - .dividerType = \ref CY_CTDAC_FAST_CLKCFG_TYPE
* - .dividerNum = \ref CY_CTDAC_FAST_CLKCFG_NUM
* - .dividerInitValue = \ref CY_CTDAC_FAST_CLKCFG_DIV
* - .dividerFracValue = \ref CY_CTDAC_DEINIT
*
* A separate call to \ref Cy_CTDAC_Enable is needed to turn on the hardware.
*
* \param base
* Pointer to structure describing registers
*
* \param config
* Pointer to structure containing configuration data for quick initialization.
* Define your own or use one of the provided structures:
* - \ref Cy_CTDAC_Fast_VddaRef_UnbufferedOut
* - \ref Cy_CTDAC_Fast_VddaRef_BufferedOut
* - \ref Cy_CTDAC_Fast_OA1Ref_UnbufferedOut
* - \ref Cy_CTDAC_Fast_OA1Ref_BufferedOut
*
* \return
* Status of initialization, \ref CY_CTDAC_SUCCESS or \ref CY_CTDAC_BAD_PARAM
*
* \funcusage
*
* The following code snippets configures VDDA as the reference source and
* routes the output directly to Pin 6 (unbuffered).
*
* \snippet ctdac_sut_01.cydsn/main_cm4.c CTDAC_SNIPPET_FAST_INIT
*
* \funcusage
*
* The following code snippet shows how the CTDAC and CTB blocks can
* quickly be configured to work together. The code
* configures the CTDAC to use a buffered output,
* a buffered reference source from the internal bandgap voltage, and closes
* all required analog routing switches.
*
* \image html ctdac_fast_init_funcusage.png
* \image latex ctdac_fast_init_funcusage.png
*
* \snippet ctdac_sut_01.cydsn/main_cm4.c CTDAC_SNIPPET_FAST_INIT_CTB
*
*******************************************************************************/
cy_en_ctdac_status_t Cy_CTDAC_FastInit(CTDAC_Type *base, const cy_stc_ctdac_fast_config_t *config)
{
CY_ASSERT_L1(NULL != base);
CY_ASSERT_L1(NULL != config);
cy_en_ctdac_status_t result;
uint32_t ctdacCtrl;
uint32_t setSwitch = CY_CTDAC_DEINIT;
uint32_t clearSwitch = CY_CTDAC_DEINIT;
if ((NULL == base) || (NULL == config))
{
result = CY_CTDAC_BAD_PARAM;
}
else
{
CY_ASSERT_L3(CY_CTDAC_REFSOURCE(config->refSource));
CY_ASSERT_L3(CY_CTDAC_OUTPUTBUFFER(config->outputBuffer));
ctdacCtrl = (uint32_t) CY_CTDAC_DEGLITCHMODE_NONE \
| (uint32_t) CY_CTDAC_UPDATE_BUFFERED_WRITE \
| (uint32_t) CY_CTDAC_FORMAT_UNSIGNED \
| (uint32_t) CY_CTDAC_DEEPSLEEP_DISABLE \
| (uint32_t) CY_CTDAC_OUTPUT_VALUE;
/* Handle the reference source */
switch(config->refSource)
{
case CY_CTDAC_REFSOURCE_VDDA:
/* Close the CVD switch to use Vdda as the reference source */
setSwitch |= CTDAC_CTDAC_SW_CTDD_CVD_Msk;
break;
case CY_CTDAC_REFSOURCE_EXTERNAL:
default:
clearSwitch |= CTDAC_CTDAC_SW_CLEAR_CTDD_CVD_Msk;
break;
}
/* Handle the output buffer switch CO6 */
switch(config->outputBuffer)
{
case CY_CTDAC_OUTPUT_UNBUFFERED:
/* Close the CO6 switch to send output to a direct pin unbuffered */
setSwitch |= CTDAC_CTDAC_SW_CTDO_CO6_Msk;
break;
case CY_CTDAC_OUTPUT_BUFFERED:
default:
clearSwitch |= CTDAC_CTDAC_SW_CTDO_CO6_Msk;
break;
}
base->INTR_MASK = CTDAC_INTR_VDAC_EMPTY_Msk;
base->CTDAC_SW = setSwitch;
base->CTDAC_SW_CLEAR = clearSwitch;
base->CTDAC_VAL = CY_CTDAC_UNSIGNED_MID_CODE_VALUE;
base->CTDAC_VAL_NXT = CY_CTDAC_UNSIGNED_MID_CODE_VALUE;
/* For fast configuration, the DAC clock is the Peri clock divided by 100. */
Cy_CTDAC_ConfigureClock(CY_CTDAC_UPDATE_BUFFERED_WRITE, CY_CTDAC_FAST_CLKCFG_TYPE, CY_CTDAC_FAST_CLKCFG_NUM, CY_CTDAC_FAST_CLKCFG_DIV, CY_CTDAC_DEINIT);
base->CTDAC_CTRL = ctdacCtrl;
result = CY_CTDAC_SUCCESS;
}
return result;
}
/*******************************************************************************
* Function Name: Cy_CTDAC_ConfigureClock
****************************************************************************//**
*
* Private function for configuring the CTDAC clock based on the desired
* update mode. This function is called by \ref Cy_CTDAC_Init.
*
* \param updateMode
* Update mode value. See \ref cy_en_ctdac_update_t for values.
*
* \return None
*
*******************************************************************************/
static void Cy_CTDAC_ConfigureClock(cy_en_ctdac_update_t updateMode, cy_en_divider_types_t dividerType,
uint32_t dividerNum, uint32_t dividerIntValue, uint32_t dividerFracValue)
{
if (updateMode == CY_CTDAC_UPDATE_DIRECT_WRITE)
{ /* In direct mode, there is not a clock */
}
else if(updateMode == CY_CTDAC_UPDATE_STROBE_EDGE_IMMEDIATE)
{
/* In this mode, the Peri Clock is divided by 1 to give a constant logic high on the CTDAC clock. */
(void)Cy_SysClk_PeriphDisableDivider(dividerType, dividerNum);
(void)Cy_SysClk_PeriphAssignDivider(PCLK_PASS_CLOCK_CTDAC, dividerType, dividerNum);
if ((dividerType == CY_SYSCLK_DIV_8_BIT) || (dividerType == CY_SYSCLK_DIV_16_BIT))
{
(void)Cy_SysClk_PeriphSetDivider(dividerType, dividerNum, CY_CTDAC_STROBE_EDGE_IMMEDIATE_DIV);
}
else
{
(void)Cy_SysClk_PeriphSetFracDivider(dividerType, dividerNum, CY_CTDAC_STROBE_EDGE_IMMEDIATE_DIV, CY_CTDAC_STROBE_EDGE_IMMEDIATE_DIV_FRAC);
}
(void)Cy_SysClk_PeriphEnableDivider(dividerType, dividerNum);
}
else
{
/* All other modes, require a CTDAC clock configured to the desired user frequency */
(void)Cy_SysClk_PeriphDisableDivider(dividerType, dividerNum);
(void)Cy_SysClk_PeriphAssignDivider(PCLK_PASS_CLOCK_CTDAC, dividerType, dividerNum);
if ((dividerType == CY_SYSCLK_DIV_8_BIT) || (dividerType == CY_SYSCLK_DIV_16_BIT))
{
(void)Cy_SysClk_PeriphSetDivider(dividerType, dividerNum, dividerIntValue);
}
else
{
(void)Cy_SysClk_PeriphSetFracDivider(dividerType, dividerNum, dividerIntValue, dividerFracValue);
}
(void)Cy_SysClk_PeriphEnableDivider(dividerType, dividerNum);
}
}
/*******************************************************************************
* Function Name: Cy_CTDAC_SetSignMode
****************************************************************************//**
*
* Set whether to interpret the DAC value as signed or unsigned.
* In unsigned mode, the DAC value register is used without any decoding.
* In signed mode, the MSB is inverted by adding 0x800 to the DAC value.
* This converts the lowest signed number, 0x800, to the lowest unsigned
* number, 0x000.
*
* \param base
* Pointer to structure describing registers
*
* \param formatMode
* Mode can be signed or unsigned. See \ref cy_en_ctdac_format_t for values.
*
* \return None
*
* \funcusage
*
* \snippet ctdac_sut_01.cydsn/main_cm4.c CTDAC_SNIPPET_SET_SIGN_MODE
*
*******************************************************************************/
void Cy_CTDAC_SetSignMode(CTDAC_Type *base, cy_en_ctdac_format_t formatMode)
{
CY_ASSERT_L3(CY_CTDAC_FORMAT(formatMode));
uint32_t ctdacCtrl;
/* Clear the CTDAC_MODE bits */
ctdacCtrl = base->CTDAC_CTRL & ~CTDAC_CTDAC_CTRL_CTDAC_MODE_Msk;
base->CTDAC_CTRL = ctdacCtrl | (uint32_t)formatMode;
}
/*******************************************************************************
* Function Name: Cy_CTDAC_SetDeepSleepMode
****************************************************************************//**
*
* Enable or disable the DAC hardware operation in Deep Sleep mode.
*
* \param base
* Pointer to structure describing registers
*
* \param deepSleep
* Enable or disable Deep Sleep operation. Select value from \ref cy_en_ctdac_deep_sleep_t.
*
* \return None
*
* \funcusage
*
* \snippet ctdac_sut_01.cydsn/main_cm4.c CTDAC_SNIPPET_SET_DEEPSLEEP_MODE
*
*******************************************************************************/
void Cy_CTDAC_SetDeepSleepMode(CTDAC_Type *base, cy_en_ctdac_deep_sleep_t deepSleep)
{
CY_ASSERT_L3(CY_CTDAC_DEEPSLEEP(deepSleep));
uint32_t ctdacCtrl;
ctdacCtrl = base->CTDAC_CTRL & ~CTDAC_CTDAC_CTRL_DEEPSLEEP_ON_Msk;
base->CTDAC_CTRL = ctdacCtrl | (uint32_t)deepSleep;
}
/*******************************************************************************
* Function Name: Cy_CTDAC_SetOutputMode
****************************************************************************//**
*
* Set the output mode of the CTDAC:
* - \ref CY_CTDAC_OUTPUT_HIGHZ : Disable the output
* - \ref CY_CTDAC_OUTPUT_VALUE : Enable the output and drive the value
* stored in the CTDAC_VAL register.
* - \ref CY_CTDAC_OUTPUT_VALUE_PLUS1 : Enable the output and drive the
* value stored in the CTDAC_VAL register plus 1.
* - \ref CY_CTDAC_OUTPUT_VSSA : Output pulled to VSSA through 1.1 MOhm (typ) resistor.
* - \ref CY_CTDAC_OUTPUT_VREF : Output pulled to VREF through 1.1 MOhm (typ) resistor.
*
* \param base
* Pointer to structure describing registers
*
* \param outputMode
* Select a value from \ref cy_en_ctdac_output_mode_t.
*
* \return None
*
* \funcusage
*
* \snippet ctdac_sut_01.cydsn/main_cm4.c CTDAC_SNIPPET_SET_OUTPUT_MODE
*
*******************************************************************************/
void Cy_CTDAC_SetOutputMode(CTDAC_Type *base, cy_en_ctdac_output_mode_t outputMode)
{
CY_ASSERT_L3(CY_CTDAC_OUTPUTMODE(outputMode));
uint32_t ctdacCtrl;
/* Clear out the three affected bits */
ctdacCtrl = base->CTDAC_CTRL & ~(CTDAC_CTDAC_CTRL_OUT_EN_Msk | CTDAC_CTDAC_CTRL_DISABLED_MODE_Msk | CTDAC_CTDAC_CTRL_CTDAC_RANGE_Msk);
base->CTDAC_CTRL = ctdacCtrl | (uint32_t)outputMode;
}
/*******************************************************************************
* Function Name: Cy_CTDAC_SetDeglitchMode
****************************************************************************//**
*
* Enable deglitching on the unbuffered path, buffered path, both, or
* disable deglitching. The deglitch mode should match the configured output path.
*
* \param base
* Pointer to structure describing registers
*
* \param deglitchMode
* Deglitching mode selection. See \ref cy_en_ctdac_deglitch_t for values.
*
* \return None
*
* \funcusage
*
* \snippet ctdac_sut_01.cydsn/main_cm4.c CTDAC_SNIPPET_SET_DEGLITCH_MODE
*
*******************************************************************************/
void Cy_CTDAC_SetDeglitchMode(CTDAC_Type *base, cy_en_ctdac_deglitch_t deglitchMode)
{
CY_ASSERT_L3(CY_CTDAC_DEGLITCH(deglitchMode));
uint32_t ctdacCtrl;
/* Clear out DEGLITCH_CO6 and DEGLITCH_C0S bits */
ctdacCtrl = base->CTDAC_CTRL & ~(CTDAC_CTDAC_CTRL_DEGLITCH_COS_Msk | CTDAC_CTDAC_CTRL_DEGLITCH_CO6_Msk);
base->CTDAC_CTRL = ctdacCtrl | (uint32_t)deglitchMode;
}
/*******************************************************************************
* Function Name: Cy_CTDAC_SetDeglitchCycles
****************************************************************************//**
*
* Set the number of deglitch cycles (0 to 63) that will be used.
* To calculate the deglitch time:
*
* (DEGLITCH_CNT + 1) / PERI_CLOCK_FREQ
*
* The optimal deglitch time is 700 ns.
*
* \param base
* Pointer to structure describing registers
*
* \param deglitchCycles
* Number of cycles to deglitch
*
* \return None
*
* \funcusage
*
* \snippet ctdac_sut_01.cydsn/main_cm4.c CTDAC_SNIPPET_SET_DEGLITCH_CYCLES
*
*******************************************************************************/
void Cy_CTDAC_SetDeglitchCycles(CTDAC_Type *base, uint32_t deglitchCycles)
{
CY_ASSERT_L2(CY_CTDAC_DEGLITCHCYCLES(deglitchCycles));
uint32_t ctdacCtrl;
ctdacCtrl = (base->CTDAC_CTRL) & ~CTDAC_CTDAC_CTRL_DEGLITCH_CNT_Msk;
base->CTDAC_CTRL = ctdacCtrl | ((deglitchCycles << CTDAC_CTDAC_CTRL_DEGLITCH_CNT_Pos) & CTDAC_CTDAC_CTRL_DEGLITCH_CNT_Msk);
}
/*******************************************************************************
* Function Name: Cy_CTDAC_SetRef
****************************************************************************//**
*
* Set the CTDAC reference source to Vdda or an external reference.
* The external reference must come from Opamp1 of the CTB.
*
* \param base
* Pointer to structure describing registers
*
* \param refSource
* The reference source. Select a value from \ref cy_en_ctdac_ref_source_t.
*
* \return None
*
* \funcusage
*
* \snippet ctdac_sut_01.cydsn/main_cm4.c CTDAC_SNIPPET_SET_REF
*
*******************************************************************************/
void Cy_CTDAC_SetRef(CTDAC_Type *base, cy_en_ctdac_ref_source_t refSource)
{
CY_ASSERT_L3(CY_CTDAC_REFSOURCE(refSource));
switch(refSource)
{
case CY_CTDAC_REFSOURCE_VDDA:
/* Close the CVD switch to use Vdda as the reference source */
base->CTDAC_SW |= CTDAC_CTDAC_SW_CTDD_CVD_Msk;
break;
case CY_CTDAC_REFSOURCE_EXTERNAL:
default:
base->CTDAC_SW_CLEAR = CTDAC_CTDAC_SW_CLEAR_CTDD_CVD_Msk;
break;
}
}
/*******************************************************************************
* Function Name: Cy_CTDAC_SetAnalogSwitch
****************************************************************************//**
*
* Provide firmware control of the CTDAC switches. Each call to this function
* can open a set of switches or close a set of switches.
*
* \note
* The switches are configured by the reference
* source and output mode selections during initialization.
*
* \param base
* Pointer to structure describing registers
*
* \param switchMask
* The mask of the switches to either open or close.
* Select one or more values from \ref cy_en_ctdac_switches_t and "OR" them together.
*
* \param state
* Open or close the switche(s). Select a value from \ref cy_en_ctdac_switch_state_t.
*
* \return None
*
* \funcusage
*
* \snippet ctdac_sut_01.cydsn/main_cm4.c CTDAC_SNIPPET_SET_ANALOG_SWITCH
*
*******************************************************************************/
void Cy_CTDAC_SetAnalogSwitch(CTDAC_Type *base, uint32_t switchMask, cy_en_ctdac_switch_state_t state)
{
CY_ASSERT_L2(CY_CTDAC_SWITCHMASK(switchMask));
CY_ASSERT_L3(CY_CTDAC_SWITCHSTATE(state));
switch(state)
{
case CY_CTDAC_SWITCH_CLOSE:
base->CTDAC_SW |= switchMask;
break;
case CY_CTDAC_SWITCH_OPEN:
default:
/* Unlike the close case, do not OR the register. Set 1 to clear.*/
base->CTDAC_SW_CLEAR = switchMask;
break;
}
}
/*******************************************************************************
* Function Name: Cy_CTDAC_DeepSleepCallback
****************************************************************************//**
*
* Callback to prepare the CTDAC before entering and after exiting Deep Sleep
* mode. If deglitching is used, it is disabled before entering Deep Sleep
* to ensure the deglitch switches are closed. This is needed only
* if the CTDAC will be enabled in DeepSleep. Upon wakeup, deglitching will
* be re-enabled if it was previously used.
*
* \param callbackParams
* Pointer to structure of type \ref cy_stc_syspm_callback_params_t
*
* \return
* See \ref cy_en_syspm_status_t
*
* \funcusage
*
* \snippet ctdac_sut_01.cydsn/main_cm4.c CTDAC_SNIPPET_DEEP_SLEEP_CALLBACK
*
*******************************************************************************/
cy_en_syspm_status_t Cy_CTDAC_DeepSleepCallback(cy_stc_syspm_callback_params_t *callbackParams)
{
/* Static variable preserved between function calls.
* Tracks the state of the deglitch mode before sleep so that it can be re-enabled after wakeup */
static uint32_t deglitchModeBeforeSleep;
cy_en_syspm_status_t returnValue = CY_SYSPM_SUCCESS;
CTDAC_Type *ctdacBase = (CTDAC_Type *)callbackParams->base;
if (CY_SYSPM_BEFORE_TRANSITION == callbackParams->mode)
{ /* Actions that should be done before entering the Deep Sleep mode */
/* Store the state of the deglitch switches before turning deglitch off */
deglitchModeBeforeSleep = ctdacBase->CTDAC_CTRL & (CTDAC_CTDAC_CTRL_DEGLITCH_CO6_Msk | CTDAC_CTDAC_CTRL_DEGLITCH_COS_Msk);
/* Turn deglitch off before entering Deep Sleep */
ctdacBase->CTDAC_CTRL &= ~(CTDAC_CTDAC_CTRL_DEGLITCH_CO6_Msk | CTDAC_CTDAC_CTRL_DEGLITCH_COS_Msk);
}
else if (CY_SYSPM_AFTER_TRANSITION == callbackParams->mode)
{ /* Actions that should be done after exiting the Deep Sleep mode */
/* Re-enable the deglitch mode that was configured before Deep Sleep entry */
ctdacBase->CTDAC_CTRL |= deglitchModeBeforeSleep;
}
else
{ /* Does nothing in other modes */
}
return returnValue;
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,353 @@
/***************************************************************************//**
* \file cy_dma.c
* \version 2.0.1
*
* \brief
* The source code file for the DMA driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "cy_dma.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_DMA_Descriptor_Init
****************************************************************************//**
*
* Initializes the descriptor structure in SRAM from a pre-initialized
* configuration structure.
* This function initializes only the descriptor and not the channel.
*
* \param descriptor
* The descriptor structure instance declared by the user/component.
*
* \param config
* This is a configuration structure that has all initialization information for
* the descriptor.
*
* \return
* The status /ref cy_en_dma_status_t.
*
*******************************************************************************/
cy_en_dma_status_t Cy_DMA_Descriptor_Init(cy_stc_dma_descriptor_t * descriptor, const cy_stc_dma_descriptor_config_t * config)
{
cy_en_dma_status_t retVal = CY_DMA_BAD_PARAM;
if ((NULL != descriptor) && (NULL != config))
{
CY_ASSERT_L3(CY_DMA_IS_RETRIGGER_VALID(config->retrigger));
CY_ASSERT_L3(CY_DMA_IS_TRIG_TYPE_VALID(config->interruptType));
CY_ASSERT_L3(CY_DMA_IS_TRIG_TYPE_VALID(config->triggerOutType));
CY_ASSERT_L3(CY_DMA_IS_TRIG_TYPE_VALID(config->triggerInType));
CY_ASSERT_L3(CY_DMA_IS_XFER_SIZE_VALID(config->srcTransferSize));
CY_ASSERT_L3(CY_DMA_IS_XFER_SIZE_VALID(config->dstTransferSize));
CY_ASSERT_L3(CY_DMA_IS_CHANNEL_STATE_VALID(config->channelState));
CY_ASSERT_L3(CY_DMA_IS_DATA_SIZE_VALID(config->dataSize));
CY_ASSERT_L3(CY_DMA_IS_TYPE_VALID(config->descriptorType));
descriptor->ctl =
_VAL2FLD(CY_DMA_CTL_RETRIG, config->retrigger) |
_VAL2FLD(CY_DMA_CTL_INTR_TYPE, config->interruptType) |
_VAL2FLD(CY_DMA_CTL_TR_OUT_TYPE, config->triggerOutType) |
_VAL2FLD(CY_DMA_CTL_TR_IN_TYPE, config->triggerInType) |
_VAL2FLD(CY_DMA_CTL_SRC_SIZE, config->srcTransferSize) |
_VAL2FLD(CY_DMA_CTL_DST_SIZE, config->dstTransferSize) |
_VAL2FLD(CY_DMA_CTL_CH_DISABLE, config->channelState) |
_VAL2FLD(CY_DMA_CTL_DATA_SIZE, config->dataSize) |
_VAL2FLD(CY_DMA_CTL_TYPE, config->descriptorType);
descriptor->src = (uint32_t)config->srcAddress;
descriptor->dst = (uint32_t)config->dstAddress;
switch(config->descriptorType)
{
case CY_DMA_SINGLE_TRANSFER:
{
descriptor->xCtl = (uint32_t)config->nextDescriptor;
break;
}
case CY_DMA_1D_TRANSFER:
{
CY_ASSERT_L2(CY_DMA_IS_INCR_VALID(config->srcXincrement));
CY_ASSERT_L2(CY_DMA_IS_INCR_VALID(config->dstXincrement));
CY_ASSERT_L2(CY_DMA_IS_COUNT_VALID(config->xCount));
descriptor->xCtl =
_VAL2FLD(CY_DMA_CTL_SRC_INCR, config->srcXincrement) |
_VAL2FLD(CY_DMA_CTL_DST_INCR, config->dstXincrement) |
/* Convert the data count from the user's range (1-256) into the machine range (0-255). */
_VAL2FLD(CY_DMA_CTL_COUNT, config->xCount - 1UL);
descriptor->yCtl = (uint32_t)config->nextDescriptor;
break;
}
case CY_DMA_2D_TRANSFER:
{
CY_ASSERT_L2(CY_DMA_IS_INCR_VALID(config->srcXincrement));
CY_ASSERT_L2(CY_DMA_IS_INCR_VALID(config->dstXincrement));
CY_ASSERT_L2(CY_DMA_IS_COUNT_VALID(config->xCount));
CY_ASSERT_L2(CY_DMA_IS_INCR_VALID(config->srcYincrement));
CY_ASSERT_L2(CY_DMA_IS_INCR_VALID(config->dstYincrement));
CY_ASSERT_L2(CY_DMA_IS_COUNT_VALID(config->yCount));
descriptor->xCtl =
_VAL2FLD(CY_DMA_CTL_SRC_INCR, config->srcXincrement) |
_VAL2FLD(CY_DMA_CTL_DST_INCR, config->dstXincrement) |
/* Convert the data count from the user's range (1-256) into the machine range (0-255). */
_VAL2FLD(CY_DMA_CTL_COUNT, config->xCount - 1UL);
descriptor->yCtl =
_VAL2FLD(CY_DMA_CTL_SRC_INCR, config->srcYincrement) |
_VAL2FLD(CY_DMA_CTL_DST_INCR, config->dstYincrement) |
/* Convert the data count from the user's range (1-256) into the machine range (0-255). */
_VAL2FLD(CY_DMA_CTL_COUNT, config->yCount - 1UL);
descriptor->nextPtr = (uint32_t)config->nextDescriptor;
break;
}
default:
{
/* An unsupported type of a descriptor */
break;
}
}
retVal = CY_DMA_SUCCESS;
}
return retVal;
}
/*******************************************************************************
* Function Name: Cy_DMA_Descriptor_DeInit
****************************************************************************//**
*
* Clears the content of the specified descriptor.
*
* \param descriptor
* The descriptor structure instance declared by the user/component.
*
*******************************************************************************/
void Cy_DMA_Descriptor_DeInit(cy_stc_dma_descriptor_t * descriptor)
{
descriptor->ctl = 0UL;
descriptor->src = 0UL;
descriptor->dst = 0UL;
descriptor->xCtl = 0UL;
descriptor->yCtl = 0UL;
descriptor->nextPtr = 0UL;
}
/*******************************************************************************
* Function Name: Cy_DMA_Channel_Init
****************************************************************************//**
*
* Initializes the DMA channel with a descriptor and other parameters.
*
* \param base
* The pointer to the hardware DMA block.
*
* \param channel
* A channel number.
*
* \param channelConfig
* The structure that has the initialization information for the
* channel.
*
* \return
* The status /ref cy_en_dma_status_t.
*
*******************************************************************************/
cy_en_dma_status_t Cy_DMA_Channel_Init(DW_Type * base, uint32_t channel, cy_stc_dma_channel_config_t const * channelConfig)
{
cy_en_dma_status_t retVal = CY_DMA_BAD_PARAM;
if (((CY_DMA_IS_DW_CH_NR_VALID(base, channel)) && (NULL != channelConfig) && (NULL != channelConfig->descriptor)))
{
CY_ASSERT_L2(CY_DMA_IS_PRIORITY_VALID(channelConfig->priority));
/* Set the current descriptor */
base->CH_STRUCT[channel].CH_CURR_PTR = (uint32_t)channelConfig->descriptor;
/* Set the channel configuration */
base->CH_STRUCT[channel].CH_CTL = _BOOL2FLD(DW_CH_STRUCT_CH_CTL_PREEMPTABLE, channelConfig->preemptable) |
_VAL2FLD(DW_CH_STRUCT_CH_CTL_PRIO, channelConfig->priority) |
_BOOL2FLD(DW_CH_STRUCT_CH_CTL_ENABLED, channelConfig->enable) |
_BOOL2FLD(DW_CH_STRUCT_CH_CTL_B, channelConfig->bufferable);
retVal = CY_DMA_SUCCESS;
}
return (retVal);
}
/*******************************************************************************
* Function Name: Cy_DMA_Channel_DeInit
****************************************************************************//**
*
* Clears the content of registers corresponding to the channel.
*
* \param base
* The pointer to the hardware DMA block.
*
* \param channel
* A channel number.
*
*******************************************************************************/
void Cy_DMA_Channel_DeInit(DW_Type * base, uint32_t channel)
{
CY_ASSERT_L1(CY_DMA_IS_DW_CH_NR_VALID(base, channel));
base->CH_STRUCT[channel].CH_CTL = 0UL;
base->CH_STRUCT[channel].CH_IDX = 0UL;
base->CH_STRUCT[channel].CH_CURR_PTR = 0UL;
base->CH_STRUCT[channel].INTR_MASK = 0UL;
}
/*******************************************************************************
* Function Name: Cy_DMA_Descriptor_SetNextDescriptor
****************************************************************************//**
*
* Sets a Next Descriptor parameter for the specified descriptor.
*
* Based on the descriptor type, the offset of the address for the next descriptor may
* vary. For the single-transfer descriptor type, this register is at offset 0x0c.
* For the 1D-transfer descriptor type, this register is at offset 0x10.
* For the 2D-transfer descriptor type, this register is at offset 0x14.
*
* \param descriptor
* The descriptor structure instance declared by the user/component.
*
* \param nextDescriptor
* The pointer to the next descriptor.
*
*******************************************************************************/
void Cy_DMA_Descriptor_SetNextDescriptor(cy_stc_dma_descriptor_t * descriptor, cy_stc_dma_descriptor_t const * nextDescriptor)
{
CY_ASSERT_L1(NULL != descriptor);
switch((cy_en_dma_descriptor_type_t) _FLD2VAL(CY_DMA_CTL_TYPE, descriptor->ctl))
{
case CY_DMA_SINGLE_TRANSFER:
descriptor->xCtl = (uint32_t)nextDescriptor;
break;
case CY_DMA_1D_TRANSFER:
descriptor->yCtl = (uint32_t)nextDescriptor;
break;
case CY_DMA_2D_TRANSFER:
descriptor->nextPtr = (uint32_t)nextDescriptor;
break;
default:
/* Unsupported type of descriptor */
break;
}
}
/*******************************************************************************
* Function Name: Cy_DMA_Descriptor_GetNextDescriptor
****************************************************************************//**
*
* Returns a next descriptor address of the specified descriptor.
*
* Based on the descriptor type, the offset of the address for the next descriptor may
* vary. For a single-transfer descriptor type, this register is at offset 0x0c.
* For the 1D-transfer descriptor type, this register is at offset 0x10.
* For the 2D-transfer descriptor type, this register is at offset 0x14.
*
* \param descriptor
* The descriptor structure instance declared by the user/component.
*
* \return
* The pointer to the next descriptor.
*
*******************************************************************************/
cy_stc_dma_descriptor_t * Cy_DMA_Descriptor_GetNextDescriptor(cy_stc_dma_descriptor_t const * descriptor)
{
cy_stc_dma_descriptor_t * retVal = NULL;
CY_ASSERT_L1(NULL != descriptor);
switch((cy_en_dma_descriptor_type_t) _FLD2VAL(CY_DMA_CTL_TYPE, descriptor->ctl))
{
case CY_DMA_SINGLE_TRANSFER:
retVal = (cy_stc_dma_descriptor_t*) descriptor->xCtl;
break;
case CY_DMA_1D_TRANSFER:
retVal = (cy_stc_dma_descriptor_t*) descriptor->yCtl;
break;
case CY_DMA_2D_TRANSFER:
retVal = (cy_stc_dma_descriptor_t*) descriptor->nextPtr;
break;
default:
/* An unsupported type of the descriptor */
break;
}
return (retVal);
}
/*******************************************************************************
* Function Name: Cy_DMA_Descriptor_SetDescriptorType
****************************************************************************//**
*
* Sets the descriptor's type for the specified descriptor.
* Moves the next descriptor register value into the proper place in accordance
* to the actual descriptor type.
* During the descriptor's type changing, the Xloop and Yloop settings, such as
* data count and source/destination increment (i.e. the content of the
* xCtl and yCtl descriptor registers) might be lost (overriden by the
* next descriptor value) because of the different descriptor registers structures
* for different descriptor types. Set up carefully the Xloop
* (and Yloop, if used) data count and source/destination increment if the
* descriptor type is changed from a simpler to a more complicated type
* ("single transfer" -> "1D", "1D" -> "2D", etc.).
*
* \param descriptor
* The descriptor structure instance declared by the user/component.
*
* \param descriptorType
* The descriptor type \ref cy_en_dma_descriptor_type_t.
*
*******************************************************************************/
void Cy_DMA_Descriptor_SetDescriptorType(cy_stc_dma_descriptor_t * descriptor, cy_en_dma_descriptor_type_t descriptorType)
{
CY_ASSERT_L1(NULL != descriptor);
CY_ASSERT_L3(CY_DMA_IS_TYPE_VALID(descriptorType));
if (descriptorType != Cy_DMA_Descriptor_GetDescriptorType(descriptor)) /* Don't perform if the type is not changed */
{
/* Store the current nextDescriptor pointer. */
cy_stc_dma_descriptor_t * locNextDescriptor = Cy_DMA_Descriptor_GetNextDescriptor(descriptor);
/* Change the descriptor type. */
descriptor->ctl = _CLR_SET_FLD32U(descriptor->ctl, CY_DMA_CTL_TYPE, descriptorType);
/* Restore the nextDescriptor pointer into the proper place. */
Cy_DMA_Descriptor_SetNextDescriptor(descriptor, locNextDescriptor);
}
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,225 @@
/***************************************************************************//**
* \file cy_efuse.c
* \version 1.0
*
* \brief
* Provides API implementation of the eFuse driver.
*
********************************************************************************
* \copyright
* Copyright 2017-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "cy_efuse.h"
#include "ipc/cy_ipc_drv.h"
/** \cond INTERNAL */
#define CY_EFUSE_OPCODE_SUCCESS (0xA0000000UL) /**< The command completed with no errors */
#define CY_EFUSE_OPCODE_STS_Msk (0xF0000000UL) /**< The status mask of the SROM API return value */
#define CY_EFUSE_OPCODE_INV_PROT (0xF0000001UL) /**< The API is not available in the current protection state */
#define CY_EFUSE_OPCODE_INV_ADDR (0xF0000002UL) /**< An attempt to read byte from the out-of-bond or protected eFuse region */
#define CY_EFUSE_OPCODE_READ_FUSE_BYTE (0x03000000UL) /**< The SROM API opcode for Read fuse byte operation */
#define CY_EFUSE_OPCODE_OFFSET_Pos (8UL) /**< A fuse byte offset position in an opcode */
#define CY_EFUSE_OPCODE_DATA_Msk (0xFFUL) /**< The mask for extracting data from the SROM API return value */
#define CY_EFUSE_IPC_STRUCT (Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL)) /**< IPC structure to be used */
#define CY_EFUSE_IPC_NOTIFY_STRUCT0 (0x1UL << CY_IPC_INTR_SYSCALL1) /**< IPC notify bit for IPC_STRUCT0 (dedicated to System Call) */
/** \endcond */
static volatile uint32_t opcode;
static cy_en_efuse_status_t ProcessOpcode(void);
/*******************************************************************************
* Function Name: Cy_EFUSE_GetEfuseBit
****************************************************************************//**
*
* Reports the current state of a given eFuse bit-number. Consult the device TRM
* to determine the target fuse bit number.
*
* \note An attempt to read an eFuse data from a protected memory region
* will generate a HardFault.
*
* \param bitNum
* The number of the bit to read. The valid range of the bit number is
* from 0 to EFUSE_EFUSE_NR * 32 * 8 - 1 where:
* - EFUSE_EFUSE_NR is number of efuse macros in the selected device series,
* - 32 is a number of fuse bytes in one efuse macro,
* - 8 is a number of fuse bits in the byte.
*
* The EFUSE_EFUSE_NR macro is defined in the series-specific header file, e.g
* \e \<PDL_DIR\>/devices/psoc6/psoc63/include/psoc63_config.\e h
*
* \param bitVal
* The pointer to the location to store the bit value.
*
* \return
* \ref cy_en_efuse_status_t
*
* \funcusage
* The example below shows how to read device life-cycle register bits in
* PSoC 6:
* \snippet eFuse_v1_0_sut_00.cydsn/main_cm0p.c SNIPPET_EFUSE_READ_BIT
*
*******************************************************************************/
cy_en_efuse_status_t Cy_EFUSE_GetEfuseBit(uint32_t bitNum, bool *bitVal)
{
cy_en_efuse_status_t result = CY_EFUSE_BAD_PARAM;
if (bitVal != NULL)
{
uint32_t offset = bitNum / CY_EFUSE_BITS_PER_BYTE;
uint8_t byteVal;
*bitVal = false;
/* Read the eFuse byte */
result = Cy_EFUSE_GetEfuseByte(offset, &byteVal);
if (result == CY_EFUSE_SUCCESS)
{
uint32_t bitPos = bitNum % CY_EFUSE_BITS_PER_BYTE;
/* Extract the bit from the byte */
*bitVal = (((byteVal >> bitPos) & 0x01U) != 0U);
}
}
return (result);
}
/*******************************************************************************
* Function Name: Cy_EFUSE_GetEfuseByte
****************************************************************************//**
*
* Reports the current state of the eFuse byte.
* If the offset parameter is beyond the available quantities,
* zeroes will be stored to the byteVal parameter. Consult the device TRM
* to determine the target fuse byte offset.
*
* \note An attempt to read an eFuse data from a protected memory region
* will generate a HardFault.
*
* \param offset
* The offset of the byte to read. The valid range of the byte offset is
* from 0 to EFUSE_EFUSE_NR * 32 - 1 where:
* - EFUSE_EFUSE_NR is a number of efuse macros in the selected device series,
* - 32 is a number of fuse bytes in one efuse macro.
*
* The EFUSE_EFUSE_NR macro is defined in the series-specific header file, e.g
* \e \<PDL_DIR\>/devices/psoc6/psoc63/include/psoc63_config.\e h
*
* \param byteVal
* The pointer to the location to store eFuse data.
*
* \return
* \ref cy_en_efuse_status_t
*
* \funcusage
* The example below shows how to read a device life-cycle stage register in
* PSoC 6:
* \snippet eFuse_v1_0_sut_00.cydsn/main_cm0p.c SNIPPET_EFUSE_READ_LIFECYCLE
*
*******************************************************************************/
cy_en_efuse_status_t Cy_EFUSE_GetEfuseByte(uint32_t offset, uint8_t *byteVal)
{
cy_en_efuse_status_t result = CY_EFUSE_BAD_PARAM;
if (byteVal != NULL)
{
/* Prepare opcode before calling the SROM API */
opcode = CY_EFUSE_OPCODE_READ_FUSE_BYTE | (offset << CY_EFUSE_OPCODE_OFFSET_Pos);
/* Send the IPC message */
if (Cy_IPC_Drv_SendMsgPtr(CY_EFUSE_IPC_STRUCT, CY_EFUSE_IPC_NOTIFY_STRUCT0, (void*)&opcode) == CY_IPC_DRV_SUCCESS)
{
/* Wait until the IPC structure is locked */
while(Cy_IPC_Drv_IsLockAcquired(CY_EFUSE_IPC_STRUCT) != false)
{
}
/* The result of the SROM API call is returned to the opcode variable */
if ((opcode & CY_EFUSE_OPCODE_STS_Msk) == CY_EFUSE_OPCODE_SUCCESS)
{
*byteVal = (uint8_t)(opcode & CY_EFUSE_OPCODE_DATA_Msk);
result = CY_EFUSE_SUCCESS;
}
else
{
result = ProcessOpcode();
*byteVal = 0U;
}
}
else
{
result = CY_EFUSE_IPC_BUSY;
}
}
return (result);
}
/*******************************************************************************
* Function Name: Cy_EFUSE_GetExternalStatus
****************************************************************************//**
*
* This function handles the case where a module such as a security image captures
* a system call from this driver and reports its own status or error code,
* for example, protection violation. In that case, a function from this
* driver returns an unknown error (see \ref cy_en_efuse_status_t). After receipt
* of an unknown error, the user may call this function to get the status
* of the capturing module.
*
* The user is responsible for parsing the content of the returned value
* and casting it to the appropriate enumeration.
*
* \return
* The error code of the previous efuse operation.
*
*******************************************************************************/
uint32_t Cy_EFUSE_GetExternalStatus(void)
{
return (opcode);
}
/*******************************************************************************
* Function Name: ProcessOpcode
****************************************************************************//**
*
* Converts System Call returns to the eFuse driver return defines. If
* an unknown error was returned, the error code can be accessed via the
* Cy_EFUSE_GetExternalStatus() function.
*
* \param opcode The value returned by a System Call.
*
* \return
* \ref cy_en_efuse_status_t
*
*******************************************************************************/
static cy_en_efuse_status_t ProcessOpcode(void)
{
cy_en_efuse_status_t result;
switch(opcode)
{
case CY_EFUSE_OPCODE_INV_PROT :
{
result = CY_EFUSE_INVALID_PROTECTION;
break;
}
case CY_EFUSE_OPCODE_INV_ADDR :
{
result = CY_EFUSE_INVALID_FUSE_ADDR;
break;
}
default :
{
result = CY_EFUSE_ERR_UNC;
break;
}
}
return (result);
}
/* [] END OF FILE */

View File

@ -0,0 +1,178 @@
/***************************************************************************//**
* \file cy_efuse.h
* \version 1.0
*
* Provides the API declarations of the eFuse driver.
*
********************************************************************************
* \copyright
* Copyright 2017-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#if !defined(CY_EFUSE_H)
#define CY_EFUSE_H
/**
* \defgroup group_efuse Electronic Fuses (eFuse)
* \{
*
* Electronic Fuses (eFuses) - non-volatile memory whose
* each bit is one-time programmable (OTP). One eFuse macro consists of
* 256 bits (32 * 8). The PSoC devices have up to 16 eFuse macros; consult the
* device-specific datasheet to determine how many macros for a particular device.
* These are implemented as a regular Advanced High-performance Bus (AHB)
* peripheral with the following characteristics:
* - eFuses are used to control the device life-cycle stage (NORMAL, SECURE,
* and SECURE_WITH_DEBUG) and the protection settings;
* - eFuse memory can be programmed (eFuse bit value changed from '0' to '1')
* only once; if an eFuse bit is blown, it cannot be cleared again;
* - programming fuses requires the associated I/O supply to be at a specific
* level: the VDDIO0 (or VDDIO if only one VDDIO is present in the package)
* supply of the device should be set to 2.5 V (&plusmn;5%);
* - fuses are programmed via the PSoC Programmer tool that parses the hex file
* and extracts the necessary information; the fuse data must be located at the
* dedicated section in the hex file. For more details see
* [PSoC 6 Programming Specifications](http://www.cypress.com/documentation/programming-specifications/psoc-6-programming-specifications)
*
* \section group_efuse_configuration Configuration Considerations
*
* Efuse memory can have different organization depending on the selected device.
* Consult the device TRM to determine the efuse memory organization and
* registers bitmap on the selected device.
*
* To read fuse data use the driver [functions] (\ref group_efuse_functions).
*
* To blow fuses, define a data structure of \ref cy_stc_efuse_data_t type in the
* firmware. The structure must be placed in the special memory section, for
* this use a compiler attribute.
* Each byte in the structure corresponds to the one fuse bit in the
* device. It allows the PSoC Programmer tool to distinguish bytes that are
* being set from bytes we don't care about or with unknown values. Fill the
* structure with the following values:
* - 0x00 - Not blown;
* - 0x01 - Blown;
* - 0xFF - Ignore.
*
* After the structure is defined and the values are set, build the project and
* download the firmware. To blow fuses, the firmware must be downloaded by the
* PSoC Programmer tool. Before you download firmware, ensure that the
* conditions from the PSoC 6 Programming Specification are met.
*
* The code below shows an example of the efuse data structure
* definition to blow SECURE bit of the life-cycle stage register.
* The bits to blow are set to the EFUSE_STATE_SET value.
* \snippet eFuse_v1_0_sut_00.cydsn/main_cm0p.c SNIPPET_EFUSE_DATA_STC
*
* \section group_efuse_more_information More Information
*
* Refer to the technical reference manual (TRM) and the device datasheet.
*
* \section group_efuse_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>2.3</td>
* <td>R</td>
* <td>The character sequence // shall not be used within a comment.</td>
* <td>The comments provide a useful WEB link to the documentation.</td>
* </tr>
* <tr>
* <td>11.5</td>
* <td>R</td>
* <td>Dangerous pointer cast results in loss of volatile qualification.</td>
* <td>The removal of the volatile qualification inside the function has no
* side effects.</td>
* </tr>
* </table>
*
* \section group_efuse_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_efuse_macros Macros
* \defgroup group_efuse_functions Functions
* \defgroup group_efuse_data_structures Data Structures
* \defgroup group_efuse_enumerated_types Enumerated Types
*/
#include "cy_device_headers.h"
#include "syslib/cy_syslib.h"
/***************************************
* Macro Definitions
***************************************/
/**
* \addtogroup group_efuse_macros
* \{
*/
/** The driver major version */
#define CY_EFUSE_DRV_VERSION_MAJOR 1
/** The driver minor version */
#define CY_EFUSE_DRV_VERSION_MINOR 0
/** The eFuse driver identifier */
#define CY_EFUSE_ID (CY_PDL_DRV_ID(0x1AUL))
/** The number of bits in the byte */
#define CY_EFUSE_BITS_PER_BYTE (8UL)
/** \} group_efuse_macros */
/***************************************
* Enumerated Types
***************************************/
/**
* \addtogroup group_efuse_enumerated_types
* \{
*/
/** This enum has the return values of the eFuse driver */
typedef enum
{
CY_EFUSE_SUCCESS = 0x00UL, /**< Success */
CY_EFUSE_INVALID_PROTECTION = CY_EFUSE_ID | CY_PDL_STATUS_ERROR | 0x01UL, /**< Invalid access in the current protection state */
CY_EFUSE_INVALID_FUSE_ADDR = CY_EFUSE_ID | CY_PDL_STATUS_ERROR | 0x02UL, /**< Invalid eFuse address */
CY_EFUSE_BAD_PARAM = CY_EFUSE_ID | CY_PDL_STATUS_ERROR | 0x03UL, /**< One or more invalid parameters */
CY_EFUSE_IPC_BUSY = CY_EFUSE_ID | CY_PDL_STATUS_ERROR | 0x04UL, /**< The IPC structure is already locked by another process */
CY_EFUSE_ERR_UNC = CY_EFUSE_ID | CY_PDL_STATUS_ERROR | 0xFFUL /**< Unknown error code. See Cy_EFUSE_GetExternalStatus() */
} cy_en_efuse_status_t;
/** \} group_efuse_data_structure */
#if defined(__cplusplus)
extern "C" {
#endif
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_efuse_functions
* \{
*/
cy_en_efuse_status_t Cy_EFUSE_GetEfuseBit(uint32_t bitNum, bool *bitVal);
cy_en_efuse_status_t Cy_EFUSE_GetEfuseByte(uint32_t offset, uint8_t *byteVal);
uint32_t Cy_EFUSE_GetExternalStatus(void);
/** \} group_efuse_functions */
#if defined(__cplusplus)
}
#endif
#endif /* #if !defined(CY_EFUSE_H) */
/** \} group_efuse */
/* [] END OF FILE */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,405 @@
/***************************************************************************//**
* \file cy_flash.h
* \version 3.0
*
* Provides the API declarations of the Flash driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#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.
*
* A Read while Write violation occurs when a flash Read operation is initiated
* in the same or neighboring flash sector where the flash Write, Erase, or
* Program operation is working. This violation may cause a HardFault exception.
* To avoid the Read while Write violation, the user must carefully split the
* Read and Write operation on flash sectors which are not neighboring,
* considering both cores in the multi-processor device. The flash is divided
* into four equal sectors. You may edit the linker script to place the code
* into neighboring sectors. For example, use sectors number 0 and 1 for code
* and sectors 2 and 3 for data storage.
*
* \section group_flash_configuration Configuration Considerations
*
* \subsection group_flash_config_intro Introduction:
* The PSoC 6 MCU user-programmable Flash consists of:
* - Up to four User Flash sectors (0 through 3) - 256KB each.
* - EEPROM emulation sector - 32KB.
*
* Write operations are performed on a per-sector basis and may be done as
* Blocking or Partially Blocking, defined as follows:
*
* \subsection group_flash_config_blocking Blocking:
* In this case, the entire Flash block is not available for the duration of the
* Write (up to 20 milliseconds). Therefore, no Flash accesses
* (from any Bus Master) can occur during that time. CPU execution can be
* performed from SRAM. All pre-fetching must be disabled. Application code
* execution from Flash is blocked for the Flash Write duration for both cores.
*
* \subsection group_flash_config_block_const Constraints for Blocking Flash operations:
* -# During write to flash, the device should not be reset (including XRES pin,
* software reset, and watchdog), or unexpected changes may be made to portions
* of the flash.
* -# The low-voltage detect circuits should be configured to generate an
* interrupt instead of a reset.
* -# Flash write operation is allowed only in one of the following CM4 states:
* -# CM4 is Active and initialized:<br>
* call \ref Cy_SysEnableCM4 "Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR)".
* <b>Note:</b> If desired user may put CM4 core in Deep Sleep any time
* after calling Cy_SysEnableCM4().
* -# CM4 is Off:<br>
* call Cy_SysDisableCM4(). <b>Note:</b> In this state Debug mode is not
* supported.
* .
* -# Flash write cannot be performed in ULP (core voltage 0.9V) mode.
* -# Interrupts must be enabled on both active cores. Do not enter a critical
* section during flash operation.
* -# User must guarantee that system pipe interrupts (IPC interrupts 3 and 4)
* have the highest priority, or at least that pipe interrupts are not
* interrupted or in a pending state for more than 700 &micro;s.
* -# User must guarantee that during flash write operation no flash read
* operations are performed by bus masters other than CM0+ and CM4 (DMA and
* Crypto).
* -# If you do not use the default startup, ensure that firmware calls the
* following functions before any flash write/erase operations:
* \snippet Flash_sut_01.cydsn/main_cm0p.c Flash Initialization
*
* \subsection group_flash_config_rww Partially Blocking:
* This method has a much shorter time window during which Flash accesses are not
* allowed. Application code execution from Flash is blocked for only a part of
* Flash Write duration, for both cores. Blocking duration depends upon the API
* sequence used.
*
* For API sequence Cy_Flash_StartErase() + Cy_Flash_StartProgram() there are
* four block-out regions during which the read is blocked using the software
* driver (PDL). See <b>Figure 1</b>.
*
* <center>
* <table class="doxtable">
* <caption>Table 1 - Block-out periods</caption>
* <tr>
* <th>Block-out</th>
* <th>Phase</th>
* <th>Duration</th>
* </tr>
* <tr>
* <td>A</td>
* <td>The beginning of the Erase operation</td>
* <td>2ms + 9500 SlowClk cycles</td>
* </tr>
* <tr>
* <td>B</td>
* <td>The end of the Erase operation</td>
* <td>0.13ms + 1000 SlowClk cycles</td>
* </tr>
* <tr>
* <td>C</td>
* <td>The beginning of the Program operation</td>
* <td>0.8ms + 6000 SlowClk cycles</td>
* </tr>
* <tr>
* <td>D</td>
* <td>The end of the Program operation</td>
* <td>0.13ms + 1000 SlowClk cycles</td>
* </tr>
* </table>
* </center>
*
* This allows both cores to execute an application for about 80% of Flash Write
* operation - see <b>Figure 1</b>.
* This capability is important for communication protocols that rely on fast
* response.
*
* \image html flash-rww-diagram.png "Figure 1 - Blocking Intervals in Flash Write operation" width=70%
*
* For the Cy_Flash_StartWrite() function, the block-out period is different for
* the two cores. The core that initiates Cy_Flash_StartWrite() is blocked for
* two periods:
* - From start of Erase operation (start of A on Figure 1) till the start of
* Program operation (end of C on Figure 1).
* - During D period on <b>Figure 1</b>.
*
* The core that performs read/execute is blocked identically to the
* Cy_Flash_StartErase() + Cy_Flash_StartProgram() sequence - see <b>Figure 1</b>.
*
* This allows the core that initiates Cy_Flash_StartWrite() to execute an
* application for about 20% of the Flash Write operation. The other core executes
* the application for about 80% of the Flash Write operation.
*
* Some constraints must be planned for in the Partially Blocking mode which are
* described in detail below.
*
* \subsection group_flash_config_rww_const Constraints for Partially Blocking Flash operations:
* -# During write to flash, the device should not be reset (including XRES pin,
* software reset, and watchdog) or unexpected changes may be made to portions
* of the flash.
* -# The low-voltage detect circuits should be configured to generate an
* interrupt instead of a reset.
* -# During write to flash, application code should not change the clock
* settings. Use Cy_Flash_IsOperationComplete() to ensure flash write
* operation is finished.
* -# Flash write operation is allowed only in one of the following CM4 states:
* -# CM4 is Active and initialized:<br>
* call \ref Cy_SysEnableCM4 "Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR)".
* <b>Note:</b> If desired user may put CM4 core in Deep Sleep any time
* after calling Cy_SysEnableCM4().
* -# CM4 is Off:<br>
* call Cy_SysDisableCM4(). <b>Note:</b> In this state Debug mode is not
* supported.
* .
* -# Use the following rules for split by sectors. (In this context, read means
* read of any bus master: CM0+, CM4, DMA, Crypto, etc.)
* -# Do not write to and read/execute from the same flash sector at the same
* time. This is true for all sectors.
* -# Writing rules in User Flash:
* -# Any bus master can read/execute from UFLASH S0 and/or S1, during
* flash write to UFLASH S2 or S3.
* -# Any bus master can read/execute from UFLASH S2 and/or S3, during
* flash write to UFLASH S0 or S1.
*
* <b>Suggestion:</b> in case of bootloading, it is recommended to place
* code for CM4 in either S0 or S1. CM0+ code resides in S0. Write data
* to S2 and S3 sections.
* .
* -# Flash write cannot be performed in ULP mode (core voltage 0.9V).
* -# Interrupts must be enabled on both active cores. Do not enter a critical
* section during flash operation.
* -# User must guarantee that system pipe interrupts (IPC interrupts 3 and 4)
* have the highest priority, or at least that pipe interrupts are not
* interrupted or in a pending state for more than 700 &micro;s.
* -# User must guarantee that during flash write operation no flash read
* operations are performed by bus masters other than CM0+ and CM4
* (DMA and Crypto).
* -# If you do not use the default startup, ensure that firmware calls the
* following functions before any flash write/erase operations:
* \snippet Flash_sut_01.cydsn/main_cm0p.c Flash Initialization
*
* \subsection group_flash_config_emeeprom EEPROM section use:
* If you plan to use "cy_em_eeprom" section for different purposes for both of
* device cores or use <b>Em_EEPROM Middleware</b> together with flash driver
* write operations you must modify the linker scripts.<br>
* For more information, refer to the <b>Middleware/Cypress Em_EEPROM Middleware
* Library</b> section of the PDL documentation.
*
* \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
*
* <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>11.4</td>
* <td>A</td>
* <td>Casting to different object pointer type.</td>
* <td>The cast of the uint32_t pointer to pipe message structure pointer
* is used to get transmitted data via the \ref group_ipc channel.
* We cast only one pointer, so there is no way to avoid this cast.</td>
* </tr>
* <tr>
* <td>11.5</td>
* <td>R</td>
* <td>Not performed, the cast that removes any const or volatile qualification from the type addressed by a pointer.</td>
* <td>The removal of the volatile qualification inside the function has no side effects.</td>
* </tr>
* </table>
*
* \section group_flash_changelog Changelog
*
* <table class="doxtable">
* <tr><th>Version</th><th style="width: 52%;">Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>3.0</td>
* <td>New function - Cy_Flash_ProgramRow();<br>
* Updated Cy_Flash_RowChecksum(): changed input parameter to take the
* <b>row address</b> (rowAddr) instead of the <b>row number</b>
* (rowNum);<br>
* Renamed macro for disabling RWW support in driver to
* <b>CY_FLASH_RWW_DRV_SUPPORT_DISABLED</b>.<br>
* Updated \ref group_flash_configuration documentation section with
* flash usage constraints.</td>
* <td>Improvements made based on usability feedback to use a common
* interface</td>
* </tr>
* <tr>
* <td rowspan="3">2.0</td>
* <td>Added non-blocking erase function - Cy_Flash_StartErase().
* Removed the clear cache function call.</td>
* <td>The clear cache operation is removed from the blocking Write/Erase
* function because in this case it is performed by the hardware.
* Otherwise it is documented that it is the user's responsibility to
* clear the cache after executing the non-blocking Write/Erase flash
* operation.</td>
* </tr>
* <tr>
* <td>Added new Cy_Flash_IsOperationComplete() function to check completeness.
* Obsoleted Cy_Flash_IsWriteComplete(), Cy_Flash_IsProgramComplete(),
* and Cy_Flash_IsEraseComplete() functions.<br>
* Added Cy_Flash_GetExternalStatus() function to get unparsed status where
* flash driver will be used in security applications with other modules
* as SecureImage.<br>
* Added Cy_Flash_Init() function to initialize all needed prerequisites
* for Erase/Write operations.</td>
* <td>Updated driver design to improve user experience.</td>
* </tr>
* <tr>
* <td>Updated driver implementation to remove MISRA rules deviations.</td>
* <td>Driver implementation quality improvement.</td>
* </tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_flash_macros Macros
* \{
* \defgroup group_flash_general_macros Flash general parameters
* Provides general information about flash
* \}
* \defgroup group_flash_functions Functions
* \defgroup group_flash_enumerated_types Enumerated Types
*/
#include <cy_device_headers.h>
#include "syslib/cy_syslib.h"
#if defined(__cplusplus)
extern "C" {
#endif
/***************************************
* Macro definitions
***************************************/
/**
* \addtogroup group_flash_macros
* \{
*/
/** Driver major version */
#define CY_FLASH_DRV_VERSION_MAJOR 3
/** Driver minor version */
#define CY_FLASH_DRV_VERSION_MINOR 0
#define CY_FLASH_ID (CY_PDL_DRV_ID(0x14UL)) /**< 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 */
/** \} group_flash_macros */
/**
* \addtogroup group_flash_general_macros
* \{
*/
/** 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))
/** \} group_flash_general_macros */
/**
* \addtogroup group_flash_enumerated_types
* \{
*/
/** This enum has the return values of the Flash driver */
typedef enum cy_en_flashdrv_status
{
CY_FLASH_DRV_SUCCESS = 0x00UL, /**< Success */
CY_FLASH_DRV_INV_PROT = ( CY_FLASH_ID_ERROR + 0x0UL), /**< Invalid device protection state */
CY_FLASH_DRV_INVALID_FM_PL = ( CY_FLASH_ID_ERROR + 0x1UL), /**< Invalid flash page latch address */
CY_FLASH_DRV_INVALID_FLASH_ADDR = ( CY_FLASH_ID_ERROR + 0x2UL), /**< Invalid flash address */
CY_FLASH_DRV_ROW_PROTECTED = ( CY_FLASH_ID_ERROR + 0x3UL), /**< Row is write protected */
CY_FLASH_DRV_IPC_BUSY = ( CY_FLASH_ID_ERROR + 0x5UL), /**< IPC structure is already locked by another process */
CY_FLASH_DRV_INVALID_INPUT_PARAMETERS = ( CY_FLASH_ID_ERROR + 0x6UL), /**< Input parameters passed to Flash API are not valid */
CY_FLASH_DRV_PL_ROW_COMP_FA = ( CY_FLASH_ID_ERROR + 0x22UL), /**< Comparison between Page Latches and FM row failed */
CY_FLASH_DRV_ERR_UNC = ( CY_FLASH_ID_ERROR + 0xFFUL), /**< Unknown error code. See \ref Cy_Flash_GetExternalStatus() */
CY_FLASH_DRV_PROGRESS_NO_ERROR = ( CY_FLASH_ID_INFO + 0x0UL), /**< Command in progress; no error */
CY_FLASH_DRV_OPERATION_STARTED = ( CY_FLASH_ID_INFO + 0x1UL), /**< Flash operation is successfully initiated */
CY_FLASH_DRV_OPCODE_BUSY = ( CY_FLASH_ID_INFO + 0x2UL) /**< Flash is under operation */
} cy_en_flashdrv_status_t;
/** \} group_flash_enumerated_types */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_flash_functions
* \{
*/
void Cy_Flash_Init(void);
cy_en_flashdrv_status_t Cy_Flash_EraseRow(uint32_t rowAddr);
cy_en_flashdrv_status_t Cy_Flash_ProgramRow(uint32_t rowAddr, const uint32_t* data);
cy_en_flashdrv_status_t Cy_Flash_WriteRow(uint32_t rowAddr, const uint32_t* data);
cy_en_flashdrv_status_t Cy_Flash_StartWrite(uint32_t rowAddr, const uint32_t* data);
cy_en_flashdrv_status_t Cy_Flash_StartProgram(uint32_t rowAddr, const uint32_t* data);
cy_en_flashdrv_status_t Cy_Flash_StartErase(uint32_t rowAddr);
cy_en_flashdrv_status_t Cy_Flash_IsOperationComplete(void);
cy_en_flashdrv_status_t Cy_Flash_RowChecksum(uint32_t rowAddr, uint32_t* checksumPtr);
cy_en_flashdrv_status_t Cy_Flash_CalculateHash(const uint32_t* data, uint32_t numberOfBytes, uint32_t* hashPtr);
uint32_t Cy_Flash_GetExternalStatus(void);
/** \} group_flash_functions */
/** \cond INTERNAL */
/* Macros to backward compatibility */
#define Cy_Flash_IsWriteComplete(...) Cy_Flash_IsOperationComplete()
#define Cy_Flash_IsProgramComplete(...) Cy_Flash_IsOperationComplete()
#define Cy_Flash_IsEraseComplete(...) Cy_Flash_IsOperationComplete()
/** \endcond */
#if defined(__cplusplus)
}
#endif
#endif /* #if !defined(CY_FLASH_H) */
/** \} group_flash */
/* [] END OF FILE */

View File

@ -0,0 +1,262 @@
/***************************************************************************//**
* \file cy_gpio.c
* \version 1.10.1
*
* \brief
* Provides an API implementation of the GPIO driver
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "cy_gpio.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_GPIO_Pin_Init
****************************************************************************//**
*
* \brief Initializes all pin configuration settings for the specified 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
* Initialization status
*
* \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.
*
* \funcusage
* \snippet gpio/gpio_v1_10_sut_01.cydsn/main_cm4.c snippet_Cy_GPIO_Pin_Init
*
*******************************************************************************/
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_ASSERT_L2(CY_GPIO_IS_PIN_VALID(pinNum));
CY_ASSERT_L2(CY_GPIO_IS_VALUE_VALID(config->outVal));
CY_ASSERT_L2(CY_GPIO_IS_DM_VALID(config->driveMode));
CY_ASSERT_L2(CY_GPIO_IS_HSIOM_VALID(config->hsiom));
CY_ASSERT_L2(CY_GPIO_IS_INT_EDGE_VALID(config->intEdge));
CY_ASSERT_L2(CY_GPIO_IS_VALUE_VALID(config->intMask));
CY_ASSERT_L2(CY_GPIO_IS_VALUE_VALID(config->vtrip));
CY_ASSERT_L2(CY_GPIO_IS_VALUE_VALID(config->slewRate));
CY_ASSERT_L2(CY_GPIO_IS_DRIVE_SEL_VALID(config->driveSel));
CY_ASSERT_L2(CY_GPIO_IS_VALUE_VALID(config->vregEn));
CY_ASSERT_L2(CY_GPIO_IS_VALUE_VALID(config->ibufMode));
CY_ASSERT_L2(CY_GPIO_IS_VALUE_VALID(config->vtripSel));
CY_ASSERT_L2(CY_GPIO_IS_VREF_SEL_VALID(config->vrefSel));
CY_ASSERT_L2(CY_GPIO_IS_VOH_SEL_VALID(config->vohSel));
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 << ((uint32_t)(pinNum << 1u) + 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) << ((uint32_t)(pinNum << 1u) + 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.
*
* The configuration structure used in this function has a 1:1 mapping to the
* GPIO and HSIOM registers. Refer to the device Technical Reference Manual (TRM)
* for the register details on how to populate them.
*
* \param base
* Pointer to the pin's port register base address
*
* \param config
* Pointer to the pin config structure base address
*
* \return
* Initialization status
*
* \note
* If using the PSoC Creator IDE, there is no need to initialize the pins when
* using the GPIO component on the schematic. Ports are configured in
* Cy_SystemInit() before main() entry.
*
* \funcusage
* \snippet gpio/gpio_v1_10_sut_01.cydsn/main_cm4.c snippet_Cy_GPIO_Port_Init
*
*******************************************************************************/
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))
{
CY_ASSERT_L2(CY_GPIO_IS_PIN_BIT_VALID(config->out));
CY_ASSERT_L2(CY_GPIO_IS_PIN_BIT_VALID(config->cfgIn));
CY_ASSERT_L2(CY_GPIO_IS_INTR_CFG_VALID(config->intrCfg));
CY_ASSERT_L2(CY_GPIO_IS_INTR_MASK_VALID(config->intrMask));
CY_ASSERT_L2(CY_GPIO_IS_SEL_ACT_VALID(config->sel0Active));
CY_ASSERT_L2(CY_GPIO_IS_SEL_ACT_VALID(config->sel1Active));
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);
}
/*******************************************************************************
* Function Name: Cy_GPIO_Pin_FastInit
****************************************************************************//**
*
* \brief Initialize the most common configuration settings for all pin types.
*
* These include, drive mode, initial output value, and HSIOM connection.
*
* \param base
* Pointer to the pin's port register base address
*
* \param pinNum
* Position of the pin bit-field within the port register
*
* \param driveMode
* Pin drive mode. Options are detailed in \ref group_gpio_driveModes macros
*
* \param outVal
* Logic state of the output buffer driven to the pin (1 or 0)
*
* \param hsiom
* HSIOM input selection
*
* \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.
*
* \funcusage
* \snippet gpio/gpio_v1_10_sut_01.cydsn/main_cm4.c snippet_Cy_GPIO_Pin_FastInit
*
*******************************************************************************/
void Cy_GPIO_Pin_FastInit(GPIO_PRT_Type* base, uint32_t pinNum, uint32_t driveMode,
uint32_t outVal, en_hsiom_sel_t hsiom)
{
uint32_t tempReg;
CY_ASSERT_L2(CY_GPIO_IS_PIN_VALID(pinNum));
CY_ASSERT_L2(CY_GPIO_IS_DM_VALID(driveMode));
CY_ASSERT_L2(CY_GPIO_IS_VALUE_VALID(outVal));
CY_ASSERT_L2(CY_GPIO_IS_HSIOM_VALID(hsiom));
tempReg = (base->OUT & ~(CY_GPIO_OUT_MASK << pinNum));
base->OUT = tempReg | ((outVal & CY_GPIO_OUT_MASK) << pinNum);
tempReg = (base->CFG & ~(CY_GPIO_CFG_DM_MASK << (pinNum << CY_GPIO_DRIVE_MODE_OFFSET)));
base->CFG = tempReg | ((driveMode & CY_GPIO_CFG_DM_MASK) << (pinNum << CY_GPIO_DRIVE_MODE_OFFSET));
Cy_GPIO_SetHSIOM(base, pinNum, hsiom);
}
/*******************************************************************************
* Function Name: Cy_GPIO_Port_Deinit
****************************************************************************//**
*
* \brief Reset a complete port of pins back to power on reset defaults.
*
* \param base
* Pointer to the pin's port register base address
*
* \return
* void
*
* \funcusage
* \snippet gpio/gpio_v1_10_sut_01.cydsn/main_cm4.c snippet_Cy_GPIO_Port_Deinit
*
*******************************************************************************/
void Cy_GPIO_Port_Deinit(GPIO_PRT_Type* base)
{
uint32_t portNum;
HSIOM_PRT_Type* portAddrHSIOM;
portNum = ((uint32_t)(base) - GPIO_BASE) / GPIO_PRT_SECTION_SIZE;
portAddrHSIOM = (HSIOM_PRT_Type*)(HSIOM_BASE + (HSIOM_PRT_SECTION_SIZE * portNum));
base->OUT = CY_GPIO_PRT_DEINIT;
base->CFG = CY_GPIO_PRT_DEINIT;
base->CFG_IN = CY_GPIO_PRT_DEINIT;
base->CFG_OUT = CY_GPIO_PRT_DEINIT;
base->INTR_CFG = CY_GPIO_PRT_DEINIT;
base->INTR_MASK = CY_GPIO_PRT_DEINIT;
base->CFG_SIO = CY_GPIO_PRT_DEINIT;
portAddrHSIOM->PORT_SEL0 = CY_GPIO_PRT_DEINIT;
portAddrHSIOM->PORT_SEL1 = CY_GPIO_PRT_DEINIT;
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,287 @@
/***************************************************************************//**
* \file cy_i2s.c
* \version 2.0.1
*
* The source code file for the I2S driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "cy_i2s.h"
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_I2S_Init
****************************************************************************//**
*
* Initializes the I2S module in accordance with a configuration structure.
*
* \pre If the I2S module is initialized previously, the \ref Cy_I2S_DeInit()
* must be called before calling this function.
*
* \param base The pointer to the I2S instance address.
*
* \param config The pointer to a configuration structure.
*
* \return error / status code. See \ref cy_en_i2s_status_t.
*
* \funcusage
* \snippet i2s/i2s_v2_0_sut_00.cydsn/main_cm4.c snippet_Cy_I2S_Init
*
*******************************************************************************/
cy_en_i2s_status_t Cy_I2S_Init(I2S_Type * base, cy_stc_i2s_config_t const * config)
{
cy_en_i2s_status_t ret = CY_I2S_BAD_PARAM;
if((NULL != base) && (NULL != config))
{
cy_en_i2s_ws_pw_t wsPulseWidth;
cy_en_i2s_len_t channelLength;
uint32_t channels;
uint32_t clockDiv = (uint32_t)config->clkDiv - 1U;
CY_ASSERT_L2(CY_I2S_IS_CLK_DIV_VALID(clockDiv));
/* The clock setting */
base->CLOCK_CTL = _VAL2FLD(I2S_CLOCK_CTL_CLOCK_DIV, clockDiv) |
_BOOL2FLD(I2S_CLOCK_CTL_CLOCK_SEL, config->extClk);
/* The Tx setting */
if (config->txEnabled)
{
CY_ASSERT_L3(CY_I2S_IS_ALIGNMENT_VALID(config->txAlignment));
CY_ASSERT_L3(CY_I2S_IS_OVHDATA_VALID(config->txOverheadValue));
if ((CY_I2S_TDM_MODE_A == config->txAlignment) || (CY_I2S_TDM_MODE_B == config->txAlignment))
{
channels = (uint32_t)config->txChannels - 1UL;
wsPulseWidth = config->txWsPulseWidth;
channelLength = CY_I2S_LEN32;
CY_ASSERT_L2(CY_I2S_IS_CHANNELS_VALID(channels));
CY_ASSERT_L3(CY_I2S_IS_WSPULSE_VALID(wsPulseWidth));
CY_ASSERT_L3(CY_I2S_IS_LEN_VALID(config->txWordLength));
}
else
{
channels = 1UL;
wsPulseWidth = CY_I2S_WS_ONE_CHANNEL_LENGTH;
channelLength = config->txChannelLength;
CY_ASSERT_L3(CY_I2S_IS_CHAN_WORD_VALID(channelLength, config->txWordLength));
}
CY_ASSERT_L2(CY_I2S_IS_TRIG_LEVEL_VALID(config->txFifoTriggerLevel, channels));
base->TX_WATCHDOG = config->txWatchdogValue;
base->TX_CTL = _VAL2FLD(I2S_TX_CTL_I2S_MODE, config->txAlignment) |
_BOOL2FLD(I2S_TX_CTL_B_CLOCK_INV, config->txSdoLatchingTime) |
_VAL2FLD(I2S_TX_CTL_CH_NR, channels) |
_BOOL2FLD(I2S_TX_CTL_MS, config->txMasterMode) |
_VAL2FLD(I2S_TX_CTL_WS_PULSE, wsPulseWidth) |
_BOOL2FLD(I2S_TX_CTL_WD_EN, config->txWatchdogEnable) |
_BOOL2FLD(I2S_TX_CTL_SCKO_POL, config->txSckoInversion) |
_BOOL2FLD(I2S_TX_CTL_SCKI_POL, config->txSckiInversion) |
_VAL2FLD(I2S_TX_CTL_CH_LEN, channelLength) |
_VAL2FLD(I2S_TX_CTL_WORD_LEN, config->txWordLength) |
_VAL2FLD(I2S_TX_CTL_OVHDATA, config->txOverheadValue);
}
/* The Rx setting */
if (config->rxEnabled)
{
CY_ASSERT_L3(CY_I2S_IS_ALIGNMENT_VALID(config->rxAlignment));
if ((CY_I2S_TDM_MODE_A == config->rxAlignment) || (CY_I2S_TDM_MODE_B == config->rxAlignment))
{
channels = (uint32_t)config->rxChannels - 1UL;
wsPulseWidth = config->rxWsPulseWidth;
channelLength = CY_I2S_LEN32;
CY_ASSERT_L2(CY_I2S_IS_CHANNELS_VALID(channels));
CY_ASSERT_L3(CY_I2S_IS_WSPULSE_VALID(wsPulseWidth));
CY_ASSERT_L3(CY_I2S_IS_LEN_VALID(config->rxWordLength));
}
else
{
channels = 1UL;
wsPulseWidth = CY_I2S_WS_ONE_CHANNEL_LENGTH;
channelLength = config->rxChannelLength;
CY_ASSERT_L3(CY_I2S_IS_CHAN_WORD_VALID(channelLength, config->rxWordLength));
}
CY_ASSERT_L2(CY_I2S_IS_TRIG_LEVEL_VALID(config->rxFifoTriggerLevel, channels));
base->RX_WATCHDOG = config->rxWatchdogValue;
base->RX_CTL = _VAL2FLD(I2S_RX_CTL_I2S_MODE, config->rxAlignment) |
_BOOL2FLD(I2S_RX_CTL_B_CLOCK_INV, config->rxSdiLatchingTime) |
_VAL2FLD(I2S_RX_CTL_CH_NR, channels) |
_BOOL2FLD(I2S_RX_CTL_MS, config->rxMasterMode) |
_VAL2FLD(I2S_RX_CTL_WS_PULSE, wsPulseWidth) |
_BOOL2FLD(I2S_RX_CTL_WD_EN, config->rxWatchdogEnable) |
_BOOL2FLD(I2S_RX_CTL_SCKO_POL, config->rxSckoInversion) |
_BOOL2FLD(I2S_RX_CTL_SCKI_POL, config->rxSckiInversion) |
_VAL2FLD(I2S_RX_CTL_CH_LEN, channelLength) |
_VAL2FLD(I2S_RX_CTL_WORD_LEN, config->rxWordLength) |
_BOOL2FLD(I2S_RX_CTL_BIT_EXTENSION, config->rxSignExtension);
}
/* The I2S enable setting */
if (config->txEnabled)
{
base->CTL |= I2S_CTL_TX_ENABLED_Msk;
}
if (config->rxEnabled)
{
base->CTL |= I2S_CTL_RX_ENABLED_Msk;
}
/* The FIFO setting */
if (config->txEnabled)
{
base->TX_FIFO_CTL = _VAL2FLD(I2S_TX_FIFO_CTL_TRIGGER_LEVEL, config->txFifoTriggerLevel);
base->TR_CTL |= _BOOL2FLD(I2S_TR_CTL_TX_REQ_EN, config->txDmaTrigger);
}
if (config->rxEnabled)
{
base->RX_FIFO_CTL = _VAL2FLD(I2S_RX_FIFO_CTL_TRIGGER_LEVEL, config->rxFifoTriggerLevel);
base->TR_CTL |= _BOOL2FLD(I2S_TR_CTL_RX_REQ_EN, config->rxDmaTrigger);
}
ret = CY_I2S_SUCCESS;
}
return (ret);
}
/*******************************************************************************
* Function Name: Cy_I2S_DeInit
****************************************************************************//**
*
* Uninitializes the I2S module (reverts default register values).
*
* \param base The pointer to the I2S instance address.
*
* \funcusage
* \snippet i2s/i2s_v2_0_sut_00.cydsn/main_cm4.c snippet_Cy_I2S_DeInit
*
*******************************************************************************/
void Cy_I2S_DeInit(I2S_Type * base)
{
base->INTR_MASK = 0UL; /* Disable interrupts prior to stopping the operation */
base->CMD = 0UL;
base->TR_CTL = 0UL;
base->TX_FIFO_CTL = 0UL;
base->RX_FIFO_CTL = 0UL;
base->CTL = 0UL;
base->TX_CTL = CY_I2S_TX_CTL_DEFAULT;
base->RX_CTL = CY_I2S_RX_CTL_DEFAULT;
base->TX_WATCHDOG = 0UL;
base->RX_WATCHDOG = 0UL;
base->CLOCK_CTL = 0UL;
}
/*******************************************************************************
* Function Name: Cy_I2S_DeepSleepCallback
****************************************************************************//**
*
* This is a callback function to be used at the application layer to
* manage an I2S operation during the Deep-Sleep cycle. It stores the I2S state
* (Tx/Rx enabled/disabled/paused) into the context structure and stops the
* communication before entering into Deep-Sleep power mode and restores the I2S
* state after waking up.
*
* \param
* callbackParams - The pointer to the callback parameters structure,
* see \ref cy_stc_syspm_callback_params_t.
*
* \return the SysPm callback status \ref cy_en_syspm_status_t.
*
* \note Use the \ref cy_stc_i2s_context_t data type for definition of the
* *context element of the \ref cy_stc_syspm_callback_params_t strusture.
*
* \funcusage
* \snippet i2s/i2s_v2_0_sut_00.cydsn/main_cm4.c snippet_Cy_I2S_DeepSleepCallback
*
*******************************************************************************/
cy_en_syspm_status_t Cy_I2S_DeepSleepCallback(cy_stc_syspm_callback_params_t * callbackParams)
{
cy_en_syspm_status_t ret = CY_SYSPM_SUCCESS;
CY_ASSERT_L1(NULL != callbackParams->context);
I2S_Type * locBase = (I2S_Type*) callbackParams->base;
uint32_t * locInterruptMask = (uint32_t*) &(((cy_stc_i2s_context_t*)(callbackParams->context))->interruptMask);
uint32_t * locState = (uint32_t*) &(((cy_stc_i2s_context_t*)(callbackParams->context))->enableState);
switch(callbackParams->mode)
{
case CY_SYSPM_CHECK_READY:
case CY_SYSPM_CHECK_FAIL:
break;
case CY_SYSPM_BEFORE_TRANSITION:
*locInterruptMask = Cy_I2S_GetInterruptMask(locBase); /* Store I2S interrupts */
*locState = Cy_I2S_GetCurrentState(locBase); /* Store I2S state */
if (0UL != (*locState & I2S_CMD_TX_START_Msk))
{
Cy_I2S_DisableTx(locBase); /* Stop TX operation */
}
if (0UL != (*locState & I2S_CMD_RX_START_Msk))
{
Cy_I2S_DisableRx(locBase); /* Stop RX operation */
}
Cy_I2S_SetInterruptMask(locBase, 0UL); /* Disable I2S interrupts */
/* Unload FIFOs in order not to lose data (if needed) */
break;
case CY_SYSPM_AFTER_TRANSITION:
if (0UL != (*locState & I2S_CMD_RX_START_Msk))
{
Cy_I2S_ClearRxFifo(locBase); /* Clear the RX FIFO */
Cy_I2S_EnableRx(locBase); /* Start RX operation */
}
if (0UL != (*locState & I2S_CMD_TX_START_Msk))
{
Cy_I2S_ClearTxFifo(locBase); /* Clear the TX FIFO */
Cy_I2S_WriteTxData(locBase, 0UL); /* Fill at least one TX frame */
Cy_I2S_WriteTxData(locBase, 0UL);
if (0UL != (*locState & I2S_CMD_TX_PAUSE_Msk))
{
Cy_I2S_PauseTx(locBase); /* Restore the TX paused state */
}
Cy_I2S_EnableTx(locBase); /* Start TX operation */
}
Cy_I2S_ClearInterrupt(locBase, *locInterruptMask); /* Clear possible pending I2S interrupts */
Cy_I2S_SetInterruptMask(locBase, *locInterruptMask); /* Restore I2S interrupts */
break;
default:
ret = CY_SYSPM_FAIL;
break;
}
return(ret);
}
#ifdef __cplusplus
}
#endif
/* [] END OF FILE */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,170 @@
/***************************************************************************//**
* \file cy_ipc_drv.c
* \version 1.10.1
*
* \breif
* IPC Driver - This source file contains the low-level driver code for
* the IPC hardware.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "cy_ipc_drv.h"
/*******************************************************************************
* Function Name: Cy_IPC_Drv_LockRelease
****************************************************************************//**
*
* The function is used to release an IPC channel from the locked state.
* The function also has a way to specify through a parameter which IPC
* interrupts must be notified during the release event.
*
* \param base
* This parameter is a handle that 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 of the operation
* \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC channel
* was released.
* \retval CY_IPC_DRV_ERROR: The IPC channel was not acquired before the
* function call.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_ReadMsgPtr
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_Drv_LockRelease (IPC_STRUCT_Type* base, uint32_t releaseEventIntr)
{
cy_en_ipcdrv_status_t retStatus;
/* Check to make sure the IPC is Acquired */
if( Cy_IPC_Drv_IsLockAcquired(base) )
{
/* The IPC was acquired, release the IPC channel */
Cy_IPC_Drv_ReleaseNotify(base, releaseEventIntr);
retStatus = CY_IPC_DRV_SUCCESS;
}
else /* The IPC channel was already released (not acquired) */
{
retStatus = CY_IPC_DRV_ERROR;
}
return (retStatus);
}
/*******************************************************************************
* 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 base
* This parameter is a handle that 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 of the operation:
* \retval CY_IPC_DRV_SUCCESS: The send operation was successful.
* \retval CY_IPC_DRV_ERROR: The IPC channel is unavailable because it is already locked.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_SendMsgWord
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_Drv_SendMsgWord (IPC_STRUCT_Type* base, uint32_t notifyEventIntr, uint32_t message)
{
cy_en_ipcdrv_status_t retStatus;
if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire(base) )
{
/* If the channel was acquired, send the message. */
Cy_IPC_Drv_WriteDataValue(base, message);
Cy_IPC_Drv_AcquireNotify(base, 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 (for a valid message).
* If the channel is not locked, the message is invalid. The user must call
* Cy_IPC_Drv_Release() function after reading the message to release the
* IPC channel.
*
* \param base
* This parameter is a handle that 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 of the operation
* \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC
* was acquired.
* \retval CY_IPC_DRV_ERROR: The function encountered an error because the IPC
* channel was already in a released state, meaning the data
* may be invalid.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_ReadMsgWord
*
*******************************************************************************/
cy_en_ipcdrv_status_t Cy_IPC_Drv_ReadMsgWord (IPC_STRUCT_Type const * base, uint32_t * message)
{
cy_en_ipcdrv_status_t retStatus;
CY_ASSERT_L1(NULL != message);
if ( Cy_IPC_Drv_IsLockAcquired(base) )
{
/* The channel is locked; message is valid. */
*message = Cy_IPC_Drv_ReadDataValue(base);
retStatus = CY_IPC_DRV_SUCCESS;
}
else
{
/* The channel is not locked so channel is invalid. */
retStatus = CY_IPC_DRV_ERROR;
}
return(retStatus);
}
/* [] END OF FILE */

View File

@ -0,0 +1,930 @@
/***************************************************************************//**
* \file cy_ipc_drv.h
* \version 1.10.1
*
* Provides an API declaration of the IPC driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#ifndef CY_IPC_DRV_H
#define CY_IPC_DRV_H
/**
* \defgroup group_ipc Inter Process Communication (IPC)
* \{
* The inter-processor communication (IPC) driver provides a safe and reliable
* method to transfer data between CPUs. Hardware locking ensures that only one
* device can acquire and transfer data at a time so no data is lost or
* overwritten by asynchronous processes or CPUs.
*
* There are three parts to the API:
* - Driver-level (DRV) API - used internally by Semaphore and Pipe levels
* - Pipe-level (PIPE) API - establishes a communication channel between
* processors
* - Semaphore-level (SEMA) API - enables users to set and clear flags to
* synchronize operations.
*
* Firmware does not need to use the DRV API. It can implement IPC functionality
* entirely with the PIPE and SEMA APIs.
*
* \section group_ipc_background Background
*
* IPC is implemented in hardware as a collection of individual communication
* channels, each with a set of 32-bit registers. The IPC design implements a set
* of interrupts that enable each processor to notify the other that data is
* available, or has been processed. There is also a locking mechanism that
* allows only one CPU to gain access at a time.
*
* The Driver-level API manages each channel's registers to implement IPC
* functionality. For information on the IPC registers, see the IPC chapter of
* the Technical Reference Manual (TRM).
*
* At the hardware level, communication is a five-step process.
* -# The sending processor acquires a channel
* -# It puts data into the channel
* -# The sender generates a notify event (interrupt)
* -# The receiving processor identifies the sender and retrieves the data
* -# The receiving processor generates a release event (interrupt)
*
* \image html ipc_driver.png
*
* These transactions are handled transparently by the DRV-level API. Use the
* PIPE and SEMA layers of the API to implement communication in your application.
* The data transferred is limited to a single 32-bit value. As implemented by
* the PIPE API, that value is a pointer to a data structure of arbitrary size
* and complexity.
*
* \section group_ipc_overview Overview
*
* The Pipe is the key element in the PDL design. A pipe is typically a
* full-duplex communication channel between CPU cores. A pipe allows a single
* conduit to transfer messages or data to and from multiple processes or CPUs.
*
* A pipe has two endpoints, one on each core. Each endpoint contains a dedicated
* IPC channel and an interrupt. IPC channels 0-7 and IPC interrupts 0-7 are
* reserved for system use.
*
* The pipe also contains the number of clients it supports, and for each client
* a callback function. So the pipe can service a number of clients, each with a
* separate callback function, on either endpoint. The number of clients a pipe
* supports is the sum of each endpoint's clients.
*
* This design enables any number of processes on the sending core to put
* arbitrary data into a single pipe. The first element of that data is the
* client ID of the client that should handle the data.
*
* An interrupt notifies the receiving core that data is available. The receiving
* core parses the data to identify the client, and then dispatches the event to
* the appropriate client via the client callback function. An interrupt notifies
* the sending core that the receiver is finished. In this way a single pipe can
* manage arbitrary data transfers between cores with data flowing in either
* direction.
*
* \image html ipc_ints.png
*
* The application can use semaphores to control access to shared resources, as
* required by the application's logic.
*
* The PDL provides two specific files that set up default IPC functionality.
* They are cy_ipc_config.h and cy_ipc_config.c. You can modify these files based
* on the requirements of your design. If you use PSoC Creator as a development
* environment, it will not overwrite your changes when you generate the
* application or build your code.
*
* \section group_ipc_pipe_layer PIPE layer
*
* A pipe is a communication channel between two endpoints. PSoC 6 devices support
* 16 IPC channels, and 16 IPC interrupts, each numbered 0-15. IPC Channels 0-7
* and IPC interrupts 0-7 are reserved for system use. Channels 8-15 and
* interrupts 8-15 are available for application use.
*
* A full duplex pipe uses two IPC channels, one per endpoint. Each endpoint
* specifies all the information required to process a message (either sent or
* received). Each endpoint is configured to use an IPC channel, and an IPC
* interrupt. Common practice is to use the interrupt with the same number as
* the IPC channel. However, IPC Interrupts are not directly associated with the
* IPC channels, so any channel can use any interrupt. Any IPC channel can
* trigger 0, 1 or all the IPC interrupts at once, depending on the Notify or
* Release masks used.
*
* It is also possible to set up a one-directional pipe, using a single IPC
* channel. In this design one processor is always the sender, and the other is
* always the receiver. However, there are still two endpoints.
*
* A pipe supports an arbitrary number of clients with an array of callback
* functions, one per client. The client ID is the index number into the array
* for the client. After a pipe is configured and initialized, the application
* calls Cy_IPC_Pipe_RegisterCallback() once per client to register each client's
* callback function. Multiple clients can use the same callback function. The
* endpoints in a pipe share the callback array.
*
* Use Cy_IPC_Pipe_SendMessage() to send data. You specify both the "to" and
* "from" endpoints, and a callback function to be used when the data transfer is
* complete. The data is a 32-bit void pointer. The data pointed to is arbitrary,
* and can be an array, a structure, or a location in memory. The only limitation
* is that the first element of the data must be a 32-bit unsigned word containing
* a client ID number. The ID number is the index into the callback array.
*
* When a message is sent, the receiving endpoint's interrupt handler is called.
* The ISR can perform any task required by the design. However, as part of its
* function it calls \ref Cy_IPC_Pipe_ExecCallback. This function retrieves the
* client ID from the data and calls the associated callback function.
* The user-supplied callback function handles the data in whatever way is
* appropriate based on the application logic.
*
* After the callback function is returned by the receiver, it invokes the release
* callback function defined by the sender of the message.
*
* \section group_ipc_sema_layer SEMA Layer
*
* A semaphore is a flag the application uses to control access to a shared
* resource. The SEMA-level API uses an IPC channel to implement
* semaphores. Startup code sets up a default semaphore system. The
* default system creates an array of 128 semaphores (four 32-bit values).
* Semaphores 0-15 are reserved for system use. See
* Configuration Considerations - SEMA.
*
* Functions are available to initialize the semaphore system, to set or
* clear a semaphore, or to get the semaphore's current status. Application
* logic uses SEMA functions to relate a particular semaphore to a particular
* shared resource, and set, clear, or check the flag when accessing the
* shared resource.
*
* \section group_ipc_configuration_cypipe Configuration Considerations - CYPIPE
*
* There are none. The cy_ipc_config files set up the required CYPIPE for system
* use. Do not modify the CYPIPE. It uses IPC channels 5 and 6 to implement full
* duplex communication between cores. On the CM0+ the notify interrupt is
* assigned to NVIC IRQn 27. See System Interrupt (SysInt) for background.
*
* To create your own pipe you should make 3 steps:
* -# Define pipe callbacks processing interrupt handler
* -# Define your pipe configuration by cy_stc_ipc_pipe_config_t type structure
* -# Call Cy_IPC_Pipe_Init() to initialize your pipe on both cores
*
* \section group_ipc_configuration_sema Configuration Considerations - SEMA
*
* Startup code calls Cy_IPC_SystemSemaInit() (in cy_ipc_config.c) to set up
* semaphore functionality. This function calls the PDL init function
* Cy_IPC_Sema_Init() with default values. By default the semaphore system
* uses IPC channel 4, and creates 128 semaphores. Do <b>not</b> change the IPC
* channel. You can change the number of semaphores.
*
* To change the number of semaphores, modify this line of code in cy_ipc_config.h.
*
* \code
* #define CY_IPC_SEMA_COUNT (uint32_t)(128u)
* \endcode
*
* The file cy_ipc_config.c declares array ipcSemaArray to hold the semaphore
* flags based on the size defined for this symbol. Use increments of 32. You
* must have at least 32 semaphores. Semaphores 0-15 are reserved for
* system use. Your application can use semaphores greater than 15.
*
* \section group_ipc_more_information More Information
*
* Cy_IPC_SystemSemaInit() and Cy_IPC_SystemPipeInit() functions are called in the
* SystemInit function. If the default startup file is not used, or SystemInit is
* not called in your project, call the following three functions prior to
* executing any flash or EmEEPROM write or erase operation. For example:
* -# Cy_IPC_SystemSemaInit()
* -# Cy_IPC_SystemPipeInit()
* -# Cy_Flash_Init()
*
* Also Cy_IPC_SystemPipeInit function is called to support BLE host/controller
* communication.
*
* See the technical reference manual(TRM) for more information on the 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>10.3</td>
* <td>R</td>
* <td>The value of a complex expression of integer type shall be cast
* only to a type of the same signedness that is no wider than the underlying
* type of the expression.</td>
* <td>The cast from integer to enumeration value is used to calculate
* the interrupt vector source from the integer number of the IPC interrupt
* structure, so there is no way to avoid this cast.</td>
* </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 \ref group_ipc channel by exchanging the pointer. We
* exchange only one pointer, so there is no way to avoid this cast.</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.10.1</td>
* <td>Updated description of the \ref Cy_IPC_Pipe_Init,
* \ref Cy_IPC_Pipe_EndpointInit, \ref Cy_IPC_Sema_Set functions.
* Added / updated code snippets.
* </td>
* <td>Documentation update and clarification</td>
* </tr>
* <tr>
* <td>1.10</td>
* <td>Added support for more IPC structures</td>
* <td>New device support</td>
* </tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_ipc_drv IPC driver layer (IPC_DRV)
* \{
* The functions of this layer are used in the higher IPC levels
* (Semaphores and Pipes).
* Users should not call any of these IPC functions directly.
*
* \defgroup group_ipc_macros Macros
* Macro definitions are used in the driver
*
* \defgroup group_ipc_functions Functions
* Functions are used in the driver
*
* \defgroup group_ipc_data_structures Data Structures
* Data structures are used in the driver
*
* \defgroup group_ipc_enums Enumerated Types
* Enumerations are used in the driver
* \}
*
* \defgroup group_ipc_sema IPC semaphores layer (IPC_SEMA)
* \defgroup group_ipc_pipe IPC pipes layer (IPC_PIPE)
*
*/
/******************************************************************************/
/* Include files */
/******************************************************************************/
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
#include "cy_ipc_config.h"
#include <stddef.h>
/**
* \addtogroup group_ipc_macros
* \{
*/
/** Driver major version */
#define CY_IPC_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_IPC_DRV_VERSION_MINOR 10
/** Defines a value to indicate that no notification events are needed */
#define CY_IPC_NO_NOTIFICATION (uint32_t)(0x00000000ul)
/* Error Code constants */
#define CY_IPC_ID CY_PDL_DRV_ID(0x22u) /**< Software PDL driver ID for IPC */
/** Return prefix for IPC driver function status codes */
#define CY_IPC_ID_INFO (uint32_t)( CY_IPC_ID | CY_PDL_STATUS_INFO )
/** Return prefix for IPC driver function warning return values */
#define CY_IPC_ID_WARNING (uint32_t)( CY_IPC_ID | CY_PDL_STATUS_WARNING)
/** Return prefix for IPC driver function error return values */
#define CY_IPC_ID_ERROR (uint32_t)( CY_IPC_ID | CY_PDL_STATUS_ERROR)
/** Converts the IPC interrupt channel number to interrupt vector */
#define CY_IPC_INTR_NUM_TO_VECT(x) ((int32_t)cpuss_interrupts_ipc_0_IRQn + (x))
/** \} group_ipc_macros */
/* end of definition in device.h */
/**
* \addtogroup group_ipc_enums
* \{
*/
/**
* This is a list of ENUMs used for function return status.
*/
typedef enum
{
/** Function was successfully executed */
CY_IPC_DRV_SUCCESS = (0x00u),
/** Function was not executed due to an error.
Typical conditions for the error explained
in the function description */
CY_IPC_DRV_ERROR = ( CY_IPC_ID_ERROR + 1ul),
} cy_en_ipcdrv_status_t;
/** \} group_ipc_enums */
#ifdef __cplusplus
extern "C" {
#endif
/** \cond INTERNAL */
__STATIC_INLINE void Cy_IPC_Drv_WriteDataValue (IPC_STRUCT_Type* base, uint32_t dataValue);
__STATIC_INLINE uint32_t Cy_IPC_Drv_ReadDataValue (IPC_STRUCT_Type const * base);
__STATIC_INLINE uint32_t Cy_IPC_Drv_ExtractAcquireMask (uint32_t intMask);
__STATIC_INLINE uint32_t Cy_IPC_Drv_ExtractReleaseMask (uint32_t intMask);
/** \endcond */
/**
* \addtogroup group_ipc_functions
* \{
*/
__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);
__STATIC_INLINE void Cy_IPC_Drv_AcquireNotify (IPC_STRUCT_Type * base, uint32_t notifyEventIntr);
__STATIC_INLINE void Cy_IPC_Drv_ReleaseNotify (IPC_STRUCT_Type * base, uint32_t notifyEventIntr);
__STATIC_INLINE cy_en_ipcdrv_status_t Cy_IPC_Drv_LockAcquire (IPC_STRUCT_Type const * base);
cy_en_ipcdrv_status_t Cy_IPC_Drv_LockRelease (IPC_STRUCT_Type * base, uint32_t releaseEventIntr);
__STATIC_INLINE bool Cy_IPC_Drv_IsLockAcquired (IPC_STRUCT_Type const * base);
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetLockStatus (IPC_STRUCT_Type const * base);
cy_en_ipcdrv_status_t Cy_IPC_Drv_SendMsgWord (IPC_STRUCT_Type * base, uint32_t notifyEventIntr, uint32_t message);
cy_en_ipcdrv_status_t Cy_IPC_Drv_ReadMsgWord (IPC_STRUCT_Type const * base, uint32_t * message);
__STATIC_INLINE cy_en_ipcdrv_status_t Cy_IPC_Drv_SendMsgPtr (IPC_STRUCT_Type* base, uint32_t notifyEventIntr, void const * msgPtr);
__STATIC_INLINE cy_en_ipcdrv_status_t Cy_IPC_Drv_ReadMsgPtr (IPC_STRUCT_Type const * base, void ** msgPtr);
__STATIC_INLINE void Cy_IPC_Drv_SetInterruptMask (IPC_INTR_STRUCT_Type * base,
uint32_t ipcReleaseMask, uint32_t ipcNotifyMask);
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptMask (IPC_INTR_STRUCT_Type const * base);
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptStatusMasked (IPC_INTR_STRUCT_Type const * base);
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptStatus (IPC_INTR_STRUCT_Type const * base);
__STATIC_INLINE void Cy_IPC_Drv_SetInterrupt (IPC_INTR_STRUCT_Type * base,
uint32_t ipcReleaseMask, uint32_t ipcNotifyMask);
__STATIC_INLINE void Cy_IPC_Drv_ClearInterrupt (IPC_INTR_STRUCT_Type * base,
uint32_t ipcReleaseMask, uint32_t ipcNotifyMask);
/*******************************************************************************
* Function Name: Cy_IPC_Drv_GetIpcBaseAddress
****************************************************************************//**
*
* This function takes an IPC channel index as a parameter and returns the base
* address the IPC registers corresponding to the IPC channel.
*
* \note The user is responsible for ensuring that ipcIndex does not exceed the
* limits.
*
* \param ipcIndex
* Represents the number of IPC structure. This is converted to the base address of
* the IPC channel registers.
*
* \return
* Returns a pointer to the base of the IPC registers.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_SendMsgWord
*
*******************************************************************************/
__STATIC_INLINE IPC_STRUCT_Type* Cy_IPC_Drv_GetIpcBaseAddress (uint32_t ipcIndex)
{
CY_ASSERT_L1((uint32_t)CY_IPC_CHANNELS > ipcIndex);
return ( (IPC_STRUCT_Type*) ( &IPC->STRUCT[ipcIndex] ) );
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_GetIntrBaseAddr
****************************************************************************//**
*
* This function takes an IPC interrupt structure index and returns the base
* address of the IPC interrupt registers corresponding to the IPC Interrupt.
*
* \note The user is responsible for ensuring that ipcIntrIndex does not exceed the
* limits.
*
* \param ipcIntrIndex
* Represents the number of IPC interrupt structure. This is converted to the
* base address of the IPC interrupt registers.
*
* \return
* Returns a pointer to the base of the IPC interrupt registers.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_GetInterruptStatus
*
*******************************************************************************/
__STATIC_INLINE IPC_INTR_STRUCT_Type* Cy_IPC_Drv_GetIntrBaseAddr (uint32_t ipcIntrIndex)
{
CY_ASSERT_L1((uint32_t)CY_IPC_INTERRUPTS > ipcIntrIndex);
return ( (IPC_INTR_STRUCT_Type*) ( &IPC->INTR_STRUCT[ipcIntrIndex] ) );
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_SetInterruptMask
****************************************************************************//**
*
* This function is used to set the interrupt mask for an IPC Interrupt.
* The mask sets release or acquire notification events for all IPC channels.
*
* \param base
* 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 channels that can trigger the interrupt on a
* release event.
*
* \param ipcNotifyMask
* An encoded list of all IPC channels that can trigger the interrupt on a
* notify event.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_GetInterruptStatusMasked
*
*******************************************************************************/
__STATIC_INLINE void Cy_IPC_Drv_SetInterruptMask (IPC_INTR_STRUCT_Type* base,
uint32_t ipcReleaseMask, uint32_t ipcNotifyMask)
{
CY_ASSERT_L1(0ul == (ipcNotifyMask & ~(uint32_t)(IPC_STRUCT_NOTIFY_INTR_NOTIFY_Msk)));
CY_ASSERT_L1(0ul == (ipcReleaseMask & ~(uint32_t)(IPC_STRUCT_RELEASE_INTR_RELEASE_Msk)));
base->INTR_MASK = _VAL2FLD( IPC_INTR_STRUCT_INTR_MASK_NOTIFY, ipcNotifyMask) |
_VAL2FLD( IPC_INTR_STRUCT_INTR_MASK_RELEASE, ipcReleaseMask);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_GetInterruptMask
****************************************************************************//**
*
* This function is used to read the interrupt mask.
*
* \param base
* 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+16th bit set
* </table>
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_GetInterruptStatusMasked
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptMask(IPC_INTR_STRUCT_Type const * base)
{
return (base->INTR_MASK);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_GetInterruptStatusMasked
****************************************************************************//**
*
* 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 base
* 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+16th bit set
* </table>
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_GetInterruptStatusMasked
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptStatusMasked (IPC_INTR_STRUCT_Type const * base)
{
return (base->INTR_MASKED);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_GetInterruptStatus
****************************************************************************//**
*
* 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 base
* 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+16th bit set
* </table>
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_GetInterruptStatus
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptStatus(IPC_INTR_STRUCT_Type const * base)
{
return (base->INTR);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_SetInterrupt
****************************************************************************//**
*
* 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 base
* 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 channels that can trigger the interrupt on a
* release event.
*
* \param ipcNotifyMask
* An encoded list of all IPC channels that can trigger the interrupt on a
* notify event.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_SetInterrupt
*
*******************************************************************************/
__STATIC_INLINE void Cy_IPC_Drv_SetInterrupt(IPC_INTR_STRUCT_Type* base, uint32_t ipcReleaseMask, uint32_t ipcNotifyMask)
{
CY_ASSERT_L1(0ul == (ipcNotifyMask & ~(uint32_t)(IPC_STRUCT_NOTIFY_INTR_NOTIFY_Msk)));
CY_ASSERT_L1(0ul == (ipcReleaseMask & ~(uint32_t)(IPC_STRUCT_RELEASE_INTR_RELEASE_Msk)));
base->INTR_SET = _VAL2FLD( IPC_INTR_STRUCT_INTR_NOTIFY, ipcNotifyMask ) |
_VAL2FLD( IPC_INTR_STRUCT_INTR_RELEASE, ipcReleaseMask );
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ClearInterrupt
****************************************************************************//**
*
* This function is used to clear the interrupt source. Use this function to clear
* a pending interrupt source in the interrupt status.
*
* \param base
* 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 channels that can trigger the interrupt on a
* release event.
*
* \param ipcNotifyMask
* An encoded list of all IPC channels that can trigger the interrupt on a
* notify event.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_GetInterruptStatusMasked
*
*******************************************************************************/
__STATIC_INLINE void Cy_IPC_Drv_ClearInterrupt(IPC_INTR_STRUCT_Type* base, uint32_t ipcReleaseMask, uint32_t ipcNotifyMask)
{
CY_ASSERT_L1(0ul == (ipcNotifyMask & ~(uint32_t)(IPC_STRUCT_NOTIFY_INTR_NOTIFY_Msk)));
CY_ASSERT_L1(0ul == (ipcReleaseMask & ~(uint32_t)(IPC_STRUCT_RELEASE_INTR_RELEASE_Msk)));
base->INTR = _VAL2FLD(IPC_INTR_STRUCT_INTR_NOTIFY, ipcNotifyMask) |
_VAL2FLD(IPC_INTR_STRUCT_INTR_RELEASE, ipcReleaseMask);
(void)base->INTR; /* Read the register to flush the cache */
}
/** \} group_ipc_functions */
/** \} group_ipc */
/*******************************************************************************
* Function Name: Cy_IPC_Drv_AcquireNotify
****************************************************************************//**
*
* The function generates a notify event by IPC interrupt structures.
*
* \param base
* This parameter is a handle that 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 structures that are triggered
* by a notification. Bit number correspond to number of the IPC interrupt
* structure.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_LockAcquire
*
*******************************************************************************/
__STATIC_INLINE void Cy_IPC_Drv_AcquireNotify (IPC_STRUCT_Type* base, uint32_t notifyEventIntr)
{
CY_ASSERT_L1(0ul == (notifyEventIntr & ~(uint32_t)(IPC_STRUCT_NOTIFY_INTR_NOTIFY_Msk)));
base->NOTIFY = _VAL2FLD(IPC_STRUCT_NOTIFY_INTR_NOTIFY, notifyEventIntr);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ReleaseNotify
****************************************************************************//**
*
* The function generates a notify event to an IPC interrupt structure.
*
* \param base
* This parameter is a handle that 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.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_ReadMsgWord
*
*******************************************************************************/
__STATIC_INLINE void Cy_IPC_Drv_ReleaseNotify (IPC_STRUCT_Type* base, uint32_t notifyEventIntr)
{
CY_ASSERT_L1(0ul == (notifyEventIntr & ~(uint32_t)(IPC_STRUCT_NOTIFY_INTR_NOTIFY_Msk)));
base->RELEASE = _VAL2FLD(IPC_INTR_STRUCT_INTR_RELEASE, notifyEventIntr);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_WriteDataValue
****************************************************************************//**
*
* The function writes a value to the DATA register of the IPC channel.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This parameter is a handle that 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 dataValue
* Value to be written.
*
*******************************************************************************/
__STATIC_INLINE void Cy_IPC_Drv_WriteDataValue (IPC_STRUCT_Type* base, uint32_t dataValue)
{
base->DATA = dataValue;
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ReadDataValue
****************************************************************************//**
*
* The function reads a value from the DATA register of the IPC channel.
*
* This function is internal and should not be called directly by user
* software.
*
* \param base
* This parameter is a handle that 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
* Value from DATA register.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_ReadDataValue (IPC_STRUCT_Type const * base)
{
return (base->DATA);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_IsLockAcquired
****************************************************************************//**
*
* The function is used to test the status of an IPC channel. The function
* tells the reader if the IPC channel was in the locked or released state.
*
* \param base
* This parameter is a handle that 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:
* true: The IPC channel is in the Locked state.
* false: The IPC channel is in the Released state.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_LockAcquire
*
*******************************************************************************/
__STATIC_INLINE bool Cy_IPC_Drv_IsLockAcquired (IPC_STRUCT_Type const * base)
{
return ( 0u != _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, base->LOCK_STATUS) );
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_GetLockStatus
****************************************************************************//**
*
* The function is used to get the status of an IPC channel.
*
* \param base
* This parameter is a handle that 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
* Value from LOCK_STATUS register.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_GetLockStatus
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_GetLockStatus (IPC_STRUCT_Type const * base)
{
return (base->LOCK_STATUS);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ExtractAcquireMask
****************************************************************************//**
*
* The function extracts an Acquire mask part from full interrupt mask value.
*
* This function is internal and should not be called directly by user
* software.
*
* \param intMask
* Interrupt mask value to be processed.
*
* \return
* Acquire mask value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_ExtractAcquireMask (uint32_t intMask)
{
return _FLD2VAL(IPC_INTR_STRUCT_INTR_MASK_NOTIFY, intMask);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ExtractReleaseMask
****************************************************************************//**
*
* The function extracts a Release mask part from full interrupt mask value.
*
* This function is internal and should not be called directly by user
* software.
*
* \param intMask
* Interrupt mask value to be processed.
*
* \return
* Release mask value.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_IPC_Drv_ExtractReleaseMask (uint32_t intMask)
{
return _FLD2VAL(IPC_INTR_STRUCT_INTR_MASK_RELEASE, intMask);
}
/*******************************************************************************
* 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 that 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 base
* This parameter is a handle that 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 of the operation:
* \retval CY_IPC_DRV_SUCCESS: The send operation was successful.
* \retval CY_IPC_DRV_ERROR: The IPC channel is unavailable because
* it is already locked.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_SendMsgPtr
*
*******************************************************************************/
__STATIC_INLINE cy_en_ipcdrv_status_t Cy_IPC_Drv_SendMsgPtr(IPC_STRUCT_Type* base, uint32_t notifyEventIntr, void const * msgPtr)
{
CY_ASSERT_L1(NULL != msgPtr);
return Cy_IPC_Drv_SendMsgWord(base, notifyEventIntr, (uint32_t)msgPtr);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_ReadMsgPtr
****************************************************************************//**
*
* This function is used to read a 32-bit pointer message through an IPC channel.
*
* \param base
* This parameter is a handle that 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 of the operation
* \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC
* was acquired.
* \retval CY_IPC_DRV_ERROR: The function encountered an error because the IPC
* channel was already in a released state meaning the data
* in it is invalid.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_ReadMsgPtr
*
*******************************************************************************/
__STATIC_INLINE cy_en_ipcdrv_status_t Cy_IPC_Drv_ReadMsgPtr (IPC_STRUCT_Type const * base, void ** msgPtr)
{
CY_ASSERT_L1(NULL != msgPtr);
return Cy_IPC_Drv_ReadMsgWord(base, (uint32_t *)msgPtr);
}
/*******************************************************************************
* Function Name: Cy_IPC_Drv_LockAcquire
****************************************************************************//**
*
* This function is used to acquire the IPC channel.
*
* \param base
* This parameter is a handle that 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 of the operation
* \retval CY_IPC_DRV_SUCCESS: The IPC was successfully acquired
* \retval CY_IPC_DRV_ERROR: The IPC was not acquired because it was already acquired
* by another master
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_LockAcquire
*
*******************************************************************************/
__STATIC_INLINE cy_en_ipcdrv_status_t Cy_IPC_Drv_LockAcquire (IPC_STRUCT_Type const * base)
{
return ( 0ul != _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, base->ACQUIRE)) ? CY_IPC_DRV_SUCCESS : CY_IPC_DRV_ERROR;
}
#ifdef __cplusplus
}
#endif
#endif /* !defined(CY_IPC_DRV_H) */
/* [] END OF FILE */

View File

@ -0,0 +1,565 @@
/***************************************************************************//**
* \file cy_ipc_pipe.c
* \version 1.10.1
*
* Description:
* IPC Pipe Driver - This source file includes code for the Pipe layer on top
* of the IPC driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "cy_ipc_pipe.h"
/* Define a pointer to array of endPoints. */
static cy_stc_ipc_pipe_ep_t * cy_ipc_pipe_epArray = NULL;
/*******************************************************************************
* 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.
*
* \note In general case, this function is called in the default startup code,
* so user doesn't need to call it anywhere.
* However, it may be useful in case of some pipe customizations.
*
* \param theEpArray
* This is the pointer to an array of endpoint structures that the designer
* created and will be used to reference all endpoints.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_myIpcPipeEpArray
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Pipe_Config
*
*******************************************************************************/
void Cy_IPC_Pipe_Config(cy_stc_ipc_pipe_ep_t * theEpArray)
{
/* Keep copy of this endpoint */
if (cy_ipc_pipe_epArray == NULL)
{
cy_ipc_pipe_epArray = theEpArray;
}
}
/*******************************************************************************
* Function Name: Cy_IPC_Pipe_Init
****************************************************************************//**
*
* Initializes the system pipes. The system pipes are used by BLE.
* \note The function should be called on all CPUs.
*
* \note In general case, this function is called in the default startup code,
* so user doesn't need to call it anywhere.
* However, it may be useful in case of some pipe customizations.
*
* \param config
* This is the pointer to the pipe configuration structure
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_myIpcPipeCbArray
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_myIpcPipeEpConfig
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Pipe_Init
*
*******************************************************************************/
void Cy_IPC_Pipe_Init(cy_stc_ipc_pipe_config_t const *config)
{
/* Create the interrupt structures and arrays needed */
cy_stc_sysint_t ipc_intr_cypipeConfig;
cy_stc_ipc_pipe_ep_config_t epConfigDataA;
cy_stc_ipc_pipe_ep_config_t epConfigDataB;
/* Parameters checking begin */
CY_ASSERT_L1(NULL != config);
#if (CY_CPU_CORTEX_M0P)
CY_ASSERT_L2((uint32_t)(1UL << __NVIC_PRIO_BITS) > config->ep0ConfigData.ipcNotifierPriority);
#else
CY_ASSERT_L2((uint32_t)(1UL << __NVIC_PRIO_BITS) > config->ep1ConfigData.ipcNotifierPriority);
#endif
CY_ASSERT_L1(NULL != config->endpointsCallbacksArray);
CY_ASSERT_L2(CY_IPC_MAX_ENDPOINTS > config->ep0ConfigData.epAddress);
CY_ASSERT_L2(CY_IPC_MAX_ENDPOINTS > config->ep1ConfigData.epAddress);
CY_ASSERT_L1(NULL != config->userPipeIsrHandler);
/* Parameters checking end */
#if (CY_CPU_CORTEX_M0P)
/* Receiver endpoint = EP0, Sender endpoint = EP1 */
epConfigDataA = config->ep0ConfigData;
epConfigDataB = config->ep1ConfigData;
/* Configure CM0 interrupts */
ipc_intr_cypipeConfig.intrSrc = (IRQn_Type)epConfigDataA.ipcNotifierMuxNumber;
ipc_intr_cypipeConfig.cm0pSrc = (cy_en_intr_t)((int32_t)cpuss_interrupts_ipc_0_IRQn + (int32_t)epConfigDataA.ipcNotifierNumber);
ipc_intr_cypipeConfig.intrPriority = epConfigDataA.ipcNotifierPriority;
#else
/* Receiver endpoint = EP1, Sender endpoint = EP0 */
epConfigDataA = config->ep1ConfigData;
epConfigDataB = config->ep0ConfigData;
/* Configure interrupts */
ipc_intr_cypipeConfig.intrSrc = (IRQn_Type)(cpuss_interrupts_ipc_0_IRQn + epConfigDataA.ipcNotifierNumber);
ipc_intr_cypipeConfig.intrPriority = epConfigDataA.ipcNotifierPriority;
#endif
/* Initialize the pipe endpoints */
Cy_IPC_Pipe_EndpointInit(epConfigDataA.epAddress,
config->endpointsCallbacksArray,
config->endpointClientsCount,
epConfigDataA.epConfig,
&ipc_intr_cypipeConfig);
/* Create the endpoints for the CM4 just for reference */
Cy_IPC_Pipe_EndpointInit(epConfigDataB.epAddress, NULL, 0ul, epConfigDataB.epConfig, NULL);
(void)Cy_SysInt_Init(&ipc_intr_cypipeConfig, config->userPipeIsrHandler);
/* Enable the interrupts */
NVIC_EnableIRQ(ipc_intr_cypipeConfig.intrSrc);
}
/*******************************************************************************
* Function Name: Cy_IPC_Pipe_EndpointInit
****************************************************************************//**
*
* This function initializes the endpoint of a pipe for the current CPU. The
* current CPU is the CPU that is executing the code. An endpoint of a pipe
* is for the IPC channel that receives a message for the current CPU.
*
* 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.
*
* \note In general case, this function is called within \ref Cy_IPC_Pipe_Init,
* so user doesn't need to call it anywhere.
* However, it may be useful in case of some pipe/endpoint customizations.
*
* \param epAddr
* This parameter is the address (or index in the array of endpoint structures)
* that designates the endpoint 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
*
* \param epInterrupt
* This is a pointer to the endpoint interrupt description structure.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_myIpcPipeCbArray
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_myIpcPipeEpConfig
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Pipe_EndpointInit
*
*******************************************************************************/
void Cy_IPC_Pipe_EndpointInit(uint32_t epAddr, cy_ipc_pipe_callback_array_ptr_t cbArray,
uint32_t cbCnt, uint32_t epConfig, cy_stc_sysint_t const *epInterrupt)
{
cy_stc_ipc_pipe_ep_t * endpoint;
CY_ASSERT_L2(CY_IPC_MAX_ENDPOINTS > epAddr);
endpoint = &cy_ipc_pipe_epArray[epAddr];
/* Extract the channel, interrupt and interrupt mask */
endpoint->ipcChan = _FLD2VAL(CY_IPC_PIPE_CFG_CHAN, epConfig);
endpoint->intrChan = _FLD2VAL(CY_IPC_PIPE_CFG_INTR, epConfig);
endpoint->pipeIntMask = _FLD2VAL(CY_IPC_PIPE_CFG_IMASK, epConfig);
/* 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);
/* Only allow notify and release interrupts from endpoints in this pipe. */
Cy_IPC_Drv_SetInterruptMask(endpoint->ipcIntrPtr, endpoint->pipeIntMask, endpoint->pipeIntMask);
/* Save the Client count and the callback array pointer */
endpoint->clientCount = cbCnt;
endpoint->callbackArray = cbArray;
endpoint->busy = CY_IPC_PIPE_ENDPOINT_NOTBUSY;
if (NULL != epInterrupt)
{
endpoint->pipeIntrSrc = epInterrupt->intrSrc;
}
}
/*******************************************************************************
* 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 from 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_ERROR_BAD_HANDLE: The handle provided for the pipe was not valid
* CY_IPC_PIPE_ERROR_SEND_BUSY: The pipe is already busy sending a message
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_myReleaseCallback
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Pipe_SendMessage
*
*******************************************************************************/
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;
CY_ASSERT_L1(NULL != msgPtr);
CY_ASSERT_L2(CY_IPC_MAX_ENDPOINTS > toAddr);
CY_ASSERT_L2(CY_IPC_MAX_ENDPOINTS > fromAddr);
toEp = &(cy_ipc_pipe_epArray[toAddr]);
fromEp = &cy_ipc_pipe_epArray[fromAddr];
/* Create the release mask for the "fromAddr" channel's interrupt channel */
releaseMask = (uint32_t)(1ul << (fromEp->intrChan));
/* Shift into position */
releaseMask = _VAL2FLD(CY_IPC_PIPE_MSG_RELEASE, releaseMask);
/* Create the notify mask for the "toAddr" channel's interrupt channel */
notifyMask = (uint32_t)(1ul << (toEp->intrChan));
/* Check if IPC channel valid */
if( toEp->ipcPtr != NULL)
{
if(fromEp->busy == CY_IPC_PIPE_ENDPOINT_NOTBUSY)
{
/* Attempt to acquire the channel */
if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire(toEp->ipcPtr) )
{
/* Mask out the release mask area */
* (uint32_t *) msgPtr &= ~(CY_IPC_PIPE_MSG_RELEASE_Msk);
* (uint32_t *) msgPtr |= releaseMask;
/* If the channel was acquired, write the message. */
Cy_IPC_Drv_WriteDataValue(toEp->ipcPtr, (uint32_t) msgPtr);
/* Set the busy flag. The ISR clears this after the release */
fromEp->busy = CY_IPC_PIPE_ENDPOINT_BUSY;
/* Setup release callback function */
fromEp->releaseCallbackPtr = callBackPtr;
/* Cause notify event/interrupt */
Cy_IPC_Drv_AcquireNotify(toEp->ipcPtr, 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 that is called 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.
* If this parameters is NULL current callback will be unregistered.
*
* \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.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_myAcquireCallback
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Pipe_RegisterCallback
*
*******************************************************************************/
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;
cy_stc_ipc_pipe_ep_t * thisEp;
CY_ASSERT_L2(CY_IPC_MAX_ENDPOINTS > epAddr);
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_RegisterCallbackRel
****************************************************************************//**
*
* 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.
* If this parameters is NULL current callback will be unregistered.
*
* \return
* None
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_myDefaultReleaseCallback
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Pipe_RegisterCallbackRel
*
*******************************************************************************/
void Cy_IPC_Pipe_RegisterCallbackRel(uint32_t epAddr, cy_ipc_pipe_relcallback_ptr_t callBackPtr)
{
cy_stc_ipc_pipe_ep_t * endpoint;
CY_ASSERT_L2(CY_IPC_MAX_ENDPOINTS > epAddr);
endpoint = &cy_ipc_pipe_epArray[epAddr];
/* Copy callback function into callback function pointer array */
endpoint->defaultReleaseCallbackPtr = 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
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_myIpcPipeEpArray
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Pipe_ExecCallback
*
*******************************************************************************/
void Cy_IPC_Pipe_ExecCallback(cy_stc_ipc_pipe_ep_t * endpoint)
{
uint32_t *msgPtr = NULL;
uint32_t clientID;
uint32_t shadowIntr;
uint32_t releaseMask = (uint32_t)0;
cy_ipc_pipe_callback_ptr_t callbackPtr;
/* Parameters checking begin */
CY_ASSERT_L1(NULL != endpoint);
CY_ASSERT_L1(NULL != endpoint->ipcPtr);
CY_ASSERT_L1(NULL != endpoint->ipcIntrPtr);
CY_ASSERT_L1(NULL != endpoint->callbackArray);
/* Parameters checking end */
shadowIntr = Cy_IPC_Drv_GetInterruptStatusMasked(endpoint->ipcIntrPtr);
/* Check to make sure the interrupt was a notify interrupt */
if (0ul != Cy_IPC_Drv_ExtractAcquireMask(shadowIntr))
{
/* Clear the notify interrupt. */
Cy_IPC_Drv_ClearInterrupt(endpoint->ipcIntrPtr, CY_IPC_NO_NOTIFICATION, Cy_IPC_Drv_ExtractAcquireMask(shadowIntr));
if ( Cy_IPC_Drv_IsLockAcquired (endpoint->ipcPtr) )
{
/* Extract Client ID */
if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_ReadMsgPtr (endpoint->ipcPtr, (void **)&msgPtr))
{
/* Get release mask */
releaseMask = _FLD2VAL(CY_IPC_PIPE_MSG_RELEASE, *msgPtr);
clientID = _FLD2VAL(CY_IPC_PIPE_MSG_CLIENT, *msgPtr);
/* Make sure client ID is within valid range */
if (endpoint->clientCount > clientID)
{
callbackPtr = endpoint->callbackArray[clientID]; /* Get the callback function */
if (callbackPtr != NULL)
{
callbackPtr(msgPtr); /* Call the function pointer for "clientID" */
}
}
}
/* Must always release the IPC channel */
(void)Cy_IPC_Drv_LockRelease (endpoint->ipcPtr, releaseMask);
}
}
/* Check to make sure the interrupt was a release interrupt */
if (0ul != Cy_IPC_Drv_ExtractReleaseMask(shadowIntr)) /* Check for a Release interrupt */
{
/* Clear the release interrupt */
Cy_IPC_Drv_ClearInterrupt(endpoint->ipcIntrPtr, Cy_IPC_Drv_ExtractReleaseMask(shadowIntr), CY_IPC_NO_NOTIFICATION);
if (endpoint->releaseCallbackPtr != NULL)
{
endpoint->releaseCallbackPtr();
/* Clear the pointer after it was called */
endpoint->releaseCallbackPtr = NULL;
}
else
{
if (endpoint->defaultReleaseCallbackPtr != NULL)
{
endpoint->defaultReleaseCallbackPtr();
}
}
/* Clear the busy flag when release is detected */
endpoint->busy = CY_IPC_PIPE_ENDPOINT_NOTBUSY;
}
(void)Cy_IPC_Drv_GetInterruptStatus(endpoint->ipcIntrPtr);
}
/*******************************************************************************
* Function Name: Cy_IPC_Pipe_EndpointPause
****************************************************************************//**
*
* This function sets the receiver endpoint to paused state.
*
* \param epAddr
* This parameter is the address (or index in the array of endpoint structures)
* that designates the endpoint to pause.
*
* \return
* CY_IPC_PIPE_SUCCESS: Callback registered successfully
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Pipe_EndpointPauseResume
*
*******************************************************************************/
cy_en_ipc_pipe_status_t Cy_IPC_Pipe_EndpointPause(uint32_t epAddr)
{
cy_stc_ipc_pipe_ep_t * endpoint;
CY_ASSERT_L2(CY_IPC_MAX_ENDPOINTS > epAddr);
endpoint = &cy_ipc_pipe_epArray[epAddr];
/* Disable the interrupts */
NVIC_DisableIRQ(endpoint->pipeIntrSrc);
return (CY_IPC_PIPE_SUCCESS);
}
/*******************************************************************************
* Function Name: Cy_IPC_Pipe_EndpointResume
****************************************************************************//**
*
* This function sets the receiver endpoint to active state.
*
* \param epAddr
* This parameter is the address (or index in the array of endpoint structures)
* that designates the endpoint to resume.
*
* \return
* CY_IPC_PIPE_SUCCESS: Callback registered successfully
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Pipe_EndpointPauseResume
*
*******************************************************************************/
cy_en_ipc_pipe_status_t Cy_IPC_Pipe_EndpointResume(uint32_t epAddr)
{
cy_stc_ipc_pipe_ep_t * endpoint;
CY_ASSERT_L2(CY_IPC_MAX_ENDPOINTS > epAddr);
endpoint = &cy_ipc_pipe_epArray[epAddr];
/* Enable the interrupts */
NVIC_EnableIRQ(endpoint->pipeIntrSrc);
return (CY_IPC_PIPE_SUCCESS);
}
/* [] END OF FILE */

View File

@ -0,0 +1,265 @@
/***************************************************************************//**
* \file cy_ipc_pipe.h
* \version 1.10.1
*
* Description:
* IPC Pipe Driver - This header file contains all the function prototypes,
* structure definitions, pipe constants, and pipe endpoint address definitions.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#ifndef CY_IPC_PIPE_H
#define CY_IPC_PIPE_H
/******************************************************************************/
/* Include files */
/******************************************************************************/
#include "ipc/cy_ipc_drv.h"
#include "syslib/cy_syslib.h"
#include "sysint/cy_sysint.h"
/**
* \addtogroup group_ipc_pipe IPC pipes layer (IPC_PIPE)
* \{
* 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.
*
* \defgroup group_ipc_pipe_macros Macros
* Macro definitions are used in the driver
*
* \defgroup group_ipc_pipe_functions Functions
* Functions are used in the driver
*
* \defgroup group_ipc_pipe_data_structures Data Structures
* Data structures are used in the driver
*
* \defgroup group_ipc_pipe_enums Enumerated Types
* Enumerations are used in the driver
* \}
*
*/
/*
* 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 for pipe callback function pointer */
typedef void (* cy_ipc_pipe_callback_ptr_t)(uint32_t * msgPtr);
/** Typedef for a pipe release callback function pointer */
typedef void (* cy_ipc_pipe_relcallback_ptr_t)(void);
/** Typedef for array of callback function pointers */
typedef cy_ipc_pipe_callback_ptr_t *cy_ipc_pipe_callback_array_ptr_t;
/**
* \addtogroup group_ipc_pipe_macros
* \{
*/
/*
* 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_Pos (16UL) /**< Interrupts shift value for endpoint address */
#define CY_IPC_PIPE_CFG_IMASK_Msk (0xFFFF0000UL) /**< Interrupts mask for endpoint address */
#define CY_IPC_PIPE_CFG_INTR_Pos (8UL) /**< IPC Interrupt shift value for endpoint address */
#define CY_IPC_PIPE_CFG_INTR_Msk (0x0000FF00UL) /**< IPC Interrupt mask for endpoint address */
#define CY_IPC_PIPE_CFG_CHAN_Pos (0UL) /**< IPC Channel shift value for endpoint address */
#define CY_IPC_PIPE_CFG_CHAN_Msk (0x000000FFUL) /**< IPC Channel mask for endpoint address */
#define CY_IPC_PIPE_MSG_CLIENT_Msk (0x000000FFul) /**< Client mask for first word of Pipe message */
#define CY_IPC_PIPE_MSG_CLIENT_Pos (0ul) /**< Client shift for first word of Pipe message */
#define CY_IPC_PIPE_MSG_USR_Msk (0x0000FF00ul) /**< User data mask for first word of Pipe message */
#define CY_IPC_PIPE_MSG_USR_Pos (8ul) /**< User data shift for first word of Pipe message */
#define CY_IPC_PIPE_MSG_RELEASE_Msk (0xFFFF0000ul) /**< Mask for message release mask */
#define CY_IPC_PIPE_MSG_RELEASE_Pos (16UL) /**< Shift require to line up mask to LSb */
/** Use to set the busy flag when waiting for a release interrupt */
#define CY_IPC_PIPE_ENDPOINT_BUSY (1UL)
/** Denotes that a release interrupt is not pending */
#define CY_IPC_PIPE_ENDPOINT_NOTBUSY (0UL)
/** \} group_ipc_pipe_macros */
/**
* \addtogroup group_ipc_pipe_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
* send to 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 */
IRQn_Type pipeIntrSrc; /**< Interrupt vector number that includes all endpoints on pipe */
IPC_STRUCT_Type *ipcPtr; /**< Pointer to receive IPC channel ( If ipcPtr == 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 defaultReleaseCallbackPtr; /**< Pointer to default release callback function */
} cy_stc_ipc_pipe_ep_t;
/** The Pipe endpoint configuration structure. */
typedef struct
{
uint32_t ipcNotifierNumber; /**< Notifier */
uint32_t ipcNotifierPriority; /**< Notifier Priority */
uint32_t ipcNotifierMuxNumber; /**< CM0+ interrupt multiplexer number */
uint32_t epAddress; /**< Index in the array of endpoint structure */
uint32_t epConfig; /**< Configuration mask, contains IPC channel, IPC interrupt number,
and the interrupt mask */
} cy_stc_ipc_pipe_ep_config_t;
/** The Pipe channel configuration structure. */
typedef struct
{
/** Specifies the notify interrupt number for the first endpoint */
cy_stc_ipc_pipe_ep_config_t ep0ConfigData;
/** Specifies the notify interrupt number for the second endpoint */
cy_stc_ipc_pipe_ep_config_t ep1ConfigData;
/** Client count and size of MsgCallback array */
uint32_t endpointClientsCount;
/** Pipes callback function array. */
cy_ipc_pipe_callback_array_ptr_t endpointsCallbacksArray;
/** User IRQ handler function that is called when IPC receive data to process (interrupt was raised). */
cy_israddress userPipeIsrHandler;
} cy_stc_ipc_pipe_config_t;
/** \} goup_ipc_pipe_data_structures */
/**
* \addtogroup group_ipc_pipe_macros
* \{
*/
/* 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 */
/** \} group_ipc_pipe_macros */
/**
* \addtogroup group_ipc_pipe_enums
* \{
*/
/** 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_pipe_enums */
/**
* \addtogroup group_ipc_pipe_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_pipe_data_structures */
/******************************************************************************/
/* Global function prototypes (definition in C source) */
/******************************************************************************/
/**
* \addtogroup group_ipc_pipe_functions
* \{
*/
#ifdef __cplusplus
extern "C" {
#endif
void Cy_IPC_Pipe_EndpointInit(uint32_t epAddr, cy_ipc_pipe_callback_array_ptr_t cbArray,
uint32_t cbCnt, uint32_t epConfig, cy_stc_sysint_t const *epInterrupt);
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 Cy_IPC_Pipe_RegisterCallback(uint32_t epAddr,
cy_ipc_pipe_callback_ptr_t callBackPtr, 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 callBackPtr);
void Cy_IPC_Pipe_Config(cy_stc_ipc_pipe_ep_t * theEpArray);
void Cy_IPC_Pipe_Init(cy_stc_ipc_pipe_config_t const *config);
cy_en_ipc_pipe_status_t Cy_IPC_Pipe_EndpointPause(uint32_t epAddr);
cy_en_ipc_pipe_status_t Cy_IPC_Pipe_EndpointResume(uint32_t epAddr);
#ifdef __cplusplus
}
#endif
/** \} group_ipc_pipe_functions */
#endif /* CY_IPC_PIPE_H */
/* [] END OF FILE */

View File

@ -0,0 +1,392 @@
/***************************************************************************//**
* \file cy_ipc_sema.c
* \version 1.10.1
*
* Description:
* IPC Semaphore Driver - This source file contains the source code for the
* semaphore level APIs for the IPC interface.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "ipc/cy_ipc_drv.h"
#include "ipc/cy_ipc_sema.h"
#include "syslib/cy_syslib.h"
#include <string.h> /* The memset() definition */
/* Defines a mask to Check if semaphore count is a multiple of 32 */
#define CY_IPC_SEMA_PER_WORD_MASK (CY_IPC_SEMA_PER_WORD - 1ul)
/* Pointer to IPC structure used for semaphores */
static IPC_STRUCT_Type* cy_semaIpcStruct;
/*
* Internal IPC semaphore control data structure.
*/
typedef struct
{
uint32_t maxSema; /* Maximum semaphores in system */
uint32_t *arrayPtr; /* Pointer to semaphores array */
} cy_stc_ipc_sema_t;
/*******************************************************************************
* Function Name: Cy_IPC_Sema_Init
****************************************************************************//**
*
* This function initializes the semaphores subsystem. The user must create an
* array of unsigned 32-bit words to hold the semaphore bits. The number
* of semaphores will be the size of the array * 32. The total semaphores count
* will always be a multiple of 32.
*
* \note In a multi-CPU system this init function should be called with all
* initialized parameters on one CPU only to provide a pointer to SRAM that can
* be shared between all the CPUs in the system that will use semaphores.
* On other CPUs user must specify the IPC semaphores channel and pass 0 / NULL
* to count and memPtr parameters correspondingly.
*
* \param ipcChannel
* The IPC channel number used for semaphores
*
* \param count
* The maximum number of semaphores to be supported (multiple of 32).
*
* \param memPtr
* This points to the array of (count/32) words that contain the semaphore data.
*
* \return Status of the operation
* \retval CY_IPC_SEMA_SUCCESS: Successfully initialized
* \retval CY_IPC_SEMA_BAD_PARAM: Memory pointer is NULL and count is not zero,
* or count not multiple of 32
* \retval CY_IPC_SEMA_ERROR_LOCKED: Could not acquire semaphores IPC channel
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Sema_Init
*
*******************************************************************************/
cy_en_ipcsema_status_t Cy_IPC_Sema_Init(uint32_t ipcChannel,
uint32_t count, uint32_t memPtr[])
{
/* Structure containing semaphores control data */
static cy_stc_ipc_sema_t cy_semaData;
cy_en_ipcsema_status_t retStatus = CY_IPC_SEMA_BAD_PARAM;
if (ipcChannel >= CY_IPC_CHANNELS)
{
retStatus = CY_IPC_SEMA_BAD_PARAM;
}
else
{
if( (NULL == memPtr) && (0u == count))
{
cy_semaIpcStruct = Cy_IPC_Drv_GetIpcBaseAddress(ipcChannel);
retStatus = CY_IPC_SEMA_SUCCESS;
}
/* Check for non Null pointers and count value */
else if ((NULL != memPtr) && (0u != count))
{
/* Check if semaphore count is a multiple of 32 */
if( 0ul == (count & CY_IPC_SEMA_PER_WORD_MASK))
{
cy_semaIpcStruct = Cy_IPC_Drv_GetIpcBaseAddress(ipcChannel);
cy_semaData.maxSema = count;
cy_semaData.arrayPtr = memPtr;
/* Initialize all semaphores to released */
(void)memset(cy_semaData.arrayPtr, 0, (count /8u));
/* Make sure semaphores start out released. */
/* Ignore the return value since it is OK if it was already released. */
(void) Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION);
/* Set the IPC Data with the pointer to the array. */
if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_SendMsgPtr (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION, &cy_semaData))
{
if(CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION))
{
retStatus = CY_IPC_SEMA_SUCCESS;
}
else
{
/* IPC channel not released, still semaphored */
retStatus = CY_IPC_SEMA_ERROR_LOCKED;
}
}
else
{
/* Could not acquire semaphore channel */
retStatus = CY_IPC_SEMA_ERROR_LOCKED;
}
}
else
{
retStatus = CY_IPC_SEMA_BAD_PARAM;
}
}
else
{
retStatus = CY_IPC_SEMA_BAD_PARAM;
}
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Sema_Set
****************************************************************************//**
*
* This function tries to acquire a semaphore. If the
* semaphore is not available, this function returns immediately with
* CY_IPC_SEMA_LOCKED.
*
* It first acquires the IPC channel that is used for all the semaphores, sets
* the semaphore if it is cleared, then releases the IPC channel used for the
* semaphore.
*
* \param semaNumber
* The semaphore number to acquire.
*
* \param preemptable
* When this parameter is enabled the function can be preempted by another
* task or other forms of context switching in an RTOS environment.
*
* \note
* If <b>preemptable</b> is enabled (true), the user must ensure that there are
* no deadlocks in the system, which can be caused by an interrupt that occurs
* after the IPC channel is locked. Unless the user is ready to handle IPC
* channel locks correctly at the application level, set <b>premptable</b> to
* false.
*
* \return Status of the operation
* \retval CY_IPC_SEMA_SUCCESS: The semaphore was set successfully
* \retval CY_IPC_SEMA_LOCKED: The semaphore channel is busy or locked
* by another process
* \retval CY_IPC_SEMA_NOT_ACQUIRED: Semaphore was already set
* \retval CY_IPC_SEMA_OUT_OF_RANGE: The semaphore number is not valid
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Sema_Set
*
*******************************************************************************/
cy_en_ipcsema_status_t Cy_IPC_Sema_Set(uint32_t semaNumber, bool preemptable)
{
uint32_t semaIndex;
uint32_t semaMask;
uint32_t interruptState = 0ul;
cy_stc_ipc_sema_t *semaStruct;
cy_en_ipcsema_status_t retStatus = CY_IPC_SEMA_LOCKED;
/* Get pointer to structure */
semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
if (semaNumber < semaStruct->maxSema)
{
semaIndex = semaNumber / CY_IPC_SEMA_PER_WORD;
semaMask = (uint32_t)(1ul << (semaNumber - (semaIndex * CY_IPC_SEMA_PER_WORD) ));
if (!preemptable)
{
interruptState = Cy_SysLib_EnterCriticalSection();
}
/* Check to make sure the IPC channel is released
If so, check if specific channel can be locked. */
if(CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire (cy_semaIpcStruct))
{
if((semaStruct->arrayPtr[semaIndex] & semaMask) == 0ul)
{
semaStruct->arrayPtr[semaIndex] |= semaMask;
retStatus = CY_IPC_SEMA_SUCCESS;
}
else
{
retStatus = CY_IPC_SEMA_NOT_ACQUIRED;
}
/* Release, but do not trigger a release event */
(void) Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION);
}
if (!preemptable)
{
Cy_SysLib_ExitCriticalSection(interruptState);
}
}
else
{
retStatus = CY_IPC_SEMA_OUT_OF_RANGE;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Sema_Clear
****************************************************************************//**
*
* This functions tries to releases a semaphore.
*
* It first acquires the IPC channel that is used for all the semaphores, clears
* the semaphore if it is set, then releases the IPC channel used for the
* semaphores.
*
* \param semaNumber
* The index of the semaphore to release.
*
* \param preemptable
* When this parameter is enabled the function can be preempted by another
* task or other forms of context switching in an RTOS environment.
*
* \note
* If <b>preemptable</b> is enabled (true), the user must ensure that there are
* no deadlocks in the system, which can be caused by an interrupt that occurs
* after the IPC channel is locked. Unless the user is ready to handle IPC
* channel locks correctly at the application level, set <b>premptable</b> to
* false.
*
* \return Status of the operation
* \retval CY_IPC_SEMA_SUCCESS: The semaphore was cleared successfully
* \retval CY_IPC_SEMA_NOT_ACQUIRED: The semaphore was already cleared
* \retval CY_IPC_SEMA_LOCKED: The semaphore channel was semaphored or busy
* \retval CY_IPC_SEMA_OUT_OF_RANGE: The semaphore number is not valid
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Sema_Clear
*
*******************************************************************************/
cy_en_ipcsema_status_t Cy_IPC_Sema_Clear(uint32_t semaNumber, bool preemptable)
{
uint32_t semaIndex;
uint32_t semaMask;
uint32_t interruptState = 0ul;
cy_stc_ipc_sema_t *semaStruct;
cy_en_ipcsema_status_t retStatus = CY_IPC_SEMA_LOCKED;
/* Get pointer to structure */
semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
if (semaNumber < semaStruct->maxSema)
{
semaIndex = semaNumber / CY_IPC_SEMA_PER_WORD;
semaMask = (uint32_t)(1ul << (semaNumber - (semaIndex * CY_IPC_SEMA_PER_WORD) ));
if (!preemptable)
{
interruptState = Cy_SysLib_EnterCriticalSection();
}
/* Check to make sure the IPC channel is released
If so, check if specific channel can be locked. */
if(CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire (cy_semaIpcStruct))
{
if((semaStruct->arrayPtr[semaIndex] & semaMask) != 0ul)
{
semaStruct->arrayPtr[semaIndex] &= ~semaMask;
retStatus = CY_IPC_SEMA_SUCCESS;
}
else
{
retStatus = CY_IPC_SEMA_NOT_ACQUIRED;
}
/* Release, but do not trigger a release event */
(void) Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION);
}
if (!preemptable)
{
Cy_SysLib_ExitCriticalSection(interruptState);
}
}
else
{
retStatus = CY_IPC_SEMA_OUT_OF_RANGE;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Sema_Status
****************************************************************************//**
*
* This function returns the status of the semaphore.
*
* \param semaNumber
* The index of the semaphore to return status.
*
* \return Status of the operation
* \retval CY_IPC_SEMA_STATUS_LOCKED: The semaphore is in the set state.
* \retval CY_IPC_SEMA_STATUS_UNLOCKED: The semaphore is in the cleared state.
* \retval CY_IPC_SEMA_OUT_OF_RANGE: The semaphore number is not valid
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Sema_Status
*
*******************************************************************************/
cy_en_ipcsema_status_t Cy_IPC_Sema_Status(uint32_t semaNumber)
{
cy_en_ipcsema_status_t retStatus;
uint32_t semaIndex;
uint32_t semaMask;
cy_stc_ipc_sema_t *semaStruct;
/* Get pointer to structure */
semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
if (semaNumber < semaStruct->maxSema)
{
/* Get the index into the semaphore array and calculate the mask */
semaIndex = semaNumber / CY_IPC_SEMA_PER_WORD;
semaMask = (uint32_t)(1ul << (semaNumber - (semaIndex * CY_IPC_SEMA_PER_WORD) ));
if((semaStruct->arrayPtr[semaIndex] & semaMask) != 0ul)
{
retStatus = CY_IPC_SEMA_STATUS_LOCKED;
}
else
{
retStatus = CY_IPC_SEMA_STATUS_UNLOCKED;
}
}
else
{
retStatus = CY_IPC_SEMA_OUT_OF_RANGE;
}
return(retStatus);
}
/*******************************************************************************
* Function Name: Cy_IPC_Sema_GetMaxSems
****************************************************************************//**
*
* This function returns the number of semaphores in the semaphores subsystem.
*
* \return
* Returns the semaphores quantity.
*
* \funcusage
* \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Sema_GetMaxSems
*
*******************************************************************************/
uint32_t Cy_IPC_Sema_GetMaxSems(void)
{
cy_stc_ipc_sema_t *semaStruct;
/* Get pointer to structure */
semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
return (semaStruct->maxSema);
}
/* [] END OF FILE */

View File

@ -0,0 +1,114 @@
/***************************************************************************//**
* \file cy_ipc_sema.h
* \version 1.10.1
*
* \brief
* Header file for IPC SEM functions
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#ifndef CY_IPC_SEMA_H
#define CY_IPC_SEMA_H
/******************************************************************************/
/* Include files */
/******************************************************************************/
#include "cy_ipc_drv.h"
#include <stdbool.h>
/**
* \addtogroup group_ipc_sema IPC semaphores layer (IPC_SEMA)
* \{
* The semaphores layer functions made use of a single IPC channel to allow
* multiple semaphores that can be used by system or user function calls.
* By default there are 128 semaphores provided, although the user may modify
* the default value to any number, limited only by SRAM.
*
* \defgroup group_ipc_sema_macros Macros
* Macro definitions are used in the driver
*
* \defgroup group_ipc_sema_functions Functions
* Functions are used in the driver
*
* \defgroup group_ipc_sema_enums Enumerated Types
* Enumerations are used in the driver
* \}
*
* \addtogroup group_ipc_sema_macros
* \{
*/
/** Software PDL driver ID for IPC semaphore functions */
#define CY_IPC_SEMA_RTN (0x0100ul)
/** Return prefix for IPC semaphore function status codes */
#define CY_IPC_SEMA_ID_INFO (uint32_t)( CY_IPC_ID_INFO | CY_IPC_SEMA_RTN)
/** Return prefix for IPC semaphore function warning return values */
#define CY_IPC_SEMA_ID_WARNING (uint32_t)( CY_IPC_ID_WARNING | CY_IPC_SEMA_RTN)
/** Return prefix for IPC semaphore function error return values */
#define CY_IPC_SEMA_ID_ERROR (uint32_t)( CY_IPC_ID_ERROR | CY_IPC_SEMA_RTN)
#define CY_IPC_SEMA_PER_WORD (uint32_t)32u /**< 32 semaphores per word */
/** \} group_ipc_sema_macros */
/**
* \addtogroup group_ipc_sema_enums
* \{
*/
/** Return constants for IPC semaphores functions. */
typedef enum
{
/** No error has occurred */
CY_IPC_SEMA_SUCCESS = (uint32_t)(0ul),
/** Semaphores IPC channel has already been locked */
CY_IPC_SEMA_ERROR_LOCKED = (uint32_t)(CY_IPC_SEMA_ID_ERROR | 1ul),
/** Semaphores IPC channel is unlocked */
CY_IPC_SEMA_ERROR_UNLOCKED = (uint32_t)(CY_IPC_SEMA_ID_ERROR | 2ul),
/** Semaphore API bad parameter */
CY_IPC_SEMA_BAD_PARAM = (uint32_t)(CY_IPC_SEMA_ID_ERROR | 3ul),
/** Semaphore API return when semaphore number is out of the range */
CY_IPC_SEMA_OUT_OF_RANGE = (uint32_t)(CY_IPC_SEMA_ID_ERROR | 4ul),
/** Semaphore API return when IPC channel was not acquired */
CY_IPC_SEMA_NOT_ACQUIRED = (uint32_t)(CY_IPC_SEMA_ID_INFO | 2ul),
/** Semaphore API return status when semaphore channel is busy or locked
* by another process */
CY_IPC_SEMA_LOCKED = (uint32_t)(CY_IPC_SEMA_ID_INFO | 3ul),
/** Semaphore status return that the semaphore is set */
CY_IPC_SEMA_STATUS_LOCKED = (uint32_t)(CY_IPC_SEMA_ID_INFO | 1ul),
/** Semaphore status return that the semaphore is cleared */
CY_IPC_SEMA_STATUS_UNLOCKED = (uint32_t)(CY_IPC_SEMA_ID_INFO | 0ul)
} cy_en_ipcsema_status_t;
/** \} group_ipc_sema_enums */
/**
* \addtogroup group_ipc_sema_functions
* \{
*/
#ifdef __cplusplus
extern "C" {
#endif
cy_en_ipcsema_status_t Cy_IPC_Sema_Init (uint32_t ipcChannel, uint32_t count, uint32_t memPtr[]);
cy_en_ipcsema_status_t Cy_IPC_Sema_Set (uint32_t semaNumber, bool preemptable);
cy_en_ipcsema_status_t Cy_IPC_Sema_Clear (uint32_t semaNumber, bool preemptable);
cy_en_ipcsema_status_t Cy_IPC_Sema_Status (uint32_t semaNumber);
uint32_t Cy_IPC_Sema_GetMaxSems(void);
#ifdef __cplusplus
}
#endif
/** \} group_ipc_sema_functions */
#endif /* CY_IPC_SEMA_H */
/* [] END OF FILE */

View File

@ -0,0 +1,627 @@
/*******************************************************************************
* \file cy_lpcomp.c
* \version 1.10.1
*
* \brief
* This file provides the driver code to the API for the Low Power Comparator
* component.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "cy_lpcomp.h"
#if defined(__cplusplus)
extern "C" {
#endif
static cy_stc_lpcomp_context_t cy_lpcomp_context;
/*******************************************************************************
* Function Name: Cy_LPComp_Init
****************************************************************************//**
*
* Initializes LPCOMP and returns the LPCOMP register address.
*
* \param *base
* LPCOMP registers structure pointer.
*
* \param *config
* The pointer to the configuration structure for PDL.
*
* \param channel
* The LPCOMP channel index.
*
* \return cy_en_lpcomp_status_t
* *base checking result. If the pointer is NULL, returns error.
*
*******************************************************************************/
cy_en_lpcomp_status_t Cy_LPComp_Init(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel, const cy_stc_lpcomp_config_t* config)
{
cy_en_lpcomp_status_t ret = CY_LPCOMP_BAD_PARAM;
CY_ASSERT_L3(CY_LPCOMP_IS_CHANNEL_VALID(channel));
CY_ASSERT_L3(CY_LPCOMP_IS_OUT_MODE_VALID(config->outputMode));
CY_ASSERT_L3(CY_LPCOMP_IS_HYSTERESIS_VALID(config->hysteresis));
CY_ASSERT_L3(CY_LPCOMP_IS_POWER_VALID(config->power));
CY_ASSERT_L3(CY_LPCOMP_IS_INTR_MODE_VALID(config->intType));
if ((base != NULL) && (config != NULL))
{
Cy_LPComp_GlobalEnable(base);
if (CY_LPCOMP_CHANNEL_0 == channel)
{
base->CMP0_CTRL = _VAL2FLD(LPCOMP_CMP0_CTRL_HYST0, (uint32_t)config->hysteresis) |
_VAL2FLD(LPCOMP_CMP0_CTRL_DSI_BYPASS0, (uint32_t)config->outputMode) |
_VAL2FLD(LPCOMP_CMP0_CTRL_DSI_LEVEL0, (uint32_t)config->outputMode >> 1u);
}
else
{
base->CMP1_CTRL = _VAL2FLD(LPCOMP_CMP1_CTRL_HYST1, (uint32_t)config->hysteresis) |
_VAL2FLD(LPCOMP_CMP1_CTRL_DSI_BYPASS1, (uint32_t)config->outputMode) |
_VAL2FLD(LPCOMP_CMP1_CTRL_DSI_LEVEL1, (uint32_t)config->outputMode >> 1u);
}
/* Save intType to use it in the Cy_LPComp_Enable() function */
cy_lpcomp_context.intType[(uint8_t)channel - 1u] = config->intType;
/* Save power to use it in the Cy_LPComp_Enable() function */
cy_lpcomp_context.power[(uint8_t)channel - 1u] = config->power;
ret = CY_LPCOMP_SUCCESS;
}
return (ret);
}
/*******************************************************************************
* Function Name: Cy_LPComp_Enable
****************************************************************************//**
*
* Enables the LPCOMP and sets the LPCOMP interrupt mode.
*
* \param *base
* The LPCOMP register structure pointer.
*
* \param channel
* The LPCOMP channel index.
*
* \return None
*
*******************************************************************************/
void Cy_LPComp_Enable(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel)
{
cy_en_lpcomp_pwr_t powerSpeed;
CY_ASSERT_L3(CY_LPCOMP_IS_CHANNEL_VALID(channel));
powerSpeed = cy_lpcomp_context.power[(uint8_t)channel - 1u];
/* Set power */
Cy_LPComp_SetPower(base, channel, powerSpeed);
/* Make delay before enabling the comparator interrupt to prevent false triggering */
if (CY_LPCOMP_MODE_ULP == powerSpeed)
{
Cy_SysLib_DelayUs(CY_LPCOMP_ULP_POWER_DELAY);
}
else if (CY_LPCOMP_MODE_LP == powerSpeed)
{
Cy_SysLib_DelayUs(CY_LPCOMP_LP_POWER_DELAY);
}
else
{
Cy_SysLib_DelayUs(CY_LPCOMP_NORMAL_POWER_DELAY);
}
/* Enable the comparator interrupt */
Cy_LPComp_SetInterruptTriggerMode(base, channel, cy_lpcomp_context.intType[(uint8_t)channel - 1u]);
}
/*******************************************************************************
* Function Name: Cy_LPComp_Disable
****************************************************************************//**
*
* Disables the LPCOMP power and sets the interrupt mode to disabled.
*
* \param *base
* The LPCOMP register structure pointer.
*
* \param channel
* The LPCOMP channel index.
*
* \return None
*
*******************************************************************************/
void Cy_LPComp_Disable(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel)
{
CY_ASSERT_L3(CY_LPCOMP_IS_CHANNEL_VALID(channel));
/* Disable the comparator interrupt */
Cy_LPComp_SetInterruptTriggerMode(base, channel, CY_LPCOMP_INTR_DISABLE);
/* Set power off */
Cy_LPComp_SetPower(base, channel, CY_LPCOMP_MODE_OFF);
}
/*******************************************************************************
* Function Name: Cy_LPComp_SetInterruptTriggerMode
****************************************************************************//**
*
* Sets the interrupt edge-detect mode.
* This also controls the value provided on the output.
* \note Interrupts can be enabled after the block is enabled and the appropriate
* start-up time has elapsed:
* 3 us for the normal power mode;
* 6 us for the LP mode;
* 50 us for the ULP mode.
*
* \param *base
* The LPCOMP register structure pointer.
*
* \param channel
* The LPCOMP channel index.
*
* \param intType
* Interrupt edge trigger selection
* CY_LPCOMP_INTR_DISABLE (=0) - Disabled, no interrupt will be detected
* CY_LPCOMP_INTR_RISING (=1) - Rising edge
* CY_LPCOMP_INTR_FALLING (=2) - Falling edge
* CY_LPCOMP_INTR_BOTH (=3) - Both rising and falling edges.
*
* \return None
*
*******************************************************************************/
void Cy_LPComp_SetInterruptTriggerMode(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel, cy_en_lpcomp_int_t intType)
{
CY_ASSERT_L3(CY_LPCOMP_IS_CHANNEL_VALID(channel));
CY_ASSERT_L3(CY_LPCOMP_IS_INTR_MODE_VALID(intType));
if (CY_LPCOMP_CHANNEL_0 == channel)
{
base->CMP0_CTRL = _CLR_SET_FLD32U(base->CMP0_CTRL, LPCOMP_CMP0_CTRL_INTTYPE0, (uint32_t)intType);
}
else
{
base->CMP1_CTRL = _CLR_SET_FLD32U(base->CMP1_CTRL, LPCOMP_CMP1_CTRL_INTTYPE1, (uint32_t)intType);
}
/* Save interrupt type to use it in the Cy_LPComp_Enable() function */
cy_lpcomp_context.intType[(uint8_t)channel - 1u] = intType;
}
/*******************************************************************************
* Function Name: Cy_LPComp_SetPower
****************************************************************************//**
*
* Sets the drive power and speeds to one of the four settings.
* \note Interrupts can be enabled after the block is enabled and the appropriate
* start-up time has elapsed:
* 3 us for the normal power mode;
* 6 us for the LP mode;
* 50 us for the ULP mode.
* Otherwise, unexpected interrupts events can occur.
*
* \param *base
* The LPCOMP register structure pointer.
*
* \param channel
* The LPCOMP channel index.
*
* \param power
* The power setting sets an operation mode of the component:
* CY_LPCOMP_OFF_POWER (=0) - Off power
* CY_LPCOMP_MODE_ULP (=1) - Slow/ultra low power
* CY_LPCOMP_MODE_LP (=2) - Medium/low power
* CY_LPCOMP_MODE_NORMAL(=3) - Fast/normal power
*
* \return None
*
*******************************************************************************/
void Cy_LPComp_SetPower(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel, cy_en_lpcomp_pwr_t power)
{
CY_ASSERT_L3(CY_LPCOMP_IS_CHANNEL_VALID(channel));
CY_ASSERT_L3(CY_LPCOMP_IS_POWER_VALID(power));
if (CY_LPCOMP_CHANNEL_0 == channel)
{
base->CMP0_CTRL = _CLR_SET_FLD32U(base->CMP0_CTRL, LPCOMP_CMP0_CTRL_MODE0, (uint32_t)power);
}
else
{
base->CMP1_CTRL = _CLR_SET_FLD32U(base->CMP1_CTRL, LPCOMP_CMP1_CTRL_MODE1, (uint32_t)power);
}
}
/*******************************************************************************
* Function Name: Cy_LPComp_SetHysteresis
****************************************************************************//**
*
* Adds the 30mV hysteresis to the comparator.
*
* \param *base
* The LPCOMP register structure pointer.
*
* \param channel
* The LPCOMP channel index.
*
* \param hysteresis
* Sets an operation mode of the component
* CY_LPCOMP_HYST_ENABLE (=1) - Enables HYST
* CY_LPCOMP_HYST_DISABLE(=0) - Disable HYST.
*
* \return None
*
*******************************************************************************/
void Cy_LPComp_SetHysteresis(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel, cy_en_lpcomp_hyst_t hysteresis)
{
CY_ASSERT_L3(CY_LPCOMP_IS_CHANNEL_VALID(channel));
CY_ASSERT_L3(CY_LPCOMP_IS_HYSTERESIS_VALID(hysteresis));
if (CY_LPCOMP_CHANNEL_0 == channel)
{
base->CMP0_CTRL = _CLR_SET_FLD32U(base->CMP0_CTRL, LPCOMP_CMP0_CTRL_HYST0, (uint32_t)hysteresis);
}
else
{
base->CMP1_CTRL = _CLR_SET_FLD32U(base->CMP1_CTRL , LPCOMP_CMP1_CTRL_HYST1, (uint32_t)hysteresis);
}
}
/*******************************************************************************
* Function Name: Cy_LPComp_SetInputs
****************************************************************************//**
*
* Sets the comparator input sources. The comparator inputs can be connected
* to the dedicated GPIO pins or AMUXBUSA/AMUXBUSB. Additionally, the negative
* comparator input can be connected to the local VREF.
* At least one unconnected input causes a comparator undefined output.
*
* \note Connection to AMUXBUSA/AMUXBUSB requires closing the additional
* switches which are a part of the IO system. These switches can be configured
* using the HSIOM->AMUX_SPLIT_CTL[3] register.
* Refer to the appropriate Technical Reference Manual (TRM) of a device
* for a detailed description.
*
* \param *base
* The LPCOMP register structure pointer.
*
* \param channel
* The LPCOMP channel index.
*
* \param inputP
* Positive input selection
* CY_LPCOMP_SW_GPIO (0x01u)
* CY_LPCOMP_SW_AMUXBUSA (0x02u) - Hi-Z in hibernate mode
* CY_LPCOMP_SW_AMUXBUSB (0x04u) - Hi-Z in the hibernate mode.
*
* \param inputN
* Negative input selection
* CY_LPCOMP_SW_GPIO (0x01u)
* CY_LPCOMP_SW_AMUXBUSA (0x02u) - Hi-Z in hibernate mode
* CY_LPCOMP_SW_AMUXBUSB (0x04u) - Hi-Z in hibernate mode
* CY_LPCOMP_SW_LOCAL_VREF (0x08u) - the negative input only for a crude REF.
*
* \return None
*
*******************************************************************************/
void Cy_LPComp_SetInputs(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel, cy_en_lpcomp_inputs_t inputP, cy_en_lpcomp_inputs_t inputN)
{
uint32_t input;
CY_ASSERT_L3(CY_LPCOMP_IS_CHANNEL_VALID(channel));
CY_ASSERT_L3(CY_LPCOMP_IS_INPUT_P_VALID(inputP));
CY_ASSERT_L3(CY_LPCOMP_IS_INPUT_N_VALID(inputN));
switch(inputP)
{
case CY_LPCOMP_SW_AMUXBUSA:
{
input = (channel == CY_LPCOMP_CHANNEL_0) ? LPCOMP_CMP0_SW_CMP0_AP0_Msk : LPCOMP_CMP1_SW_CMP1_AP1_Msk;
HSIOM->AMUX_SPLIT_CTL[3] = _CLR_SET_FLD32U(HSIOM->AMUX_SPLIT_CTL[3], CY_HSIOM_AMUX_SPLIT_CTL_SWITCH_AA_SL_SR, 3u);
break;
}
case CY_LPCOMP_SW_AMUXBUSB:
{
input = (channel == CY_LPCOMP_CHANNEL_0) ? LPCOMP_CMP0_SW_CMP0_BP0_Msk : LPCOMP_CMP1_SW_CMP1_BP1_Msk;
HSIOM->AMUX_SPLIT_CTL[3] = _CLR_SET_FLD32U(HSIOM->AMUX_SPLIT_CTL[3], CY_HSIOM_AMUX_SPLIT_CTL_SWITCH_BB_SL_SR, 3u);
break;
}
default:
{
input = (channel == CY_LPCOMP_CHANNEL_0) ? LPCOMP_CMP0_SW_CMP0_IP0_Msk : LPCOMP_CMP1_SW_CMP1_IP1_Msk;
break;
}
}
switch(inputN)
{
case CY_LPCOMP_SW_AMUXBUSA:
{
input |= (channel == CY_LPCOMP_CHANNEL_0) ? LPCOMP_CMP0_SW_CMP0_AN0_Msk : LPCOMP_CMP1_SW_CMP1_AN1_Msk;
HSIOM->AMUX_SPLIT_CTL[3] = _CLR_SET_FLD32U(HSIOM->AMUX_SPLIT_CTL[3], CY_HSIOM_AMUX_SPLIT_CTL_SWITCH_AA_SL_SR, 3u);
break;
}
case CY_LPCOMP_SW_AMUXBUSB:
{
input |= (channel == CY_LPCOMP_CHANNEL_0) ? LPCOMP_CMP0_SW_CMP0_BN0_Msk : LPCOMP_CMP1_SW_CMP1_BN1_Msk;
HSIOM->AMUX_SPLIT_CTL[3] = _CLR_SET_FLD32U(HSIOM->AMUX_SPLIT_CTL[3], CY_HSIOM_AMUX_SPLIT_CTL_SWITCH_BB_SL_SR, 3u);
break;
}
case CY_LPCOMP_SW_LOCAL_VREF:
{
input |= (channel == CY_LPCOMP_CHANNEL_0) ? LPCOMP_CMP0_SW_CMP0_VN0_Msk : LPCOMP_CMP1_SW_CMP1_VN1_Msk;
break;
}
default:
{
input |= (channel == CY_LPCOMP_CHANNEL_0) ? LPCOMP_CMP0_SW_CMP0_IN0_Msk : LPCOMP_CMP1_SW_CMP1_IN1_Msk;
break;
}
}
if (CY_LPCOMP_CHANNEL_0 == channel)
{
base->CMP0_SW_CLEAR = CY_LPCOMP_CMP0_SW_POS_Msk | CY_LPCOMP_CMP0_SW_NEG_Msk;
base->CMP0_SW = input;
}
else
{
base->CMP1_SW_CLEAR = CY_LPCOMP_CMP1_SW_POS_Msk | CY_LPCOMP_CMP1_SW_NEG_Msk;
base->CMP1_SW = input;
}
}
/*******************************************************************************
* Function Name: Cy_LPComp_SetOutputMode
****************************************************************************//**
*
* Sets the type of the comparator DSI output.
*
* \param *base
* The LPCOMP register structure pointer.
*
* \param channel
* The LPCOMP channel index.
*
* \param outType
* Interrupt edge trigger selection
* CY_LPCOMP_OUT_PULSE (=0) - the DSI output with the pulse option, no bypass
* CY_LPCOMP_OUT_DIRECT (=1) - the bypass mode, the direct output of the comparator
* CY_LPCOMP_OUT_SYNC (=2) - DSI output with the level option, it is similar to the
* bypass mode but it is 1 cycle slow than the bypass.
* [DSI_LEVELx : DSI_BYPASSx] = [Bit11 : Bit10]
* 0 : 0 = 0x00 -> Pulse (PULSE)
* 1 : 0 = 0x02 -> Level (SYNC)
* x : 1 = 0x01 -> Bypass (Direct).
*
* \return None
*
*******************************************************************************/
void Cy_LPComp_SetOutputMode(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel, cy_en_lpcomp_out_t outType)
{
CY_ASSERT_L3(CY_LPCOMP_IS_CHANNEL_VALID(channel));
CY_ASSERT_L3(CY_LPCOMP_IS_OUT_MODE_VALID(outType));
if (CY_LPCOMP_CHANNEL_0 == channel)
{
base->CMP0_CTRL = _CLR_SET_FLD32U(base->CMP0_CTRL, CY_LPCOMP_CMP0_OUTPUT_CONFIG, (uint32_t)outType);
}
else
{
base->CMP1_CTRL = _CLR_SET_FLD32U(base->CMP1_CTRL, CY_LPCOMP_CMP1_OUTPUT_CONFIG, (uint32_t)outType);
}
}
/*******************************************************************************
* Function Name: Cy_LPComp_DeepSleepCallback
****************************************************************************//**
*
* This function checks the current power mode of LPComp and then disables the
* LPComp block if there is no wake-up source from LPComp in the deep-sleep mode.
* It stores the state of the LPComp enable and then disables the LPComp block
* before going to the low power modes, and recovers the LPComp power state after
* wake-up using the stored value.
*
* \param *callbackParams
* The \ref cy_stc_syspm_callback_params_t structure with the callback
* parameters which consists of mode, base and context fields:
* *base - LPComp register structure pointer;
* *context - Context for the call-back function;
* mode
* CY_SYSPM_CHECK_READY - No action for this state.
* CY_SYSPM_CHECK_FAIL - No action for this state.
* CY_SYSPM_BEFORE_TRANSITION - Checks the LPComp interrupt mask and the power
* mode, and then disables or enables the LPComp block
* according to the condition.
* Stores the LPComp state to recover the state after
* wake up.
* CY_SYSPM_AFTER_TRANSITION - Enables the LPComp block, if it was disabled
* before the sleep mode.
*
* \return
* \ref cy_en_syspm_status_t
*
*******************************************************************************/
cy_en_syspm_status_t Cy_LPComp_DeepSleepCallback(cy_stc_syspm_callback_params_t *callbackParams)
{
cy_en_syspm_status_t ret = CY_SYSPM_FAIL;
LPCOMP_Type *locBase = (LPCOMP_Type *) (callbackParams->base);
static uint32_t enabled_status;
switch(callbackParams->mode)
{
case CY_SYSPM_CHECK_READY:
{
ret = CY_SYSPM_SUCCESS;
}
break;
case CY_SYSPM_CHECK_FAIL:
{
ret = CY_SYSPM_SUCCESS;
}
break;
case CY_SYSPM_BEFORE_TRANSITION:
{
/* Save the LPComp the enabled/disabled status. */
enabled_status = _FLD2VAL(LPCOMP_CONFIG_ENABLED, locBase->CONFIG);
if (0u != enabled_status)
{
/* Disable the LPComp block when there is no wake-up source from any channel. */
if( !(((_FLD2VAL(LPCOMP_CMP0_CTRL_MODE0, locBase->CMP0_CTRL) == (uint32_t)CY_LPCOMP_MODE_ULP) &&
_FLD2BOOL(LPCOMP_INTR_MASK_COMP0_MASK, locBase->INTR_MASK)) ||
((_FLD2VAL(LPCOMP_CMP1_CTRL_MODE1, locBase->CMP1_CTRL) == (uint32_t)CY_LPCOMP_MODE_ULP) &&
_FLD2BOOL(LPCOMP_INTR_MASK_COMP1_MASK, locBase->INTR_MASK))) )
{
/* Disable the LPComp block to avoid leakage. */
Cy_LPComp_GlobalDisable(locBase);
}
else
{
/* Set LPComp the status to the not changed state. */
enabled_status = 0u;
}
}
else
{
/* The LPComp block was already disabled and
* the system is allowed to go to the low power mode.
*/
}
ret = CY_SYSPM_SUCCESS;
}
break;
case CY_SYSPM_AFTER_TRANSITION:
{
/* Enable LPComp to operate if it was enabled
* before entering to the low power mode.
*/
if (0u != enabled_status)
{
Cy_LPComp_GlobalEnable(locBase);
}
else
{
/* The LPComp block was disabled before calling this API
* with mode = CY_SYSPM_CHECK_READY.
*/
}
ret = CY_SYSPM_SUCCESS;
}
break;
default:
break;
}
return (ret);
}
/*******************************************************************************
* Function Name: Cy_LPComp_HibernateCallback
****************************************************************************//**
*
* This function checks the current power mode of LPComp and then disable the
* LPComp block, if there is no wake-up source from LPComp in the hibernate mode.
*
* \param *callbackParams
* The \ref cy_stc_syspm_callback_params_t structure with the callback
* parameters which consists of mode, base and context fields:
* *base - LPComp register structure pointer;
* *context - Context for the call-back function;
* mode
* CY_SYSPM_CHECK_READY - No action for this state.
* CY_SYSPM_CHECK_FAIL - No action for this state.
* CY_SYSPM_BEFORE_TRANSITION - Checks the wake-up source from the hibernate mode
* of the LPComp block, and then disables or enables
* the LPComp block according to the condition.
*
* \return
* \ref cy_en_syspm_status_t
*
*******************************************************************************/
cy_en_syspm_status_t Cy_LPComp_HibernateCallback(cy_stc_syspm_callback_params_t *callbackParams)
{
cy_en_syspm_status_t ret = CY_SYSPM_FAIL;
LPCOMP_Type *locBase = (LPCOMP_Type *) (callbackParams->base);
static uint32_t enabled_status;
switch(callbackParams->mode)
{
case CY_SYSPM_CHECK_READY:
{
ret = CY_SYSPM_SUCCESS;
}
break;
case CY_SYSPM_CHECK_FAIL:
{
ret = CY_SYSPM_SUCCESS;
}
break;
case CY_SYSPM_BEFORE_TRANSITION:
{
/* Save the LPComp the enabled/disabled status. */
enabled_status = _FLD2VAL(LPCOMP_CONFIG_ENABLED, locBase->CONFIG);
if (0u != enabled_status)
{
/* Disable the LPComp block when there is no wake-up source from any channel. */
if( !(((_FLD2VAL(LPCOMP_CMP0_CTRL_MODE0, locBase->CMP0_CTRL) == (uint32_t)CY_LPCOMP_MODE_ULP) &&
_FLD2BOOL(CY_LPCOMP_WAKEUP_PIN0, SRSS->PWR_HIBERNATE)) ||
((_FLD2VAL(LPCOMP_CMP1_CTRL_MODE1, locBase->CMP1_CTRL) == (uint32_t)CY_LPCOMP_MODE_ULP) &&
_FLD2BOOL(CY_LPCOMP_WAKEUP_PIN1, SRSS->PWR_HIBERNATE))) )
{
/* Disable the LPComp block to avoid leakage. */
Cy_LPComp_GlobalDisable(locBase);
}
else
{
/* Set LPComp the status to the not changed state. */
enabled_status = 0u;
}
}
else
{
/* The LPComp block was already disabled and
* the system is allowed to go to the low power mode.
*/
}
ret = CY_SYSPM_SUCCESS;
}
break;
default:
break;
}
return (ret);
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */

View File

@ -0,0 +1,717 @@
/***************************************************************************//**
* \file cy_lpcomp.h
* \version 1.10.1
*
* This file provides constants and parameter values for the Low Power Comparator driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
/**
* \defgroup group_lpcomp Low Power Comparator (LPComp)
* \{
* Provides access to the low-power comparators implemented using the fixed-function
* LP comparator block that is present in PSoC 6.
*
* These comparators can perform fast analog signal comparison of internal
* and external analog signals in all system power modes. Low-power comparator
* output can be inspected by the CPU, used as an interrupt/wakeup source to the
* CPU when in low-power mode (Sleep, Low-Power Sleep, or Deep-Sleep), used as
* a wakeup source to system resources when in Hibernate mode, or fed to DSI as
* an asynchronous or synchronous signal (level or pulse).
*
* \section group_lpcomp_section_Configuration_Considerations Configuration Considerations
* To set up an LPComp, the inputs, the output, the mode, the interrupts and
* other configuration parameters should be configured. Power the LPComp to operate.
*
* The sequence recommended for the LPComp operation:
*
* 1) To initialize the driver, call the Cy_LPComp_Init() function providing
* the filled cy_stc_lpcomp_config_t structure, the LPComp channel number,
* and the LPCOMP registers structure pointer.
*
* 2) Optionally, configure the interrupt requests if the interrupt event
* triggering is needed. Use the Cy_LPComp_SetInterruptMask() function with
* the parameter for the mask available in the configuration file.
* Additionally, enable the Global interrupts and initialize the referenced
* interrupt by setting the priority and the interrupt vector using
* the \ref Cy_SysInt_Init() function of the sysint driver.
*
* 3) Configure the inputs and the output using the \ref Cy_GPIO_Pin_Init()
* functions of the GPIO driver.
* The High Impedance Analog drive mode is for the inputs and
* the Strong drive mode is for the output.
* Use the Cy_LPComp_SetInputs() function to connect the comparator inputs
* to the dedicated IO pins, AMUXBUSA/AMUXBUSB or Vref:
* \image html lpcomp_inputs.png
*
* 4) Power on the comparator using the Cy_LPComp_Enable() function.
*
* 5) The comparator output can be monitored using
* the Cy_LPComp_GetCompare() function or using the LPComp interrupt
* (if the interrupt is enabled).
*
* \note The interrupt is not cleared automatically.
* It is the user's responsibility to do that.
* The interrupt is cleared by writing a 1 in the corresponding interrupt
* register bit position. The preferred way to clear interrupt sources
* is using the Cy_LPComp_ClearInterrupt() function.
*
* \note Individual comparator interrupt outputs are ORed together
* as a single asynchronous interrupt source before it is sent out and
* used to wake up the system in the low-power mode.
* For PSoC 6 devices, the individual comparator interrupt is masked
* by the INTR_MASK register. The masked result is captured in
* the INTR_MASKED register.
* Writing a 1 to the INTR register bit will clear the interrupt.
*
* \section group_lpcomp_lp Low Power Support
* The LPComp provides the callback functions to facilitate
* the low-power mode transition. The callback
* \ref Cy_LPComp_DeepSleepCallback must be called during execution
* of \ref Cy_SysPm_DeepSleep; \ref Cy_LPComp_HibernateCallback must be
* called during execution of \ref Cy_SysPm_Hibernate.
* To trigger the callback execution, the callback must be registered
* before calling the mode transition function.
* Refer to \ref group_syspm driver for more
* information about low-power mode transitions.
*
* \section group_lpcomp_more_information More Information
*
* Refer to the appropriate device technical reference manual (TRM) for
* a detailed description of the registers.
*
* \section group_lpcomp_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 object type and
* a different pointer to object type.</td>
* <td>
* The pointer to the buffer memory is void to allow handling different
* different data types: uint8_t (4-8 bits) or uint16_t (9-16 bits).
* The cast operation is safe because the configuration is verified
* before operation is performed.
* The function \ref Cy_LPComp_DeepSleepCallback is a callback of
* the \ref cy_en_syspm_status_t type. The cast operation safety in this
* function becomes the user's responsibility because the pointers are
* initialized when a callback is registered in the SysPm driver.</td>
* </tr>
* </table>
*
* \section group_lpcomp_Changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.10.1</td>
* <td>Added Low Power Callback section</td>
* <td>Documentation update and clarification</td>
* </tr>
* <tr>
* <td>1.10</td>
* <td>The CY_WEAK keyword is removed from Cy_LPComp_DeepSleepCallback()
* and Cy_LPComp_HibernateCallback() functions<br>
* Added input parameter validation to the API functions.</td>
* <td></td>
* </tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_lpcomp_macros Macros
* \defgroup group_lpcomp_functions Functions
* \{
* \defgroup group_lpcomp_functions_syspm_callback Low Power Callback
* \}
* \defgroup group_lpcomp_data_structures Data Structures
* \defgroup group_lpcomp_enums Enumerated Types
*/
#ifndef CY_LPCOMP_PDL_H
#define CY_LPCOMP_PDL_H
/******************************************************************************/
/* Include files */
/******************************************************************************/
#include <stdbool.h>
#include <stddef.h>
#include "cy_device_headers.h"
#include "syslib/cy_syslib.h"
#include "syspm/cy_syspm.h"
#ifndef CY_IP_MXLPCOMP
#error "The LPCOMP driver is not supported on this device"
#endif
/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif
/**
* \addtogroup group_lpcomp_macros
* \{
*/
/** Driver major version */
#define CY_LPCOMP_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_LPCOMP_DRV_VERSION_MINOR 10
/******************************************************************************
* API Constants
******************************************************************************/
/**< LPCOMP PDL ID */
#define CY_LPCOMP_ID CY_PDL_DRV_ID(0x23u)
/** The LPCOMP's number of channels. */
#define CY_LPCOMP_MAX_CHANNEL_NUM (2u)
/** LPCOMP's comparator 1 interrupt mask. */
#define CY_LPCOMP_COMP0 (0x01u)
/** LPCOMP's comparator 2 interrupt mask. */
#define CY_LPCOMP_COMP1 (0x02u)
/** \cond INTERNAL_MACROS */
/******************************************************************************
* Registers Constants
******************************************************************************/
#define CY_LPCOMP_MODE_ULP_Pos (0x0uL)
#define CY_LPCOMP_MODE_ULP_Msk (0x1uL)
#define CY_LPCOMP_INTR_Pos (LPCOMP_INTR_COMP0_Pos)
#define CY_LPCOMP_INTR_Msk (LPCOMP_INTR_COMP0_Msk | LPCOMP_INTR_COMP1_Msk)
#define CY_LPCOMP_CMP0_SW_POS_Msk (LPCOMP_CMP0_SW_CMP0_IP0_Msk | \
LPCOMP_CMP0_SW_CMP0_AP0_Msk | \
LPCOMP_CMP0_SW_CMP0_BP0_Msk)
#define CY_LPCOMP_CMP0_SW_NEG_Msk (LPCOMP_CMP0_SW_CMP0_IN0_Msk | \
LPCOMP_CMP0_SW_CMP0_AN0_Msk | \
LPCOMP_CMP0_SW_CMP0_BN0_Msk | \
LPCOMP_CMP0_SW_CMP0_VN0_Msk)
#define CY_LPCOMP_CMP1_SW_POS_Msk (LPCOMP_CMP1_SW_CMP1_IP1_Msk | \
LPCOMP_CMP1_SW_CMP1_AP1_Msk | \
LPCOMP_CMP1_SW_CMP1_BP1_Msk)
#define CY_LPCOMP_CMP1_SW_NEG_Msk (LPCOMP_CMP1_SW_CMP1_IN1_Msk | \
LPCOMP_CMP1_SW_CMP1_AN1_Msk | \
LPCOMP_CMP1_SW_CMP1_BN1_Msk | \
LPCOMP_CMP1_SW_CMP1_VN1_Msk)
#define CY_LPCOMP_CMP0_OUTPUT_CONFIG_Pos LPCOMP_CMP0_CTRL_DSI_BYPASS0_Pos
#define CY_LPCOMP_CMP1_OUTPUT_CONFIG_Pos LPCOMP_CMP1_CTRL_DSI_BYPASS1_Pos
#define CY_LPCOMP_CMP0_OUTPUT_CONFIG_Msk (LPCOMP_CMP0_CTRL_DSI_BYPASS0_Msk | \
LPCOMP_CMP0_CTRL_DSI_LEVEL0_Msk)
#define CY_LPCOMP_CMP1_OUTPUT_CONFIG_Msk (LPCOMP_CMP1_CTRL_DSI_BYPASS1_Msk | \
LPCOMP_CMP1_CTRL_DSI_LEVEL1_Msk)
#define CY_HSIOM_AMUX_SPLIT_CTL_SWITCH_AA_SL_SR_Pos HSIOM_AMUX_SPLIT_CTL_SWITCH_AA_SL_Pos
#define CY_HSIOM_AMUX_SPLIT_CTL_SWITCH_AA_SL_SR_Msk (HSIOM_AMUX_SPLIT_CTL_SWITCH_AA_SL_Msk | \
HSIOM_AMUX_SPLIT_CTL_SWITCH_AA_SR_Msk)
#define CY_HSIOM_AMUX_SPLIT_CTL_SWITCH_BB_SL_SR_Pos HSIOM_AMUX_SPLIT_CTL_SWITCH_BB_SL_Pos
#define CY_HSIOM_AMUX_SPLIT_CTL_SWITCH_BB_SL_SR_Msk (HSIOM_AMUX_SPLIT_CTL_SWITCH_BB_SL_Msk | \
HSIOM_AMUX_SPLIT_CTL_SWITCH_BB_SR_Msk)
#define CY_LPCOMP_REF_CONNECTED (1u)
#define CY_LPCOMP_WAKEUP_PIN0_Msk CY_SYSPM_WAKEUP_LPCOMP0
#define CY_LPCOMP_WAKEUP_PIN1_Msk CY_SYSPM_WAKEUP_LPCOMP1
/* Internal constants for Cy_LPComp_Enable() */
#define CY_LPCOMP_NORMAL_POWER_DELAY (3u)
#define CY_LPCOMP_LP_POWER_DELAY (6u)
#define CY_LPCOMP_ULP_POWER_DELAY (50u)
/** \endcond */
/** \} group_lpcomp_macros */
/**
* \addtogroup group_lpcomp_enums
* \{
*/
/******************************************************************************
* Enumerations
*****************************************************************************/
/** The LPCOMP output modes. */
typedef enum
{
CY_LPCOMP_OUT_PULSE = 0u, /**< The LPCOMP DSI output with the pulse option, no bypass. */
CY_LPCOMP_OUT_DIRECT = 1u, /**< The LPCOMP bypass mode, the direct output of a comparator. */
CY_LPCOMP_OUT_SYNC = 2u /**< The LPCOMP DSI output with the level option, it is similar
to the bypass mode but it is 1 cycle slow than the bypass. */
} cy_en_lpcomp_out_t;
/** The LPCOMP hysteresis modes. */
typedef enum
{
CY_LPCOMP_HYST_ENABLE = 1u, /**< The LPCOMP enable hysteresis. */
CY_LPCOMP_HYST_DISABLE = 0u /**< The LPCOMP disable hysteresis. */
} cy_en_lpcomp_hyst_t;
/** The LPCOMP's channel number. */
typedef enum
{
CY_LPCOMP_CHANNEL_0 = 0x1u, /**< The LPCOMP Comparator 0. */
CY_LPCOMP_CHANNEL_1 = 0x2u /**< The LPCOMP Comparator 1. */
} cy_en_lpcomp_channel_t;
/** The LPCOMP interrupt modes. */
typedef enum
{
CY_LPCOMP_INTR_DISABLE = 0u, /**< The LPCOMP interrupt disabled, no interrupt will be detected. */
CY_LPCOMP_INTR_RISING = 1u, /**< The LPCOMP interrupt on the rising edge. */
CY_LPCOMP_INTR_FALLING = 2u, /**< The LPCOMP interrupt on the falling edge. */
CY_LPCOMP_INTR_BOTH = 3u /**< The LPCOMP interrupt on both rising and falling edges. */
} cy_en_lpcomp_int_t;
/** The LPCOMP power-mode selection. */
typedef enum
{
CY_LPCOMP_MODE_OFF = 0u, /**< The LPCOMP's channel power-off. */
CY_LPCOMP_MODE_ULP = 1u, /**< The LPCOMP's channel ULP mode. */
CY_LPCOMP_MODE_LP = 2u, /**< The LPCOMP's channel LP mode. */
CY_LPCOMP_MODE_NORMAL = 3u /**< The LPCOMP's channel normal mode. */
} cy_en_lpcomp_pwr_t;
/** The LPCOMP inputs. */
typedef enum
{
CY_LPCOMP_SW_GPIO = 0x01u, /**< The LPCOMP input connects to GPIO pin. */
CY_LPCOMP_SW_AMUXBUSA = 0x02u, /**< The LPCOMP input connects to AMUXBUSA. */
CY_LPCOMP_SW_AMUXBUSB = 0x04u, /**< The LPCOMP input connects to AMUXBUSB. */
CY_LPCOMP_SW_LOCAL_VREF = 0x08u /**< The LPCOMP input connects to local VREF. */
} cy_en_lpcomp_inputs_t;
/** The LPCOMP error codes. */
typedef enum
{
CY_LPCOMP_SUCCESS = 0x00u, /**< Successful */
CY_LPCOMP_BAD_PARAM = CY_LPCOMP_ID | CY_PDL_STATUS_ERROR | 0x01u, /**< One or more invalid parameters */
CY_LPCOMP_TIMEOUT = CY_LPCOMP_ID | CY_PDL_STATUS_ERROR | 0x02u, /**< Operation timed out */
CY_LPCOMP_INVALID_STATE = CY_LPCOMP_ID | CY_PDL_STATUS_ERROR | 0x03u, /**< Operation not setup or is in an improper state */
CY_LPCOMP_UNKNOWN = CY_LPCOMP_ID | CY_PDL_STATUS_ERROR | 0xFFu, /**< Unknown failure */
} cy_en_lpcomp_status_t;
/** \} group_lpcomp_enums */
/**
* \addtogroup group_lpcomp_data_structures
* \{
*/
/******************************************************************************
* Structures
*****************************************************************************/
/** The LPCOMP configuration structure. */
typedef struct {
cy_en_lpcomp_out_t outputMode; /**< The LPCOMP's outputMode: Direct output,
Synchronized output or Pulse output */
cy_en_lpcomp_hyst_t hysteresis; /**< Enables or disables the LPCOMP's hysteresis */
cy_en_lpcomp_pwr_t power; /**< Sets the LPCOMP power mode */
cy_en_lpcomp_int_t intType; /**< Sets the LPCOMP interrupt mode */
} cy_stc_lpcomp_config_t;
/** \cond CONTEXT_STRUCTURE */
typedef struct {
cy_en_lpcomp_int_t intType[CY_LPCOMP_MAX_CHANNEL_NUM];
cy_en_lpcomp_pwr_t power[CY_LPCOMP_MAX_CHANNEL_NUM];
} cy_stc_lpcomp_context_t;
/** \endcond */
/** \} group_lpcomp_data_structures */
/** \cond INTERNAL_MACROS */
/******************************************************************************
* Macros
*****************************************************************************/
#define CY_LPCOMP_IS_CHANNEL_VALID(channel) (((channel) == CY_LPCOMP_CHANNEL_0) || \
((channel) == CY_LPCOMP_CHANNEL_1))
#define CY_LPCOMP_IS_OUT_MODE_VALID(mode) (((mode) == CY_LPCOMP_OUT_PULSE) || \
((mode) == CY_LPCOMP_OUT_DIRECT) || \
((mode) == CY_LPCOMP_OUT_SYNC))
#define CY_LPCOMP_IS_HYSTERESIS_VALID(hyst) (((hyst) == CY_LPCOMP_HYST_ENABLE) || \
((hyst) == CY_LPCOMP_HYST_DISABLE))
#define CY_LPCOMP_IS_INTR_MODE_VALID(intr) (((intr) == CY_LPCOMP_INTR_DISABLE) || \
((intr) == CY_LPCOMP_INTR_RISING) || \
((intr) == CY_LPCOMP_INTR_FALLING) || \
((intr) == CY_LPCOMP_INTR_BOTH))
#define CY_LPCOMP_IS_POWER_VALID(power) (((power) == CY_LPCOMP_MODE_OFF) || \
((power) == CY_LPCOMP_MODE_ULP) || \
((power) == CY_LPCOMP_MODE_LP) || \
((power) == CY_LPCOMP_MODE_NORMAL))
#define CY_LPCOMP_IS_INTR_VALID(intr) (((intr) == CY_LPCOMP_COMP0) || \
((intr) == CY_LPCOMP_COMP1) || \
((intr) == (CY_LPCOMP_COMP0 | CY_LPCOMP_COMP1)))
#define CY_LPCOMP_IS_INPUT_P_VALID(input) (((input) == CY_LPCOMP_SW_GPIO) || \
((input) == CY_LPCOMP_SW_AMUXBUSA) || \
((input) == CY_LPCOMP_SW_AMUXBUSB))
#define CY_LPCOMP_IS_INPUT_N_VALID(input) (((input) == CY_LPCOMP_SW_GPIO) || \
((input) == CY_LPCOMP_SW_AMUXBUSA) || \
((input) == CY_LPCOMP_SW_AMUXBUSB) || \
((input) == CY_LPCOMP_SW_LOCAL_VREF))
/** \endcond */
/**
* \addtogroup group_lpcomp_functions
* \{
*/
/******************************************************************************
* Functions
*******************************************************************************/
cy_en_lpcomp_status_t Cy_LPComp_Init(LPCOMP_Type *base, cy_en_lpcomp_channel_t channel, const cy_stc_lpcomp_config_t *config);
void Cy_LPComp_Enable(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel);
void Cy_LPComp_Disable(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel);
__STATIC_INLINE void Cy_LPComp_GlobalEnable(LPCOMP_Type *base);
__STATIC_INLINE void Cy_LPComp_GlobalDisable(LPCOMP_Type *base);
__STATIC_INLINE void Cy_LPComp_UlpReferenceEnable(LPCOMP_Type *base);
__STATIC_INLINE void Cy_LPComp_UlpReferenceDisable(LPCOMP_Type *base);
__STATIC_INLINE uint32_t Cy_LPComp_GetCompare(LPCOMP_Type const * base, cy_en_lpcomp_channel_t channel);
void Cy_LPComp_SetPower(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel, cy_en_lpcomp_pwr_t power);
void Cy_LPComp_SetHysteresis(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel, cy_en_lpcomp_hyst_t hysteresis);
void Cy_LPComp_SetInputs(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel, cy_en_lpcomp_inputs_t inputP, cy_en_lpcomp_inputs_t inputN);
void Cy_LPComp_SetOutputMode(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel, cy_en_lpcomp_out_t outType);
void Cy_LPComp_SetInterruptTriggerMode(LPCOMP_Type* base, cy_en_lpcomp_channel_t channel, cy_en_lpcomp_int_t intType);
__STATIC_INLINE uint32_t Cy_LPComp_GetInterruptStatus(LPCOMP_Type const * base);
__STATIC_INLINE void Cy_LPComp_ClearInterrupt(LPCOMP_Type* base, uint32_t interrupt);
__STATIC_INLINE void Cy_LPComp_SetInterrupt(LPCOMP_Type* base, uint32_t interrupt);
__STATIC_INLINE uint32_t Cy_LPComp_GetInterruptMask(LPCOMP_Type const * base);
__STATIC_INLINE void Cy_LPComp_SetInterruptMask(LPCOMP_Type* base, uint32_t interrupt);
__STATIC_INLINE uint32_t Cy_LPComp_GetInterruptStatusMasked(LPCOMP_Type const * base);
__STATIC_INLINE void Cy_LPComp_ConnectULPReference(LPCOMP_Type *base, cy_en_lpcomp_channel_t channel);
/** \addtogroup group_lpcomp_functions_syspm_callback
* The driver supports SysPm callback for Deep Sleep and Hibernate transition.
* \{
*/
cy_en_syspm_status_t Cy_LPComp_DeepSleepCallback(cy_stc_syspm_callback_params_t *callbackParams);
cy_en_syspm_status_t Cy_LPComp_HibernateCallback(cy_stc_syspm_callback_params_t *callbackParams);
/** \} */
/*******************************************************************************
* Function Name: Cy_LPComp_GlobalEnable
****************************************************************************//**
*
* Activates the IP of the LPCOMP hardware block. This API should be enabled
* before operating any channel of comparators.
* Note: Interrupts can be enabled after the block is enabled and the appropriate
* start-up time has elapsed:
* 3 us for the normal power mode;
* 6 us for the LP mode;
* 50 us for the ULP mode.
*
* \param *base
* The structure of the channel pointer.
*
* \return None
*
*******************************************************************************/
__STATIC_INLINE void Cy_LPComp_GlobalEnable(LPCOMP_Type* base)
{
base->CONFIG |= LPCOMP_CONFIG_ENABLED_Msk;
}
/*******************************************************************************
* Function Name: Cy_LPComp_GlobalDisable
****************************************************************************//**
*
* Deactivates the IP of the LPCOMP hardware block.
* (Analog in power down, open all switches, all clocks off).
*
* \param *base
* The structure of the channel pointer.
*
* \return None
*
*******************************************************************************/
__STATIC_INLINE void Cy_LPComp_GlobalDisable(LPCOMP_Type *base)
{
base->CONFIG &= (uint32_t) ~LPCOMP_CONFIG_ENABLED_Msk;
}
/*******************************************************************************
* Function Name: Cy_LPComp_UlpReferenceEnable
****************************************************************************//**
*
* Enables the local reference-generator circuit.
*
* \param *base
* The structure of the channel pointer.
*
* \return None
*
*******************************************************************************/
__STATIC_INLINE void Cy_LPComp_UlpReferenceEnable(LPCOMP_Type *base)
{
base->CONFIG |= LPCOMP_CONFIG_LPREF_EN_Msk;
}
/*******************************************************************************
* Function Name: Cy_LPComp_UlpReferenceDisable
****************************************************************************//**
*
* Disables the local reference-generator circuit.
*
* \param *base
* The structure of the channel pointer.
*
* \return None
*
*******************************************************************************/
__STATIC_INLINE void Cy_LPComp_UlpReferenceDisable(LPCOMP_Type *base)
{
base->CONFIG &= (uint32_t) ~LPCOMP_CONFIG_LPREF_EN_Msk;
}
/*******************************************************************************
* Function Name: Cy_LPComp_GetCompare
****************************************************************************//**
*
* This function returns a nonzero value when the voltage connected to the
* positive input is greater than the negative input voltage.
*
* \param *base
* The LPComp register structure pointer.
*
* \param channel
* The LPComp channel index.
*
* \return LPComp compare result.
* The value is a nonzero value when the voltage connected to the positive
* input is greater than the negative input voltage.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_LPComp_GetCompare(LPCOMP_Type const * base, cy_en_lpcomp_channel_t channel)
{
uint32_t result;
CY_ASSERT_L3(CY_LPCOMP_IS_CHANNEL_VALID(channel));
if (CY_LPCOMP_CHANNEL_0 == channel)
{
result = _FLD2VAL(LPCOMP_STATUS_OUT0, base->STATUS);
}
else
{
result = _FLD2VAL(LPCOMP_STATUS_OUT1, base->STATUS);
}
return (result);
}
/*******************************************************************************
* Function Name: Cy_LPComp_SetInterruptMask
****************************************************************************//**
*
* Configures which bits of the interrupt request register will trigger an
* interrupt event.
*
* \param *base
* The LPCOMP register structure pointer.
*
* \param interrupt
* uint32_t interruptMask: Bit Mask of interrupts to set.
* Bit 0: COMP0 Interrupt Mask
* Bit 1: COMP1 Interrupt Mask
*
* \return None
*
*******************************************************************************/
__STATIC_INLINE void Cy_LPComp_SetInterruptMask(LPCOMP_Type* base, uint32_t interrupt)
{
CY_ASSERT_L2(CY_LPCOMP_IS_INTR_VALID(interrupt));
base->INTR_MASK |= interrupt;
}
/*******************************************************************************
* Function Name: Cy_LPComp_GetInterruptMask
****************************************************************************//**
*
* Returns an interrupt mask.
*
* \param *base
* The LPCOMP register structure pointer.
*
* \return bit mapping information
* Bit 0: COMP0 Interrupt Mask
* Bit 1: COMP1 Interrupt Mask
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_LPComp_GetInterruptMask(LPCOMP_Type const * base)
{
return (base->INTR_MASK);
}
/*******************************************************************************
* Function Name: Cy_LPComp_GetInterruptStatusMasked
****************************************************************************//**
*
* Returns an interrupt request register masked by an interrupt mask.
* Returns the result of the bitwise AND operation between the corresponding
* interrupt request and mask bits.
*
* \param *base
* The LPCOMP register structure pointer.
*
* \return bit mapping information
* Bit 0: COMP0 Interrupt Masked
* Bit 1: COMP1 Interrupt Masked
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_LPComp_GetInterruptStatusMasked(LPCOMP_Type const * base)
{
return (base->INTR_MASKED);
}
/*******************************************************************************
* Function Name: Cy_LPComp_GetInterruptStatus
****************************************************************************//**
*
* Returns the status of 2 different LPCOMP interrupt requests.
*
* \param *base
* The LPCOMP register structure pointer.
*
* \return bit mapping information
* Bit 0: COMP0 Interrupt status
* Bit 1: COMP1 Interrupt status
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_LPComp_GetInterruptStatus(LPCOMP_Type const * base)
{
return (_FLD2VAL(CY_LPCOMP_INTR, base->INTR));
}
/*******************************************************************************
* Function Name: Cy_LPComp_ClearInterrupt
****************************************************************************//**
*
* Clears LPCOMP interrupts by setting each bit.
*
* \param *base
* The LPCOMP register structure pointer.
*
* \param interrupt
* Bit 0: COMP0 Interrupt status
* Bit 1: COMP1 Interrupt status
*
* \return None
*
*******************************************************************************/
__STATIC_INLINE void Cy_LPComp_ClearInterrupt(LPCOMP_Type* base, uint32_t interrupt)
{
CY_ASSERT_L2(CY_LPCOMP_IS_INTR_VALID(interrupt));
base->INTR |= interrupt;
(void) LPCOMP->INTR;
}
/*******************************************************************************
* Function Name: Cy_LPComp_SetInterrupt
****************************************************************************//**
*
* Sets a software interrupt request.
* This function is used in the case of combined interrupt signal from the global
* signal reference. This function from either component instance can be used
* to trigger either or both software interrupts. It sets the INTR_SET interrupt mask.
*
* \param *base
* The LPCOMP register structure pointer.
*
* \param interrupt
* Bit 0: COMP0 Interrupt status
* Bit 1: COMP1 Interrupt status
*
* \return None
*
*******************************************************************************/
__STATIC_INLINE void Cy_LPComp_SetInterrupt(LPCOMP_Type* base, uint32_t interrupt)
{
CY_ASSERT_L2(CY_LPCOMP_IS_INTR_VALID(interrupt));
base->INTR_SET = interrupt;
}
/*******************************************************************************
* Function Name: Cy_LPComp_ConnectULPReference
****************************************************************************//**
*
* Connects the local reference generator output to the comparator negative input.
*
* \param *base
* The LPCOMP register structure pointer.
*
* \param channel
* The LPCOMP channel index.
*
* \return None
*
*******************************************************************************/
__STATIC_INLINE void Cy_LPComp_ConnectULPReference(LPCOMP_Type *base, cy_en_lpcomp_channel_t channel)
{
CY_ASSERT_L3(CY_LPCOMP_IS_CHANNEL_VALID(channel));
if (CY_LPCOMP_CHANNEL_0 == channel)
{
base->CMP0_SW_CLEAR = CY_LPCOMP_CMP0_SW_NEG_Msk;
base->CMP0_SW = _CLR_SET_FLD32U(base->CMP0_SW, LPCOMP_CMP0_SW_CMP0_VN0, CY_LPCOMP_REF_CONNECTED);
}
else
{
base->CMP1_SW_CLEAR = CY_LPCOMP_CMP1_SW_NEG_Msk;
base->CMP1_SW = _CLR_SET_FLD32U(base->CMP1_SW, LPCOMP_CMP1_SW_CMP1_VN1, CY_LPCOMP_REF_CONNECTED);
}
}
/** \} group_lpcomp_functions */
#ifdef __cplusplus
}
#endif
#endif /* CY_LPCOMP_PDL_H */
/** \} group_lpcomp */
/* [] END OF FILE */

View File

@ -0,0 +1,62 @@
/***************************************************************************//**
* \file cy_lvd.c
* \version 1.0.1
*
* The source code file for the LVD driver.
*
********************************************************************************
* \copyright
* Copyright 2017-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "cy_lvd.h"
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_LVD_DeepSleepCallback
****************************************************************************//**
*
* When this function is registered by \ref Cy_SysPm_RegisterCallback - it
* automatically enables the LVD after wake up from Deep-Sleep mode.
*
* \param callbackParams The pointer to the callback parameters structure,
* see \ref cy_stc_syspm_callback_params_t.
*
* \return the SysPm callback status \ref cy_en_syspm_status_t.
*
*******************************************************************************/
cy_en_syspm_status_t Cy_LVD_DeepSleepCallback(cy_stc_syspm_callback_params_t * callbackParams)
{
cy_en_syspm_status_t ret = CY_SYSPM_SUCCESS;
switch(callbackParams->mode)
{
case CY_SYSPM_CHECK_READY:
case CY_SYSPM_CHECK_FAIL:
case CY_SYSPM_BEFORE_TRANSITION:
break;
case CY_SYSPM_AFTER_TRANSITION:
Cy_LVD_Enable();
break;
default:
ret = CY_SYSPM_FAIL;
break;
}
return(ret);
}
#ifdef __cplusplus
}
#endif
/* [] END OF FILE */

View File

@ -0,0 +1,433 @@
/***************************************************************************//**
* \file cy_lvd.h
* \version 1.0.1
*
* The header file of the LVD driver.
*
********************************************************************************
* \copyright
* Copyright 2017-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
/**
* \addtogroup group_lvd
* \{
* The LVD driver provides an API to manage the Low Voltage Detection block.
* The LVD block provides a status of currently observed VDDD voltage
* and triggers an interrupt when the observed voltage crosses an adjusted
* threshold.
*
* \section group_lvd_configuration_considerations Configuration Considerations
* To set up an LVD, configure the voltage threshold by the
* \ref Cy_LVD_SetThreshold function, ensure that the LVD block itself and LVD
* interrupt are disabled (by the \ref Cy_LVD_Disable and
* \ref Cy_LVD_ClearInterruptMask functions correspondingly) before changing the
* threshold to prevent propagating a false interrupt.
* Then configure interrupts by the \ref Cy_LVD_SetInterruptConfig function, do
* not forget to initialise an interrupt handler (the interrupt source number
* is srss_interrupt_IRQn).
* Then enable LVD by the \ref Cy_LVD_Enable function, then wait for at least 20us
* to get the circuit stabilized and clear the possible false interrupts by the
* \ref Cy_LVD_ClearInterrupt, and finally the LVD interrupt can be enabled by
* the \ref Cy_LVD_SetInterruptMask function.
*
* For example:
* \snippet lvd_1_0_sut_00.cydsn/main_cm4.c Cy_LVD_Snippet
*
* Note that the LVD circuit is available only in Active, LPACTIVE, Sleep, and
* LPSLEEP power modes. If an LVD is required in Deep-Sleep mode, then the device
* should be configured to periodically wake up from deep sleep using a
* Deep-Sleep wakeup source. This makes sure a LVD check is performed during
* Active/LPACTIVE mode.
*
* \section group_lvd_more_information More Information
* See the LVD chapter of the device technical reference manual (TRM).
*
* \section group_lvd_MISRA MISRA-C Compliance
* The LVD 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>10.3</td>
* <td>R</td>
* <td>A composite expression of 'essentially unsigned' type (%1s) is being
* cast to a different type category, '%2s'.</td>
* <td>The value got from the bitfield physically can't exceed the enumeration
* that describes this bitfield. So the code is safety by design.</td>
* </tr>
* <tr>
* <td>16.7</td>
* <td>A</td>
* <td>The object addressed by the pointer parameter '%s' is not modified and
* so the pointer could be of type 'pointer to const'.</td>
* <td>The pointer parameter is not used or modified, as there is no need
* to do any actions with it. However, such parameter is
* required to be presented in the function, because the
* \ref Cy_LVD_DeepSleepCallback is a callback
* of \ref cy_en_syspm_status_t type.
* The SysPM driver callback function type requires implementing the
* function with the next parameters and return value: <br>
* cy_en_syspm_status_t (*Cy_SysPmCallback)
* (cy_stc_syspm_callback_params_t *callbackParams);</td>
* </tr>
* </table>
*
* \section group_lvd_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason of Change</th></tr>
* <tr>
* <td>1.0.1</td>
* <td>Added Low Power Callback section</td>
* <td>Documentation update and clarification</td>
* </tr>
* <tr>
* <td>1.0</td>
* <td>Initial Version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_lvd_macros Macros
* \defgroup group_lvd_functions Functions
* \{
* \defgroup group_lvd_functions_syspm_callback Low Power Callback
* \}
* \defgroup group_lvd_enums Enumerated Types
*/
#if !defined CY_LVD_H
#define CY_LVD_H
#include "syspm/cy_syspm.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \addtogroup group_lvd_macros
* \{
*/
/** The driver major version */
#define CY_LVD_DRV_VERSION_MAJOR 1
/** The driver minor version */
#define CY_LVD_DRV_VERSION_MINOR 0
/** The LVD driver identifier */
#define CY_LVD_ID (CY_PDL_DRV_ID(0x39U))
/** Interrupt mask for \ref Cy_LVD_GetInterruptStatus(),
\ref Cy_LVD_GetInterruptMask() and
\ref Cy_LVD_GetInterruptStatusMasked() */
#define CY_LVD_INTR (SRSS_SRSS_INTR_HVLVD1_Msk)
/** \} group_lvd_macros */
/** \addtogroup group_lvd_enums
* \{
*/
/**
* LVD reference voltage select.
*/
typedef enum
{
CY_LVD_THRESHOLD_1_2_V = 0x0U, /**<Select LVD reference voltage: 1.2V */
CY_LVD_THRESHOLD_1_4_V = 0x1U, /**<Select LVD reference voltage: 1.4V */
CY_LVD_THRESHOLD_1_6_V = 0x2U, /**<Select LVD reference voltage: 1.6V */
CY_LVD_THRESHOLD_1_8_V = 0x3U, /**<Select LVD reference voltage: 1.8V */
CY_LVD_THRESHOLD_2_0_V = 0x4U, /**<Select LVD reference voltage: 2.0V */
CY_LVD_THRESHOLD_2_1_V = 0x5U, /**<Select LVD reference voltage: 2.1V */
CY_LVD_THRESHOLD_2_2_V = 0x6U, /**<Select LVD reference voltage: 2.2V */
CY_LVD_THRESHOLD_2_3_V = 0x7U, /**<Select LVD reference voltage: 2.3V */
CY_LVD_THRESHOLD_2_4_V = 0x8U, /**<Select LVD reference voltage: 2.4V */
CY_LVD_THRESHOLD_2_5_V = 0x9U, /**<Select LVD reference voltage: 2.5V */
CY_LVD_THRESHOLD_2_6_V = 0xAU, /**<Select LVD reference voltage: 2.6V */
CY_LVD_THRESHOLD_2_7_V = 0xBU, /**<Select LVD reference voltage: 2.7V */
CY_LVD_THRESHOLD_2_8_V = 0xCU, /**<Select LVD reference voltage: 2.8V */
CY_LVD_THRESHOLD_2_9_V = 0xDU, /**<Select LVD reference voltage: 2.9V */
CY_LVD_THRESHOLD_3_0_V = 0xEU, /**<Select LVD reference voltage: 3.0V */
CY_LVD_THRESHOLD_3_1_V = 0xFU /**<Select LVD reference voltage: 3.1V */
} cy_en_lvd_tripsel_t;
/**
* LVD interrupt configuration select.
*/
typedef enum
{
CY_LVD_INTR_DISABLE = 0x0U, /**<Select LVD interrupt: disabled */
CY_LVD_INTR_RISING = 0x1U, /**<Select LVD interrupt: rising edge */
CY_LVD_INTR_FALLING = 0x2U, /**<Select LVD interrupt: falling edge */
CY_LVD_INTR_BOTH = 0x3U, /**<Select LVD interrupt: both edges */
} cy_en_lvd_intr_config_t;
/**
* LVD output status.
*/
typedef enum
{
CY_LVD_STATUS_BELOW = 0x0U, /**<The voltage is below the threshold */
CY_LVD_STATUS_ABOVE = 0x1U, /**<The voltage is above the threshold */
} cy_en_lvd_status_t;
/** \} group_lvd_enums */
/** \cond internal */
/* Macros for conditions used by CY_ASSERT calls */
#define CY_LVD_CHECK_TRIPSEL(threshold) (((threshold) == CY_LVD_THRESHOLD_1_2_V) || \
((threshold) == CY_LVD_THRESHOLD_1_4_V) || \
((threshold) == CY_LVD_THRESHOLD_1_6_V) || \
((threshold) == CY_LVD_THRESHOLD_1_8_V) || \
((threshold) == CY_LVD_THRESHOLD_2_0_V) || \
((threshold) == CY_LVD_THRESHOLD_2_1_V) || \
((threshold) == CY_LVD_THRESHOLD_2_2_V) || \
((threshold) == CY_LVD_THRESHOLD_2_3_V) || \
((threshold) == CY_LVD_THRESHOLD_2_4_V) || \
((threshold) == CY_LVD_THRESHOLD_2_5_V) || \
((threshold) == CY_LVD_THRESHOLD_2_6_V) || \
((threshold) == CY_LVD_THRESHOLD_2_7_V) || \
((threshold) == CY_LVD_THRESHOLD_2_8_V) || \
((threshold) == CY_LVD_THRESHOLD_2_9_V) || \
((threshold) == CY_LVD_THRESHOLD_3_0_V) || \
((threshold) == CY_LVD_THRESHOLD_3_1_V))
#define CY_LVD_CHECK_INTR_CFG(intrCfg) (((intrCfg) == CY_LVD_INTR_DISABLE) || \
((intrCfg) == CY_LVD_INTR_RISING) || \
((intrCfg) == CY_LVD_INTR_FALLING) || \
((intrCfg) == CY_LVD_INTR_BOTH))
/** \endcond */
/**
* \addtogroup group_lvd_functions
* \{
*/
__STATIC_INLINE void Cy_LVD_Enable(void);
__STATIC_INLINE void Cy_LVD_Disable(void);
__STATIC_INLINE void Cy_LVD_SetThreshold(cy_en_lvd_tripsel_t threshold);
__STATIC_INLINE cy_en_lvd_status_t Cy_LVD_GetStatus(void);
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptStatus(void);
__STATIC_INLINE void Cy_LVD_ClearInterrupt(void);
__STATIC_INLINE void Cy_LVD_SetInterrupt(void);
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptMask(void);
__STATIC_INLINE void Cy_LVD_SetInterruptMask(void);
__STATIC_INLINE void Cy_LVD_ClearInterruptMask(void);
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptStatusMasked(void);
__STATIC_INLINE void Cy_LVD_SetInterruptConfig(cy_en_lvd_intr_config_t lvdInterruptConfig);
/** \addtogroup group_lvd_functions_syspm_callback
* The driver supports SysPm callback for Deep Sleep transition.
* \{
*/
cy_en_syspm_status_t Cy_LVD_DeepSleepCallback(cy_stc_syspm_callback_params_t * callbackParams);
/** \} */
/*******************************************************************************
* Function Name: Cy_LVD_Enable
****************************************************************************//**
*
* Enables the output of the LVD block when the VDDD voltage is
* at or below the threshold.
* See the Configuration Considerations section for details.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_Enable(void)
{
SRSS->PWR_LVD_CTL |= SRSS_PWR_LVD_CTL_HVLVD1_EN_Msk;
}
/*******************************************************************************
* Function Name: Cy_LVD_Disable
****************************************************************************//**
*
* Disables the LVD block. A low voltage detection interrupt is disabled.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_Disable(void)
{
SRSS->PWR_LVD_CTL &= (uint32_t) ~SRSS_PWR_LVD_CTL_HVLVD1_EN_Msk;
}
/*******************************************************************************
* Function Name: Cy_LVD_SetThreshold
****************************************************************************//**
*
* Sets a threshold for monitoring the VDDD voltage.
* To prevent propagating a false interrupt, before changing the threshold
* ensure that the LVD block itself and LVD interrupt are disabled by the
* \ref Cy_LVD_Disable and \ref Cy_LVD_ClearInterruptMask functions
* correspondingly.
*
* \param threshold
* Threshold selection for Low Voltage Detect circuit, \ref cy_en_lvd_tripsel_t.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_SetThreshold(cy_en_lvd_tripsel_t threshold)
{
CY_ASSERT_L3(CY_LVD_CHECK_TRIPSEL(threshold));
SRSS->PWR_LVD_CTL = _CLR_SET_FLD32U(SRSS->PWR_LVD_CTL, SRSS_PWR_LVD_CTL_HVLVD1_TRIPSEL, threshold);
}
/*******************************************************************************
* Function Name: Cy_LVD_GetStatus
****************************************************************************//**
*
* Returns the status of LVD.
* SRSS LVD Status Register (PWR_LVD_STATUS).
*
* \return LVD status, \ref cy_en_lvd_status_t.
*
*******************************************************************************/
__STATIC_INLINE cy_en_lvd_status_t Cy_LVD_GetStatus(void)
{
return ((cy_en_lvd_status_t) _FLD2VAL(SRSS_PWR_LVD_STATUS_HVLVD1_OK, SRSS->PWR_LVD_STATUS));
}
/*******************************************************************************
* Function Name: Cy_LVD_GetInterruptStatus
****************************************************************************//**
*
* Returns the status of LVD interrupt.
* SRSS Interrupt Register (SRSS_INTR).
*
* \return SRSS Interrupt status, \ref CY_LVD_INTR.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptStatus(void)
{
return (SRSS->SRSS_INTR & SRSS_SRSS_INTR_HVLVD1_Msk);
}
/*******************************************************************************
* Function Name: Cy_LVD_ClearInterrupt
****************************************************************************//**
*
* Clears LVD interrupt.
* SRSS Interrupt Register (SRSS_INTR).
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_ClearInterrupt(void)
{
SRSS->SRSS_INTR = SRSS_SRSS_INTR_HVLVD1_Msk;
(void) SRSS->SRSS_INTR;
}
/*******************************************************************************
* Function Name: Cy_LVD_SetInterrupt
****************************************************************************//**
*
* Triggers the device to generate interrupt for LVD.
* SRSS Interrupt Set Register (SRSS_INTR_SET).
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_SetInterrupt(void)
{
SRSS->SRSS_INTR_SET = SRSS_SRSS_INTR_SET_HVLVD1_Msk;
}
/*******************************************************************************
* Function Name: Cy_LVD_GetInterruptMask
****************************************************************************//**
*
* Returns the mask value of LVD interrupts.
* SRSS Interrupt Mask Register (SRSS_INTR_MASK).
*
* \return SRSS Interrupt Mask value, \ref CY_LVD_INTR.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptMask(void)
{
return (SRSS->SRSS_INTR_MASK & SRSS_SRSS_INTR_MASK_HVLVD1_Msk);
}
/*******************************************************************************
* Function Name: Cy_LVD_SetInterruptMask
****************************************************************************//**
*
* Enables LVD interrupts.
* Sets the LVD interrupt mask in the SRSS_INTR_MASK register.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_SetInterruptMask(void)
{
SRSS->SRSS_INTR_MASK |= SRSS_SRSS_INTR_MASK_HVLVD1_Msk;
}
/*******************************************************************************
* Function Name: Cy_LVD_ClearInterruptMask
****************************************************************************//**
*
* Disables LVD interrupts.
* Clears the LVD interrupt mask in the SRSS_INTR_MASK register.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_ClearInterruptMask(void)
{
SRSS->SRSS_INTR_MASK &= (uint32_t) ~SRSS_SRSS_INTR_MASK_HVLVD1_Msk;
}
/*******************************************************************************
* Function Name: Cy_LVD_GetInterruptStatusMasked
****************************************************************************//**
*
* Returns the masked interrupt status which is a bitwise AND between the
* interrupt status and interrupt mask registers.
* SRSS Interrupt Masked Register (SRSS_INTR_MASKED).
*
* \return SRSS Interrupt Masked value, \ref CY_LVD_INTR.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptStatusMasked(void)
{
return (SRSS->SRSS_INTR_MASKED & SRSS_SRSS_INTR_MASKED_HVLVD1_Msk);
}
/*******************************************************************************
* Function Name: Cy_LVD_SetInterruptConfig
****************************************************************************//**
*
* Sets a configuration for LVD interrupt.
* SRSS Interrupt Configuration Register (SRSS_INTR_CFG).
*
* \param lvdInterruptConfig \ref cy_en_lvd_intr_config_t.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_SetInterruptConfig(cy_en_lvd_intr_config_t lvdInterruptConfig)
{
CY_ASSERT_L3(CY_LVD_CHECK_INTR_CFG(lvdInterruptConfig));
SRSS->SRSS_INTR_CFG = _CLR_SET_FLD32U(SRSS->SRSS_INTR_CFG, SRSS_SRSS_INTR_CFG_HVLVD1_EDGE_SEL, lvdInterruptConfig);
}
/** \} group_lvd_functions */
#ifdef __cplusplus
}
#endif
#endif /* CY_LVD_H */
/** \} group_lvd */
/* [] END OF FILE */

View File

@ -0,0 +1,191 @@
/***************************************************************************//**
* \file cy_mcwdt.c
* \version 1.10.1
*
* Description:
* Provides a system API for the MCWDT driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "cy_mcwdt.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* Function Name: Cy_MCWDT_Init
****************************************************************************//**
*
* Initializes the MCWDT block.
*
* \param base
* The base pointer to a structure that describes the registers.
*
* \param config
* The pointer to a structure that contains component configuration data.
*
* \return cy_en_mcwdt_status_t
* *base checking result. If the pointer is NULL, returns error.
*
* \note
* This API should not be called when the counters are running. Prior to calling
* this API the counter should be disabled.
*
*******************************************************************************/
cy_en_mcwdt_status_t Cy_MCWDT_Init(MCWDT_STRUCT_Type *base, cy_stc_mcwdt_config_t const *config)
{
cy_en_mcwdt_status_t ret = CY_MCWDT_BAD_PARAM;
if ((base != NULL) && (config != NULL))
{
CY_ASSERT_L2(CY_MCWDT_IS_MATCH_VALID(config->c0ClearOnMatch, config->c0Match));
CY_ASSERT_L2(CY_MCWDT_IS_MATCH_VALID(config->c1ClearOnMatch, config->c1Match));
CY_ASSERT_L2(CY_MCWDT_IS_BIT_VALID(config->c2ToggleBit));
CY_ASSERT_L3(CY_MCWDT_IS_MODE_VALID((cy_en_mcwdtmode_t)config->c0Mode));
CY_ASSERT_L3(CY_MCWDT_IS_MODE_VALID((cy_en_mcwdtmode_t)config->c1Mode));
CY_ASSERT_L3(CY_MCWDT_IS_MODE_VALID((cy_en_mcwdtmode_t)config->c2Mode));
base->MCWDT_MATCH = _VAL2FLD(MCWDT_STRUCT_MCWDT_MATCH_WDT_MATCH1, config->c1Match) |
_VAL2FLD(MCWDT_STRUCT_MCWDT_MATCH_WDT_MATCH0, config->c0Match);
base->MCWDT_CONFIG = _VAL2FLD(MCWDT_STRUCT_MCWDT_CONFIG_WDT_BITS2, config->c2ToggleBit) |
_VAL2FLD(MCWDT_STRUCT_MCWDT_CONFIG_WDT_MODE2, config->c2Mode) |
_VAL2FLD(MCWDT_STRUCT_MCWDT_CONFIG_WDT_CLEAR0, config->c0ClearOnMatch) |
_VAL2FLD(MCWDT_STRUCT_MCWDT_CONFIG_WDT_CLEAR1, config->c1ClearOnMatch) |
(config->c1c2Cascade ? MCWDT_STRUCT_MCWDT_CONFIG_WDT_CASCADE1_2_Msk : 0UL) |
_VAL2FLD(MCWDT_STRUCT_MCWDT_CONFIG_WDT_MODE1, config->c1Mode) |
(config->c0c1Cascade ? MCWDT_STRUCT_MCWDT_CONFIG_WDT_CASCADE0_1_Msk : 0UL) |
_VAL2FLD(MCWDT_STRUCT_MCWDT_CONFIG_WDT_MODE0, config->c0Mode);
ret = CY_MCWDT_SUCCESS;
}
return (ret);
}
/*******************************************************************************
* Function Name: Cy_MCWDT_DeInit
****************************************************************************//**
*
* De-initializes the MCWDT block, returns register values to their default state.
*
* \param base
* The base pointer to a structure that describes the registers.
*
* \note
* This API should not be called when the counters are running. Prior to calling
* this API the counter should be disabled.
*
*******************************************************************************/
void Cy_MCWDT_DeInit(MCWDT_STRUCT_Type *base)
{
Cy_MCWDT_Unlock(base);
base->MCWDT_CNTLOW = 0UL;
base->MCWDT_CNTHIGH = 0UL;
base->MCWDT_MATCH = 0UL;
base->MCWDT_CONFIG = 0UL;
base->MCWDT_CTL = 0UL;
base->MCWDT_INTR = 0UL;
base->MCWDT_INTR_SET = 0UL;
base->MCWDT_INTR_MASK = 0UL;
}
/*******************************************************************************
* Function Name: Cy_MCWDT_GetCountCascaded
****************************************************************************//**
*
* Reports the current value of combined C1-C0 cascaded counters.
*
* \param base
* The base pointer to a structure that describes the registers.
*
* \note
* The user must enable both counters, and cascade C0 to C1,
* before calling this function. C2 is not reported.
* Instead, to get a 64-bit C2-C1-C0 cascaded value, the
* user must call this function followed by
* Cy_MCWDT_GetCount(base, CY_MCWDT_COUNTER2), and then combine the results.
* \note This function does not return the correct result when it is called
* after the Cy_MCWDT_Enable() or Cy_MCWDT_ResetCounters() function with
* a delay less than two lf_clk cycles. The recommended waitUs parameter
* value is 100 us.
*
*******************************************************************************/
uint32_t Cy_MCWDT_GetCountCascaded(MCWDT_STRUCT_Type const *base)
{
uint32_t countVal = base->MCWDT_CNTLOW;
uint32_t counter1 = countVal >> MCWDT_STRUCT_MCWDT_CNTLOW_WDT_CTR1_Pos;
uint32_t counter0 = countVal & MCWDT_STRUCT_MCWDT_CNTLOW_WDT_CTR0_Msk;
uint32_t match0 = _FLD2VAL(MCWDT_STRUCT_MCWDT_MATCH_WDT_MATCH0, base->MCWDT_MATCH);
uint32_t match1 = _FLD2VAL(MCWDT_STRUCT_MCWDT_MATCH_WDT_MATCH1, base->MCWDT_MATCH);
/*
* The counter counter0 goes to zero when it reaches the match0
* value (c0ClearOnMatch = 1) or reaches the maximum
* value (c0ClearOnMatch = 0). The counter counter1 increments on
* the next rising edge of the MCWDT clock after
* the Clear On Match event takes place.
* The software increments counter1 to eliminate the case
* when the both counter0 and counter1 counters have zeros.
*/
if (0u == counter0)
{
counter1++;
}
/* Check if the counter0 is Free running */
if (0u == _FLD2VAL(MCWDT_STRUCT_MCWDT_CONFIG_WDT_CLEAR0, base->MCWDT_CONFIG))
{
/* Save match0 value with the correction when counter0
* goes to zero when it reaches the match0 value.
*/
countVal = match0 + 1u;
if (0u < counter1)
{
/* Set match to the maximum value */
match0 = MCWDT_STRUCT_MCWDT_CNTLOW_WDT_CTR0_Msk;
}
if (countVal < counter0)
{
/* Decrement counter1 when the counter0 is great than match0 value */
counter1--;
}
}
/* Add the correction to counter0 */
counter0 += counter1;
/* Set counter1 match value to 65535 when the counter1 is free running */
if (0u == _FLD2VAL(MCWDT_STRUCT_MCWDT_CONFIG_WDT_CLEAR1, base->MCWDT_CONFIG))
{
match1 = MCWDT_STRUCT_MCWDT_CNTLOW_WDT_CTR1_Msk >> MCWDT_STRUCT_MCWDT_CNTLOW_WDT_CTR1_Pos;
}
/* Check for overflow */
if (match1 < counter1)
{
counter1 = 0u;
}
/* Calculate the combined value for C1-C0 cascaded counters */
countVal = counter0 + (counter1 * match0);
return (countVal);
}
#if defined(__cplusplus)
}
#endif
/* [] END OF FILE */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,238 @@
/***************************************************************************//**
* \file cy_pdm_pcm.c
* \version 2.10
*
* The source code file for the PDM_PCM driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "cy_pdm_pcm.h"
/* The C binding of definitions if building with the C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif
/**
* \addtogroup group_pdm_pcm_functions
* \{
*/
/******************************************************************************
* Function Name: Cy_PDM_PCM_Init
***************************************************************************//**
*
* Initialize the PDM-PCM module
*
* \pre If the PDM-PCM module is initialized previously, the
* \ref Cy_PDM_PCM_DeInit() must be called before calling this function.
*
* \param base The pointer to the PDM-PCM instance address
* \param config The pointer to a configuration structure.
* \return error / status code. See \ref cy_en_pdm_pcm_status_t.
*
* An example of a configuration structure:
* \snippet PDM_PCM_PDL_sut_00.cydsn/main_cm4.c PDM_PCM Configuration
*
*******************************************************************************/
cy_en_pdm_pcm_status_t Cy_PDM_PCM_Init(PDM_Type * base, cy_stc_pdm_pcm_config_t const * config)
{
cy_en_pdm_pcm_status_t ret = CY_PDM_PCM_BAD_PARAM;
if((NULL != base) && (NULL != config))
{
CY_ASSERT_L3(CY_PDM_PCM_IS_CLK_DIV_VALID(config->clkDiv));
CY_ASSERT_L3(CY_PDM_PCM_IS_CLK_DIV_VALID(config->mclkDiv));
CY_ASSERT_L3(CY_PDM_PCM_IS_CKO_CLOCK_DIV_VALID(config->ckoDiv));
CY_ASSERT_L3(CY_PDM_PCM_IS_SINC_RATE_VALID(config->sincDecRate));
CY_ASSERT_L3(CY_PDM_PCM_IS_GAIN_VALID(config->gainRight));
CY_ASSERT_L3(CY_PDM_PCM_IS_GAIN_VALID(config->gainLeft));
CY_ASSERT_L3(CY_PDM_PCM_IS_STEP_SEL_VALID(config->softMuteFineGain));
CY_ASSERT_L3(CY_PDM_PCM_IS_CH_SET_VALID(config->chanSelect));
CY_ASSERT_L3(CY_PDM_PCM_IS_S_CYCLES_VALID(config->softMuteCycles));
CY_ASSERT_L3(CY_PDM_PCM_IS_CKO_DELAY_VALID(config->ckoDelay));
CY_ASSERT_L3(CY_PDM_PCM_IS_HPF_GAIN_VALID(config->highPassFilterGain));
CY_ASSERT_L3(CY_PDM_PCM_IS_WORD_LEN_VALID(config->wordLen));
CY_ASSERT_L3(CY_PDM_PCM_IS_TRIG_LEVEL(config->rxFifoTriggerLevel, config->chanSelect));
ret = CY_PDM_PCM_SUCCESS;
base->CTL &= (uint32_t) ~PDM_CTL_ENABLED_Msk; /* Disable the PDM_PCM block */
/* The clock setting */
base->CLOCK_CTL = _VAL2FLD(PDM_CLOCK_CTL_CLK_CLOCK_DIV, config->clkDiv) |
_VAL2FLD(PDM_CLOCK_CTL_MCLKQ_CLOCK_DIV, config->mclkDiv) |
_VAL2FLD(PDM_CLOCK_CTL_CKO_CLOCK_DIV, config->ckoDiv) |
_VAL2FLD(PDM_CLOCK_CTL_SINC_RATE, config->sincDecRate);
/* Enable the PDM-PCM block */
base->CTL = _VAL2FLD(PDM_CTL_PGA_R, config->gainRight) |
_VAL2FLD(PDM_CTL_PGA_L, config->gainLeft) |
_VAL2FLD(PDM_CTL_STEP_SEL, config->softMuteFineGain) |
_BOOL2FLD(PDM_CTL_SOFT_MUTE, config->softMuteEnable) |
_BOOL2FLD(PDM_CTL_ENABLED, true);
base->MODE_CTL = _VAL2FLD(PDM_MODE_CTL_PCM_CH_SET, config->chanSelect) |
_BOOL2FLD(PDM_MODE_CTL_SWAP_LR, config->chanSwapEnable) |
_VAL2FLD(PDM_MODE_CTL_S_CYCLES, config->softMuteCycles) |
_VAL2FLD(PDM_MODE_CTL_CKO_DELAY, config->ckoDelay) |
_VAL2FLD(PDM_MODE_CTL_HPF_GAIN, config->highPassFilterGain) |
_BOOL2FLD(PDM_MODE_CTL_HPF_EN_N, config->highPassDisable);
base->DATA_CTL = _VAL2FLD(PDM_DATA_CTL_WORD_LEN, config->wordLen) |
_BOOL2FLD(PDM_DATA_CTL_BIT_EXTENSION, config->signExtension);
base->RX_FIFO_CTL = _VAL2FLD(PDM_RX_FIFO_CTL_TRIGGER_LEVEL, config->rxFifoTriggerLevel);
base->TR_CTL = _BOOL2FLD(PDM_TR_CTL_RX_REQ_EN, config->dmaTriggerEnable);
Cy_PDM_PCM_SetInterruptMask(base, config->interruptMask);
}
return (ret);
}
/*******************************************************************************
* Function Name: Cy_PDM_PCM_DeInit
****************************************************************************//**
*
* Uninitializes the PDM-PCM module.
*
* \param base The pointer to the PDM-PCM instance address.
*
*******************************************************************************/
void Cy_PDM_PCM_DeInit(PDM_Type * base)
{
base->CMD = 0UL; /* Stop PDM-PCM operation */
base->INTR_MASK = 0UL; /* Disable interrupts */
base->RX_FIFO_CTL = 0UL;
base->TR_CTL = 0UL;
base->DATA_CTL = 0UL;
base->MODE_CTL = CY_PDM_PCM_MODE_CTL_DEFAULT;
base->CTL = CY_PDM_PCM_CTL_DEFAULT; /* Disable the PDM_PCM IP block */
base->CLOCK_CTL = CY_PDM_PCM_CLOCK_CTL_DEFAULT; /* The default clock settings */
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_SetGain
***************************************************************************//**
*
* Sets the gain factor to the left or right channel.
*
* \param base
* The pointer to the PDM-PCM instance address.
*
* \param chan
* The channel selector for gain setting \ref cy_en_pdm_pcm_chan_select_t.
*
* \param gain
* Gain for the selected channel \ref cy_en_pdm_pcm_gain_t.
*
******************************************************************************/
void Cy_PDM_PCM_SetGain(PDM_Type * base, cy_en_pdm_pcm_chan_select_t chan, cy_en_pdm_pcm_gain_t gain)
{
CY_ASSERT_L3(CY_PDM_PCM_IS_CHAN_VALID(chan));
CY_ASSERT_L3(CY_PDM_PCM_IS_GAIN_VALID(gain));
if (chan == CY_PDM_PCM_CHAN_LEFT)
{
base->CTL = _CLR_SET_FLD32U(base->CTL, PDM_CTL_PGA_L, ((uint32_t) gain));
}
else
{
base->CTL = _CLR_SET_FLD32U(base->CTL, PDM_CTL_PGA_R, ((uint32_t) gain));
}
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_GetGain
***************************************************************************//**
*
* Retrieves the current gain factor of the left or right channel.
*
* \param base
* the pointer to the PDM-PCM instance address.
*
* \param chan
* The channel selector for gain setting \ref cy_en_pdm_pcm_chan_select_t.
*
* \return
* Gain of the selected channel \ref cy_en_pdm_pcm_gain_t.
*
******************************************************************************/
cy_en_pdm_pcm_gain_t Cy_PDM_PCM_GetGain(PDM_Type const * base, cy_en_pdm_pcm_chan_select_t chan)
{
cy_en_pdm_pcm_gain_t ret;
CY_ASSERT_L3(CY_PDM_PCM_IS_CHAN_VALID(chan));
if (chan == CY_PDM_PCM_CHAN_LEFT)
{
ret = (cy_en_pdm_pcm_gain_t) (_FLD2VAL(PDM_CTL_PGA_L, base->CTL));
}
else
{
ret = (cy_en_pdm_pcm_gain_t) (_FLD2VAL(PDM_CTL_PGA_R, base->CTL));
}
return (ret);
}
/*******************************************************************************
* Function Name: Cy_PDM_PCM_DeepSleepCallback
****************************************************************************//**
*
* This is an example callback function that can be used at the application layer to
* manage the PDM-PCM operation before entering and after exiting Deep-Sleep mode.
*
* \param callbackParams
* The structure with the syspm callback parameters,
* see \ref cy_stc_syspm_callback_params_t.
*
* \return
* syspm return status, see \ref cy_en_syspm_status_t
*
*******************************************************************************/
cy_en_syspm_status_t Cy_PDM_PCM_DeepSleepCallback(cy_stc_syspm_callback_params_t * callbackParams)
{
cy_en_syspm_status_t ret = CY_SYSPM_SUCCESS;
switch(callbackParams->mode)
{
case CY_SYSPM_CHECK_READY:
case CY_SYSPM_CHECK_FAIL:
break;
case CY_SYSPM_BEFORE_TRANSITION:
Cy_PDM_PCM_Disable((PDM_Type*) callbackParams->base); /* Stop PDM-PCM operation */
/* Unload FIFO to do not lost any data (if needed) */
break;
case CY_SYSPM_AFTER_TRANSITION:
Cy_PDM_PCM_ClearFifo((PDM_Type*) callbackParams->base); /* Clear FIFO */
Cy_PDM_PCM_Enable((PDM_Type*) callbackParams->base); /* Start PDM-PCM operation */
break;
default:
ret = CY_SYSPM_FAIL;
break;
}
return(ret);
}
/** \} group_pdm_pcm_functions */
#ifdef __cplusplus
}
#endif
/* [] END OF FILE */

View File

@ -0,0 +1,769 @@
/***************************************************************************//**
* \file cy_pdm_pcm.h
* \version 2.10
*
* The header file of the PDM_PCM driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
/**
* \defgroup group_pdm_pcm PDM-PCM Converter (PDM_PCM)
* \{
*
* The pulse-density modulation to pulse-code modulation (PDM-PCM) driver provides an
* API to manage PDM-PCM conversion. A PDM-PCM converter is used
* to convert 1-bit digital audio streaming data to PCM data.
*
* Features:
* * Supports FIFO buffer for Incoming Data
* * Supports Software Mute Mode
* * Programmable Gain Settings
* * Programmable Word Length
*
* Pulse-density modulation, or PDM, represents
* an analog signal with a binary signal. In a PDM signal, specific amplitude values
* are not encoded into codewords of pulses of different weight as they would be
* in pulse-code modulation (PCM); rather, the relative density of the pulses corresponds
* to the analog signal's amplitude. The output of a 1-bit DAC is the same
* as the PDM encoding of the signal.
*
* Pulse-code modulation (PCM) is the method used to digitally represent sampled analog signals.
* It is the standard form of digital audio in computers, compact discs, digital telephony,
* and other digital audio applications. In a PCM stream, the amplitude of the analog signal
* is sampled regularly at uniform intervals, and each sample is quantized
* to the nearest value within a range of digital steps.
*
* \section group_pdm_pcm_configuration_considerations Configuration Considerations
*
* To set up a PDM-PCM, provide the configuration parameters in the
* \ref cy_stc_pdm_pcm_config_t structure.
*
* For example, set dataStreamingEnable to true, configure rxFifoTriggerLevel,
* dmaTriggerEnable (depending on whether DMA is going to be used),
* provide clock settings (clkDiv, mclkDiv and ckoDiv), set sincDecRate
* to the appropriate decimation rate, wordLen, and wordBitExtension.
* No other parameters are necessary for this example.
*
* To initialize the PDM-PCM block, call the \ref Cy_PDM_PCM_Init function, providing the
* filled \ref cy_stc_pdm_pcm_config_t structure.
*
* If you use a DMA, the DMA channel should be previously configured. PDM-PCM interrupts
* (if applicable) can be enabled by calling \ref Cy_PDM_PCM_SetInterruptMask.
*
* For example, if the trigger interrupt is used during operation, the ISR
* should call the \ref Cy_PDM_PCM_ReadFifo as many times as required for your
* FIFO payload. Then call \ref Cy_PDM_PCM_ClearInterrupt with appropriate parameters.
*
* If a DMA is used and the DMA channel is properly configured, no CPU activity
* (or application code) is needed for PDM-PCM operation.
*
* \section group_pdm_pcm_more_information More Information
* See: the PDM-PCM chapter of the device technical reference manual (TRM);
* the PDM_PCM_PDL Component datasheet;
* CE219431 - PSOC 6 MCU PDM-TO-PCM EXAMPLE.
*
* \section group_pdm_pcm_MISRA MISRA-C Compliance
* The PDM-PCM 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>10.3</td>
* <td>R</td>
* <td>A composite expression of the "essentially unsigned" type is
* cast to a different type category.</td>
* <td>The value got from the bitfield physically can't exceed the enumeration
* that describes this bitfield. So the code is safe by design.</td>
* </tr>
* <tr>
* <td>11.4</td>
* <td>A</td>
* <td>A cast should not be performed between a pointer to the object type and
* a different pointer to the object type.</td>
* <td>The function \ref Cy_I2S_DeepSleepCallback is a callback of
* \ref cy_en_syspm_status_t type. The cast operation safety in this
* function becomes the user responsibility because the pointer is
* initialized when a callback is registered in SysPm driver.</td>
* </tr>
* </table>
*
* \section group_pdm_pcm_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>2.10</td>
* <td>The gain values in range +4.5...+10.5dB (5 items) of /ref cy_en_pdm_pcm_gain_t are corrected.
* Added Low Power Callback section.</td>
* <td>Incorrect setting of gain values in limited range.
* Documentation update and clarification.</td>
* </tr>
* <tr>
* <td>2.0</td>
* <td>Enumeration types for gain and soft mute cycles are added.<br>
* Function parameter checks are added.<br>
* The next functions are removed:
* * Cy_PDM_PCM_EnterLowPowerCallback
* * Cy_PDM_PCM_ExitLowPowerCallback
* * Cy_PDM_PCM_EnableDataStream
* * Cy_PDM_PCM_DisableDataStream
* * Cy_PDM_PCM_SetFifoLevel
* * Cy_PDM_PCM_GetFifoLevel
* * Cy_PDM_PCM_EnableDmaRequest
* * Cy_PDM_PCM_DisableDmaRequest
*
* The next functions behaviour are modified:
* * Cy_PDM_PCM_Enable
* * Cy_PDM_PCM_Disable
* * Cy_PDM_PCM_SetInterruptMask
* * Cy_PDM_PCM_GetInterruptMask
* * Cy_PDM_PCM_GetInterruptStatusMasked
* * Cy_PDM_PCM_GetInterruptStatus
* * Cy_PDM_PCM_ClearInterrupt
* * Cy_PDM_PCM_SetInterrupt
*
* The Cy_PDM_PCM_GetFifoNumWords function is renamed to Cy_PDM_PCM_GetNumInFifo.<br>
* The Cy_PDM_PCM_GetCurrentState function is added.
* </td>
* <td>Improvements based on usability feedbacks.<br>
* API is reworked for consistency within the PDL.
* </td>
* </tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_pdm_pcm_macros Macros
* \defgroup group_pdm_pcm_functions Functions
* \{
* \defgroup group_pdm_pcm_functions_syspm_callback Low Power Callback
* \}
* \defgroup group_pdm_pcm_data_structures Data Structures
* \defgroup group_pdm_pcm_enums Enumerated Types
*
*/
#if !defined(CY_PDM_PCM_H__)
#define CY_PDM_PCM_H__
/******************************************************************************/
/* Include files */
/******************************************************************************/
#include "cy_device_headers.h"
#include "syslib/cy_syslib.h"
#include "syspm/cy_syspm.h"
#include <stddef.h>
#include <stdbool.h>
#ifndef CY_IP_MXAUDIOSS
#error "The PDM-PCM driver is not supported on this device"
#endif
/* The C binding of definitions if building with the C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif
/******************************************************************************
* Global definitions
******************************************************************************/
/* Macros */
/**
* \addtogroup group_pdm_pcm_macros
* \{
*/
/** The driver major version */
#define CY_PDM_PCM_DRV_VERSION_MAJOR 2
/** The driver minor version */
#define CY_PDM_PCM_DRV_VERSION_MINOR 10
/** The PDM-PCM driver identifier */
#define CY_PDM_PCM_ID CY_PDL_DRV_ID(0x26u)
/**
* \defgroup group_pdm_pcm_macros_intrerrupt_masks Interrupt Masks
* \{
*/
/** Bit 16: More entries in the RX FIFO than specified by Trigger Level. */
#define CY_PDM_PCM_INTR_RX_TRIGGER (PDM_INTR_RX_TRIGGER_Msk)
/** Bit 18: RX FIFO is not empty. */
#define CY_PDM_PCM_INTR_RX_NOT_EMPTY (PDM_INTR_RX_NOT_EMPTY_Msk)
/** Bit 21: Attempt to write to a full RX FIFO. */
#define CY_PDM_PCM_INTR_RX_OVERFLOW (PDM_INTR_RX_OVERFLOW_Msk)
/** Bit 22: Attempt to read from an empty RX FIFO. */
#define CY_PDM_PCM_INTR_RX_UNDERFLOW (PDM_INTR_RX_UNDERFLOW_Msk)
/** \} group_pdm_pcm_macros_intrerrupt_masks */
/** \} group_pdm_pcm_macros */
/**
* \addtogroup group_pdm_pcm_enums
* \{
*/
/** PDM Word Length. */
typedef enum
{
CY_PDM_PCM_WLEN_16_BIT = 0U, /**< Word length: 16 bit. */
CY_PDM_PCM_WLEN_18_BIT = 1U, /**< Word length: 18 bit. */
CY_PDM_PCM_WLEN_20_BIT = 2U, /**< Word length: 20 bit. */
CY_PDM_PCM_WLEN_24_BIT = 3U /**< Word length: 24 bit. */
} cy_en_pdm_pcm_word_len_t;
/** PDM Clock Divider. */
typedef enum
{
CY_PDM_PCM_CLK_DIV_BYPASS = 0U, /**< Clock 1/1. */
CY_PDM_PCM_CLK_DIV_1_2 = 1U, /**< Clock 1/2 (no 50% duty cycle). */
CY_PDM_PCM_CLK_DIV_1_3 = 2U, /**< Clock 1/3 (no 50% duty cycle). */
CY_PDM_PCM_CLK_DIV_1_4 = 3U /**< Clock 1/4 (no 50% duty cycle). */
} cy_en_pdm_pcm_clk_div_t;
/** PDM Output Mode. */
typedef enum
{
CY_PDM_PCM_OUT_CHAN_LEFT = 1U, /**< Channel mono left. */
CY_PDM_PCM_OUT_CHAN_RIGHT = 2U, /**< Channel mono right. */
CY_PDM_PCM_OUT_STEREO = 3U /**< Channel stereo. */
} cy_en_pdm_pcm_out_t;
/** PDM Channel selector. */
typedef enum
{
CY_PDM_PCM_CHAN_LEFT = 0U, /**< Channel left. */
CY_PDM_PCM_CHAN_RIGHT = 1U /**< Channel right. */
} cy_en_pdm_pcm_chan_select_t;
/** PDM Gain. */
typedef enum
{
CY_PDM_PCM_ATTN_12_DB = 0U, /**< -12 dB (attenuation). */
CY_PDM_PCM_ATTN_10_5_DB = 1U, /**< -10.5 dB (attenuation). */
CY_PDM_PCM_ATTN_9_DB = 2U, /**< -9 dB (attenuation). */
CY_PDM_PCM_ATTN_7_5_DB = 3U, /**< -7.5 dB (attenuation). */
CY_PDM_PCM_ATTN_6_DB = 4U, /**< -6 dB (attenuation). */
CY_PDM_PCM_ATTN_4_5_DB = 5U, /**< -4.5 dB (attenuation). */
CY_PDM_PCM_ATTN_3_DB = 6U, /**< -3 dB (attenuation). */
CY_PDM_PCM_ATTN_1_5_DB = 7U, /**< -1.5 dB (attenuation). */
CY_PDM_PCM_BYPASS = 8U, /**< 0 dB (bypass). */
CY_PDM_PCM_GAIN_1_5_DB = 9U, /**< +1.5 dB (amplification). */
CY_PDM_PCM_GAIN_3_DB = 10U, /**< +3 dB (amplification). */
CY_PDM_PCM_GAIN_4_5_DB = 11U, /**< +4.5 dB (amplification). */
CY_PDM_PCM_GAIN_6_DB = 12U, /**< +6 dB (amplification). */
CY_PDM_PCM_GAIN_7_5_DB = 13U, /**< +7.5 dB (amplification). */
CY_PDM_PCM_GAIN_9_DB = 14U, /**< +9 dB (amplification). */
CY_PDM_PCM_GAIN_10_5_DB = 15U /**< +10.5 dB (amplification). */
} cy_en_pdm_pcm_gain_t;
/** The time step for gain change during PGA or soft mute operation in
* number of 1/a sampling rate. */
typedef enum
{
CY_PDM_PCM_SOFT_MUTE_CYCLES_64 = 0U, /**< 64 steps. */
CY_PDM_PCM_SOFT_MUTE_CYCLES_96 = 1U, /**< 96 steps. */
CY_PDM_PCM_SOFT_MUTE_CYCLES_128 = 2U, /**< 128 steps. */
CY_PDM_PCM_SOFT_MUTE_CYCLES_160 = 3U, /**< 160 steps. */
CY_PDM_PCM_SOFT_MUTE_CYCLES_192 = 4U, /**< 192 steps. */
CY_PDM_PCM_SOFT_MUTE_CYCLES_256 = 5U, /**< 256 steps. */
CY_PDM_PCM_SOFT_MUTE_CYCLES_384 = 6U, /**< 384 steps. */
CY_PDM_PCM_SOFT_MUTE_CYCLES_512 = 7U /**< 512 steps. */
} cy_en_pdm_pcm_s_cycles_t;
/** The PDM-PCM status codes. */
typedef enum
{
CY_PDM_PCM_SUCCESS = 0x00UL, /**< Success status code */
CY_PDM_PCM_BAD_PARAM = CY_PDM_PCM_ID | CY_PDL_STATUS_ERROR | 0x01UL /**< Bad parameter status code */
} cy_en_pdm_pcm_status_t;
/** \} group_pdm_pcm_enums */
/**
* \addtogroup group_pdm_pcm_data_structures
* \{
*/
/******************************************************************************
* Global type definitions
******************************************************************************/
/** PDM-PCM initialization configuration */
typedef struct
{
cy_en_pdm_pcm_clk_div_t clkDiv; /**< PDM Clock Divider (1st divider), see #cy_en_pdm_pcm_clk_div_t
This configures a frequency of PDM CLK. The configured frequency
is used to operate PDM core. I.e. the frequency is input to
MCLKQ_CLOCK_DIV register. */
cy_en_pdm_pcm_clk_div_t mclkDiv; /**< MCLKQ divider (2nd divider), see #cy_en_pdm_pcm_clk_div_t */
uint8_t ckoDiv; /**< PDM CKO (FPDM_CKO) clock divider (3rd divider):
- if CKO_CLOCK_DIV >= 1 - *F(PDM_CKO) = F(PDM_CLK / (mclkDiv + 1))
- if CKO_CLOCK_DIV = 0 - *F(PDM_CKO) = MCLKQ / 2 */
uint8_t ckoDelay; /**< Extra PDM_CKO delay to internal sampler:
- 0: Three extra PDM_CLK period advance
- 1: Two extra PDM_CLK period advance
- 2: One extra PDM_CLK period advance
- 3: No delay
- 4: One extra PDM_CLK period delay
- 5: Two extra PDM_CLK period delay
- 6: Three extra PDM_CLK period delay
- 7: Four extra PDM_CLK clock delay */
uint8_t sincDecRate; /**< F(MCLK_L_R) = Fs * 2 * sincDecRate * mclkDiv,
Fs is a sampling frequency, 8kHz - 48kHz */
cy_en_pdm_pcm_out_t chanSelect; /**< see #cy_en_pdm_pcm_out_t */
bool chanSwapEnable; /**< Audio channels swapping */
uint8_t highPassFilterGain; /**< High pass filter gain:
H(Z) = (1 - Z^-1) / (1 - (1 - 2^highPassFilterGain) * Z^-1) */
bool highPassDisable; /**< High pass filter disable */
cy_en_pdm_pcm_s_cycles_t softMuteCycles; /**< The time step for gain change during PGA or soft mute operation in
number of 1/a sampling rate, see #cy_en_pdm_pcm_s_cycles_t. */
uint32_t softMuteFineGain; /**< Soft mute fine gain: 0 = 0.13dB, 1 = 0.26dB */
bool softMuteEnable; /**< Soft mute enable */
cy_en_pdm_pcm_word_len_t wordLen; /**< see #cy_en_pdm_pcm_word_len_t */
bool signExtension; /**< Word extension type:
- 0: extension by zero
- 1: extension by sign bits */
cy_en_pdm_pcm_gain_t gainLeft; /**< Gain for left channel, see #cy_en_pdm_pcm_gain_t */
cy_en_pdm_pcm_gain_t gainRight; /**< Gain for right channel, see #cy_en_pdm_pcm_gain_t */
uint8_t rxFifoTriggerLevel; /**< Fifo interrupt trigger level (in words),
range: 0 - 253 for stereo and 0 - 254 for mono mode */
bool dmaTriggerEnable; /**< DMA trigger enable */
uint32_t interruptMask; /**< Interrupts enable mask */
} cy_stc_pdm_pcm_config_t;
/** \} group_pdm_pcm_data_structures */
/** \cond INTERNAL */
/******************************************************************************
* Local definitions
*******************************************************************************/
/** Define bit mask for all available interrupt sources */
#define CY_PDM_PCM_INTR_MASK (CY_PDM_PCM_INTR_RX_TRIGGER | \
CY_PDM_PCM_INTR_RX_NOT_EMPTY | \
CY_PDM_PCM_INTR_RX_OVERFLOW | \
CY_PDM_PCM_INTR_RX_UNDERFLOW)
/* Non-zero default values */
#define CY_PDM_PCM_CTL_PGA_R_DEFAULT (0x8U)
#define CY_PDM_PCM_CTL_PGA_L_DEFAULT (0x8U)
#define CY_PDM_PCM_CTL_STEP_SEL_DEFAULT (0x1U)
#define CY_PDM_PCM_CTL_DEFAULT (_VAL2FLD(PDM_CTL_PGA_R, CY_PDM_PCM_CTL_PGA_R_DEFAULT) | \
_VAL2FLD(PDM_CTL_PGA_L, CY_PDM_PCM_CTL_PGA_L_DEFAULT) | \
_VAL2FLD(PDM_CTL_STEP_SEL, CY_PDM_PCM_CTL_STEP_SEL_DEFAULT))
#define CY_PDM_PCM_CLOCK_CTL_MCLKQ_CLOCK_DIV_DEFAULT (0x1U)
#define CY_PDM_PCM_CLOCK_CTL_CKO_CLOCK_DIV_DEFAULT (0x3U)
#define CY_PDM_PCM_CLOCK_CTL_SINC_RATE_DEFAULT (0x20U)
#define CY_PDM_PCM_CLOCK_CTL_DEFAULT (_VAL2FLD(PDM_CLOCK_CTL_MCLKQ_CLOCK_DIV, CY_PDM_PCM_CLOCK_CTL_MCLKQ_CLOCK_DIV_DEFAULT) | \
_VAL2FLD(PDM_CLOCK_CTL_CKO_CLOCK_DIV, CY_PDM_PCM_CLOCK_CTL_CKO_CLOCK_DIV_DEFAULT) | \
_VAL2FLD(PDM_CLOCK_CTL_SINC_RATE, CY_PDM_PCM_CLOCK_CTL_SINC_RATE_DEFAULT))
#define CY_PDM_PCM_MODE_CTL_PCM_CH_SET_DEFAULT (0x3U)
#define CY_PDM_PCM_MODE_CTL_S_CYCLES_DEFAULT (0x1U)
#define CY_PDM_PCM_MODE_CTL_HPF_GAIN_DEFAULT (0xBU)
#define CY_PDM_PCM_MODE_CTL_HPF_EN_N_DEFAULT (0x1U)
#define CY_PDM_PCM_MODE_CTL_DEFAULT (_VAL2FLD(PDM_MODE_CTL_PCM_CH_SET, CY_PDM_PCM_MODE_CTL_PCM_CH_SET_DEFAULT) | \
_VAL2FLD(PDM_MODE_CTL_S_CYCLES, CY_PDM_PCM_MODE_CTL_S_CYCLES_DEFAULT) | \
_VAL2FLD(PDM_MODE_CTL_HPF_GAIN, CY_PDM_PCM_MODE_CTL_HPF_GAIN_DEFAULT) | \
_VAL2FLD(PDM_MODE_CTL_HPF_EN_N, CY_PDM_PCM_MODE_CTL_HPF_EN_N_DEFAULT))
/* Macros for conditions used by CY_ASSERT calls */
#define CY_PDM_PCM_IS_CLK_DIV_VALID(clkDiv) (((clkDiv) == CY_PDM_PCM_CLK_DIV_BYPASS) || \
((clkDiv) == CY_PDM_PCM_CLK_DIV_1_2) || \
((clkDiv) == CY_PDM_PCM_CLK_DIV_1_3) || \
((clkDiv) == CY_PDM_PCM_CLK_DIV_1_4))
#define CY_PDM_PCM_IS_CH_SET_VALID(chanSelect) (((chanSelect) == CY_PDM_PCM_OUT_CHAN_LEFT) || \
((chanSelect) == CY_PDM_PCM_OUT_CHAN_RIGHT) || \
((chanSelect) == CY_PDM_PCM_OUT_STEREO))
#define CY_PDM_PCM_IS_GAIN_VALID(gain) (((gain) == CY_PDM_PCM_ATTN_12_DB) || \
((gain) == CY_PDM_PCM_ATTN_10_5_DB) || \
((gain) == CY_PDM_PCM_ATTN_9_DB) || \
((gain) == CY_PDM_PCM_ATTN_7_5_DB) || \
((gain) == CY_PDM_PCM_ATTN_6_DB) || \
((gain) == CY_PDM_PCM_ATTN_4_5_DB) || \
((gain) == CY_PDM_PCM_ATTN_3_DB) || \
((gain) == CY_PDM_PCM_ATTN_1_5_DB) || \
((gain) == CY_PDM_PCM_BYPASS) || \
((gain) == CY_PDM_PCM_GAIN_1_5_DB) || \
((gain) == CY_PDM_PCM_GAIN_3_DB) || \
((gain) == CY_PDM_PCM_GAIN_4_5_DB) || \
((gain) == CY_PDM_PCM_GAIN_6_DB) || \
((gain) == CY_PDM_PCM_GAIN_7_5_DB) || \
((gain) == CY_PDM_PCM_GAIN_9_DB) || \
((gain) == CY_PDM_PCM_GAIN_10_5_DB))
#define CY_PDM_PCM_IS_WORD_LEN_VALID(wordLen) (((wordLen) == CY_PDM_PCM_WLEN_16_BIT) || \
((wordLen) == CY_PDM_PCM_WLEN_18_BIT) || \
((wordLen) == CY_PDM_PCM_WLEN_20_BIT) || \
((wordLen) == CY_PDM_PCM_WLEN_24_BIT))
#define CY_PDM_PCM_IS_CHAN_VALID(chan) (((chan) == CY_PDM_PCM_CHAN_LEFT) || \
((chan) == CY_PDM_PCM_CHAN_RIGHT))
#define CY_PDM_PCM_IS_S_CYCLES_VALID(sCycles) (((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_64) || \
((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_96) || \
((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_128) || \
((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_160) || \
((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_192) || \
((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_256) || \
((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_384) || \
((sCycles) == CY_PDM_PCM_SOFT_MUTE_CYCLES_512))
#define CY_PDM_PCM_IS_INTR_MASK_VALID(interrupt) (0UL == ((interrupt) & ((uint32_t) ~CY_PDM_PCM_INTR_MASK)))
#define CY_PDM_PCM_IS_SINC_RATE_VALID(sincRate) ((sincRate) <= 127U)
#define CY_PDM_PCM_IS_STEP_SEL_VALID(stepSel) ((stepSel) <= 1UL)
#define CY_PDM_PCM_IS_CKO_DELAY_VALID(ckoDelay) ((ckoDelay) <= 7U)
#define CY_PDM_PCM_IS_HPF_GAIN_VALID(hpfGain) ((hpfGain) <= 15U)
#define CY_PDM_PCM_IS_CKO_CLOCK_DIV_VALID(ckoDiv) (((ckoDiv) >= 1U) && ((ckoDiv) <= 15U))
#define CY_PDM_PCM_IS_TRIG_LEVEL(trigLevel, chanSelect) ((trigLevel) <= (((chanSelect) == CY_PDM_PCM_OUT_STEREO)? 253U : 254U))
/** \endcond */
/**
* \addtogroup group_pdm_pcm_functions
* \{
*/
cy_en_pdm_pcm_status_t Cy_PDM_PCM_Init(PDM_Type * base, cy_stc_pdm_pcm_config_t const * config);
void Cy_PDM_PCM_DeInit(PDM_Type * base);
void Cy_PDM_PCM_SetGain(PDM_Type * base, cy_en_pdm_pcm_chan_select_t chan, cy_en_pdm_pcm_gain_t gain);
cy_en_pdm_pcm_gain_t Cy_PDM_PCM_GetGain(PDM_Type const * base, cy_en_pdm_pcm_chan_select_t chan);
/** \addtogroup group_pdm_pcm_functions_syspm_callback
* The driver supports SysPm callback for Deep Sleep transition.
* \{
*/
cy_en_syspm_status_t Cy_PDM_PCM_DeepSleepCallback(cy_stc_syspm_callback_params_t * callbackParams);
/** \} */
__STATIC_INLINE void Cy_PDM_PCM_Enable(PDM_Type * base);
__STATIC_INLINE void Cy_PDM_PCM_Disable(PDM_Type * base);
__STATIC_INLINE void Cy_PDM_PCM_SetInterruptMask(PDM_Type * base, uint32_t interrupt);
__STATIC_INLINE uint32_t Cy_PDM_PCM_GetInterruptMask(PDM_Type const * base);
__STATIC_INLINE uint32_t Cy_PDM_PCM_GetInterruptStatusMasked(PDM_Type const * base);
__STATIC_INLINE uint32_t Cy_PDM_PCM_GetInterruptStatus(PDM_Type const * base);
__STATIC_INLINE void Cy_PDM_PCM_ClearInterrupt(PDM_Type * base, uint32_t interrupt);
__STATIC_INLINE void Cy_PDM_PCM_SetInterrupt(PDM_Type * base, uint32_t interrupt);
__STATIC_INLINE uint8_t Cy_PDM_PCM_GetNumInFifo(PDM_Type const * base);
__STATIC_INLINE void Cy_PDM_PCM_ClearFifo(PDM_Type * base);
__STATIC_INLINE uint32_t Cy_PDM_PCM_ReadFifo(PDM_Type const * base);
__STATIC_INLINE void Cy_PDM_PCM_EnableSoftMute(PDM_Type * base);
__STATIC_INLINE void Cy_PDM_PCM_DisableSoftMute(PDM_Type * base);
__STATIC_INLINE void Cy_PDM_PCM_FreezeFifo(PDM_Type * base);
__STATIC_INLINE void Cy_PDM_PCM_UnfreezeFifo(PDM_Type * base);
__STATIC_INLINE uint32_t Cy_PDM_PCM_ReadFifoSilent(PDM_Type const * base);
/** \} group_pdm_pcm_functions */
/**
* \addtogroup group_pdm_pcm_functions
* \{
*/
/******************************************************************************
* Function Name: Cy_PDM_PCM_Enable
***************************************************************************//**
*
* Enables the PDM-PCM data conversion.
*
* \param base The pointer to the PDM-PCM instance address.
*
******************************************************************************/
__STATIC_INLINE void Cy_PDM_PCM_Enable(PDM_Type * base)
{
base->CMD |= PDM_CMD_STREAM_EN_Msk;
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_Disable
***************************************************************************//**
*
* Disables the PDM-PCM data conversion.
*
* \param base The pointer to the PDM-PCM instance address.
*
******************************************************************************/
__STATIC_INLINE void Cy_PDM_PCM_Disable(PDM_Type * base)
{
base->CMD &= (uint32_t) ~PDM_CMD_STREAM_EN_Msk;
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_GetCurrentState
***************************************************************************//**
*
* Returns the current PDM-PCM state (running/stopped).
*
* \param base The pointer to the PDM-PCM instance address.
* \return The current state (CMD register).
*
******************************************************************************/
__STATIC_INLINE uint32_t Cy_PDM_PCM_GetCurrentState(PDM_Type const * base)
{
return (base->CMD);
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_SetInterruptMask
***************************************************************************//**
*
* Sets one or more PDM-PCM interrupt factor bits (sets the INTR_MASK register).
*
* \param base The pointer to the PDM-PCM instance address
* \param interrupt Interrupt bit mask \ref group_pdm_pcm_macros_intrerrupt_masks.
*
******************************************************************************/
__STATIC_INLINE void Cy_PDM_PCM_SetInterruptMask(PDM_Type * base, uint32_t interrupt)
{
CY_ASSERT_L2(CY_PDM_PCM_IS_INTR_MASK_VALID(interrupt));
base->INTR_MASK = interrupt;
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_GetInterruptMask
***************************************************************************//**
*
* Returns the PDM-PCM interrupt mask (a content of the INTR_MASK register).
*
* \param base The pointer to the PDM-PCM instance address.
* \return The interrupt bit mask \ref group_pdm_pcm_macros_intrerrupt_masks.
*
******************************************************************************/
__STATIC_INLINE uint32_t Cy_PDM_PCM_GetInterruptMask(PDM_Type const * base)
{
return (base->INTR_MASK);
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_GetInterruptStatusMasked
***************************************************************************//**
*
* Reports the status of enabled (masked) PDM-PCM interrupt sources.
* (an INTR_MASKED register).
*
* \param base The pointer to the PDM-PCM instance address.
* \return The interrupt bit mask \ref group_pdm_pcm_macros_intrerrupt_masks.
*
*****************************************************************************/
__STATIC_INLINE uint32_t Cy_PDM_PCM_GetInterruptStatusMasked(PDM_Type const * base)
{
return (base->INTR_MASKED);
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_GetInterruptStatus
***************************************************************************//**
*
* Reports the status of PDM-PCM interrupt sources (an INTR register).
*
* \param base The pointer to the PDM-PCM instance address.
* \return The interrupt bit mask \ref group_pdm_pcm_macros_intrerrupt_masks.
*
******************************************************************************/
__STATIC_INLINE uint32_t Cy_PDM_PCM_GetInterruptStatus(PDM_Type const * base)
{
return (base->INTR);
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_ClearInterrupt
***************************************************************************//**
*
* Clears one or more PDM-PCM interrupt statuses (sets an INTR register's bits).
*
* \param base The pointer to the PDM-PCM instance address
* \param interrupt
* The interrupt bit mask \ref group_pdm_pcm_macros_intrerrupt_masks.
*
******************************************************************************/
__STATIC_INLINE void Cy_PDM_PCM_ClearInterrupt(PDM_Type * base, uint32_t interrupt)
{
CY_ASSERT_L2(CY_PDM_PCM_IS_INTR_MASK_VALID(interrupt));
base->INTR = interrupt;
(void) base->INTR;
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_SetInterrupt
***************************************************************************//**
*
* Sets one or more interrupt source statuses (sets an INTR_SET register).
*
* \param base The pointer to the PDM-PCM instance address.
* \param interrupt
* The interrupt bit mask \ref group_pdm_pcm_macros_intrerrupt_masks.
*
******************************************************************************/
__STATIC_INLINE void Cy_PDM_PCM_SetInterrupt(PDM_Type * base, uint32_t interrupt)
{
CY_ASSERT_L2(CY_PDM_PCM_IS_INTR_MASK_VALID(interrupt));
base->INTR_SET = interrupt;
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_GetNumInFifo
***************************************************************************//**
*
* Reports the current number of used words in the output data FIFO.
*
* \param base The pointer to the PDM-PCM instance address.
* \return The current number of used FIFO words (range is 0 - 254).
*
******************************************************************************/
__STATIC_INLINE uint8_t Cy_PDM_PCM_GetNumInFifo(PDM_Type const * base)
{
return (uint8_t) (_FLD2VAL(PDM_RX_FIFO_STATUS_USED, base->RX_FIFO_STATUS));
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_ClearFifo
***************************************************************************//**
*
* Resets the output data FIFO, removing all data words from the FIFO.
*
* \param base The pointer to the PDM-PCM instance address.
*
******************************************************************************/
__STATIC_INLINE void Cy_PDM_PCM_ClearFifo(PDM_Type * base)
{
base->RX_FIFO_CTL |= PDM_RX_FIFO_CTL_CLEAR_Msk; /* clear FIFO and disable it */
base->RX_FIFO_CTL &= (uint32_t) ~PDM_RX_FIFO_CTL_CLEAR_Msk; /* enable FIFO */
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_ReadFifo
***************************************************************************//**
*
* Reads ("pops") one word from the output data FIFO.
*
* \param base The pointer to the PDM-PCM instance address.
* \return The data word.
*
******************************************************************************/
__STATIC_INLINE uint32_t Cy_PDM_PCM_ReadFifo(PDM_Type const * base)
{
return (base->RX_FIFO_RD);
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_EnableSoftMute
***************************************************************************//**
*
* Enables soft mute.
*
* \param base The pointer to the PDM-PCM instance address.
*
******************************************************************************/
__STATIC_INLINE void Cy_PDM_PCM_EnableSoftMute(PDM_Type * base)
{
base->CTL |= PDM_CTL_SOFT_MUTE_Msk;
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_DisableSoftMute
***************************************************************************//**
*
* Disables soft mute.
*
* \param base The pointer to the PDM-PCM instance address.
*
******************************************************************************/
__STATIC_INLINE void Cy_PDM_PCM_DisableSoftMute(PDM_Type * base)
{
base->CTL &= (uint32_t) ~PDM_CTL_SOFT_MUTE_Msk;
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_FreezeFifo
***************************************************************************//**
*
* Freezes the RX FIFO (Debug purpose).
*
* \param base The pointer to the PDM-PCM instance address.
*
******************************************************************************/
__STATIC_INLINE void Cy_PDM_PCM_FreezeFifo(PDM_Type * base)
{
base->RX_FIFO_CTL |= PDM_RX_FIFO_CTL_FREEZE_Msk;
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_UnfreezeFifo
***************************************************************************//**
*
* Unfreezes the RX FIFO (Debug purpose).
*
* \param base The pointer to the PDM-PCM instance address.
*
******************************************************************************/
__STATIC_INLINE void Cy_PDM_PCM_UnfreezeFifo(PDM_Type * base)
{
base->RX_FIFO_CTL &= (uint32_t) ~PDM_RX_FIFO_CTL_FREEZE_Msk;
}
/******************************************************************************
* Function Name: Cy_PDM_PCM_ReadFifoSilent
***************************************************************************//**
*
* Reads the RX FIFO silent (without touching the FIFO function).
*
* \param base Pointer to PDM-PCM instance address.
* \return FIFO value.
*
******************************************************************************/
__STATIC_INLINE uint32_t Cy_PDM_PCM_ReadFifoSilent(PDM_Type const * base)
{
return (base->RX_FIFO_RD_SILENT);
}
/** \} group_pdm_pcm_functions */
#ifdef __cplusplus
}
#endif /* of __cplusplus */
#endif /* CY_PDM_PCM_H__ */
/** \} group_pdm_pcm */
/* [] END OF FILE */

View File

@ -0,0 +1,426 @@
/***************************************************************************//**
* \file cy_profile.c
* \version 1.0
*
* Provides an API declaration of the energy profiler (EP) driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "cy_profile.h"
#include <string.h>
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/* Number of elements in an array */
#define CY_N_ELMTS(a) (sizeof(a)/sizeof((a)[0]))
static cy_en_profile_status_t Cy_Profile_IsPtrValid(const cy_stc_profile_ctr_ptr_t ctrAddr);
/* Internal structure - Control and status information for each counter */
static cy_stc_profile_ctr_t cy_ep_ctrs[PROFILE_PRFL_CNT_NR];
/* ========================================================================== */
/* ===================== LOCAL FUNCTION 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 cy_en_profile_status_t Cy_Profile_IsPtrValid(const cy_stc_profile_ctr_ptr_t ctrAddr)
{
cy_en_profile_status_t retStatus = 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 */
{
retStatus = CY_PROFILE_SUCCESS;
}
}
return (retStatus);
}
/* ========================================================================== */
/* ==================== 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 PROFILE FUNCTIONS ==================== */
/* ========================================================================== */
/*******************************************************************************
* Function Name: Cy_Profile_StartProfiling
****************************************************************************//**
*
* Starts the profiling/measurement window.
*
* This operation allows the enabled profile counters to start counting.
*
* \note The profile interrupt should be enabled before calling this function
* in order for the firmware to be notified when a counter overflow occurs.
*
* \funcusage
* \snippet profile/profile_v1_0_sut_01.cydsn/main_cm4.c snippet_Cy_Profile_StartProfiling
*
*******************************************************************************/
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 configurations and sets all counters and overflow counters
* to 0. Calls Cy_Profile_ClearCounters() to clear counter registers.
*
* \funcusage
* \snippet profile/profile_v1_0_sut_01.cydsn/main_cm4.c snippet_Cy_Profile_ClearConfiguration
*
*******************************************************************************/
void Cy_Profile_ClearConfiguration(void)
{
(void)memset((void *)cy_ep_ctrs, 0, sizeof(cy_ep_ctrs));
Cy_Profile_ClearCounters();
}
/*******************************************************************************
* Function Name: Cy_Profile_ConfigureCounter
****************************************************************************//**
*
* Configures and assigns a hardware profile counter to the list of used counters.
*
* This function assigns an available profile counter to a slot in the internal
* software data structure and returns the handle for that slot location. The data
* structure is used to keep track of the counter status and to implement a 64-bit
* profile counter. If no counter slots are available, the function returns a
* NULL pointer.
*
* \param monitor The monitor source number
*
* \param duration Events are monitored (0), or duration is monitored (1)
*
* \param refClk Counter reference clock
*
* \param weight Weighting factor for the counter value
*
* \return A pointer to the counter data structure. NULL if no counter is
* available.
*
* \funcusage
* \snippet profile/profile_v1_0_sut_01.cydsn/main_cm4.c snippet_Cy_Profile_ConfigureCounter
*
*******************************************************************************/
cy_stc_profile_ctr_ptr_t Cy_Profile_ConfigureCounter(en_ep_mon_sel_t monitor, cy_en_profile_duration_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 = 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 the assigned counter (returned by calling
* \ref Cy_Profile_ConfigureCounter()).
*
* \return
* Status of the operation.
*
* \note The counter is not disabled by this function.
*
* \funcusage
* \snippet profile/profile_v1_0_sut_01.cydsn/main_cm4.c snippet_Cy_Profile_FreeCounter
*
*******************************************************************************/
cy_en_profile_status_t Cy_Profile_FreeCounter(cy_stc_profile_ctr_ptr_t ctrAddr)
{
cy_en_profile_status_t retStatus = CY_PROFILE_BAD_PARAM;
retStatus = Cy_Profile_IsPtrValid(ctrAddr);
if (retStatus == CY_PROFILE_SUCCESS)
{
ctrAddr->used = 0u;
}
return (retStatus);
}
/*******************************************************************************
* 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 the assigned counter, (returned by calling
* \ref Cy_Profile_ConfigureCounter()).
*
* \return
* Status of the operation.
*
* \funcusage
* \snippet profile/profile_v1_0_sut_01.cydsn/main_cm4.c snippet_Cy_Profile_EnableCounter
*
*******************************************************************************/
cy_en_profile_status_t Cy_Profile_EnableCounter(cy_stc_profile_ctr_ptr_t ctrAddr)
{
cy_en_profile_status_t retStatus = CY_PROFILE_BAD_PARAM;
retStatus = Cy_Profile_IsPtrValid(ctrAddr);
if (retStatus == 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 (retStatus);
}
/*******************************************************************************
* 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 the assigned counter, (returned by calling
* \ref Cy_Profile_ConfigureCounter()).
*
* \return
* Status of the operation.
*
* \funcusage
* \snippet profile/profile_v1_0_sut_01.cydsn/main_cm4.c snippet_Cy_Profile_DisableCounter
*
*******************************************************************************/
cy_en_profile_status_t Cy_Profile_DisableCounter(cy_stc_profile_ctr_ptr_t ctrAddr)
{
cy_en_profile_status_t retStatus = Cy_Profile_IsPtrValid(ctrAddr);
if (retStatus == 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 (retStatus);
}
/* ========================================================================== */
/* ================== CALCULATION FUNCTIONS SECTION =================== */
/* ========================================================================== */
/*******************************************************************************
* Function Name: Cy_Profile_GetRawCount
****************************************************************************//**
*
* Reports the raw count value for a specified counter.
*
* \param ctrAddr The handle to the assigned counter, (returned by calling
* \ref Cy_Profile_ConfigureCounter()).
*
* \param result Output parameter used to write in the result.
*
* \return
* Status of the operation.
*
* \funcusage
* \snippet profile/profile_v1_0_sut_01.cydsn/main_cm4.c snippet_Cy_Profile_GetRawCount
*
*******************************************************************************/
cy_en_profile_status_t Cy_Profile_GetRawCount(cy_stc_profile_ctr_ptr_t ctrAddr, uint64_t *result)
{
cy_en_profile_status_t retStatus = Cy_Profile_IsPtrValid(ctrAddr);
if (retStatus == 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 (retStatus);
}
/*******************************************************************************
* Function Name: Cy_Profile_GetWeightedCount
****************************************************************************//**
*
* Reports the count value for a specified counter, multiplied by the weight
* factor for that counter.
*
* \param ctrAddr The handle to the assigned counter, (returned by calling
* \ref Cy_Profile_ConfigureCounter()).
*
* \param result Output parameter used to write in the result.
*
* \return
* Status of the operation.
*
* \funcusage
* \snippet profile/profile_v1_0_sut_01.cydsn/main_cm4.c snippet_Cy_Profile_GetWeightedCount
*
*******************************************************************************/
cy_en_profile_status_t Cy_Profile_GetWeightedCount(cy_stc_profile_ctr_ptr_t ctrAddr, uint64_t *result)
{
uint64_t temp;
cy_en_profile_status_t retStatus = Cy_Profile_GetRawCount(ctrAddr, &temp);
if (retStatus == CY_PROFILE_SUCCESS)
{
/* calculate weighted count */
*result = temp * (uint64_t)(ctrAddr->weight);
}
return (retStatus);
}
/*******************************************************************************
* Function Name: Cy_Profile_GetSumWeightedCounts
****************************************************************************//**
*
* Reports the weighted sum result of the first n number of counter count values
* starting from the specified profile counter data structure base address.
*
* Each count value is multiplied by its weighing factor before the summing
* operation is performed.
*
* \param ptrsArray Base address of the profile counter data structure
*
* \param numCounters Number of measured counters in ptrsArray[]
*
* \return
* The weighted sum of the specified counters
*
* \funcusage
* \snippet profile/profile_v1_0_sut_01.cydsn/main_cm4.c snippet_Cy_Profile_GetSumWeightedCounts
*
*******************************************************************************/
uint64_t Cy_Profile_GetSumWeightedCounts(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,456 @@
/***************************************************************************//**
* \file cy_profile.h
* \version 1.0
*
* Provides an API declaration of the energy profiler driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
/**
* \defgroup group_energy_profiler Energy Profiler (Profile)
* \{
*
* The energy profiler driver is an API for configuring and using the profile
* hardware block. The profile block enables measurement of the signal activity
* of select peripherals and monitor sources during a measurement window. Using
* these measurements, it is possible to construct a profile of the energy consumed
* in the device by scaling the individual peripheral actvities with appropriate
* scaling (weight) factors. This gives the application the ability to monitor
* the energy consumed by the internal resources with minimal CPU overhead and
* without external monitoring hardware.
*
* \section group_profile_details Details
*
* \subsection group_profile_hardware Profile Hardware
*
* The profile hardware consists of a number of profile counters that accept specific
* triggers for incrementing the count value. This allows the events of the source
* (such as the number of SCB0 bus accesses or the duration of time the BLE RX radio
* is active) to be counted during the measurement window. The available monitor
* sources in the device can be found in the en_ep_mon_sel_t enum in the device
* configuration file (e.g. psoc62_config.h). These can be sourced to any of the
* profile counters as triggers. There are two methods of using the monitor sources
* in a profile counter.
*
* - Event: The count value is incremented when a pulse event signal is seen by the
* counter. This type of monitoring is suitable when the monitoring source of
* interest needs to count the discrete events (such as the number of Flash read
* accesses) happening in the measurement window.
*
* - Duration: The count value is incremented at every clock edge while the monitor
* signal is high. This type of monitoring is suitable when a signal is active for
* a finite amount of time (such as the time the BLE TX radio is active) and the
* duration needs to be expressed as number of clock cycles in the measurement window.
*
* Many of the available monitor sources are suitable for event type monitoring.
* Using a duration type on these signals may not give valuable information. Review
* the device TRM for more information on the monitor sources and details on how they
* should be used.
*
* \subsection group_profile_measurement_types Measurement Types
*
* Depending on the item of interest, energy measurement can be performed by using
* the following methods.
*
* - Continuous measurement: A profile counter can be assigned a monitor signal of
* constant 1 (PROFILE_ONE), which sets the counter to increment at every (assigned)
* clock cycle. This can be used to give a reference time for the measurement window
* and also allows the construction of time stamps. For example, a software controlled
* GPIO can be "timestamped" by reading the counter value (on the fly) before it is
* toggled. When the measurement window ends, the energy contribution caused by the
* GPIO toggle can be incorporated into the final calculation.
*
* - Event measurement: Monitored events happening in a measurement window can be
* used to increment a profile counter. This gives the activity numbers, which can
* then be multiplied by the instantaneous power numbers associated with the source
* to give the average energy consumption (Energy = Power x time). For example, the
* energy consumped by an Operating System (OS) task can be estimated by monitoring
* the processor's active cycle count (E.g. CPUSS_MONITOR_CM4) and the Flash read
* accesses (CPUSS_MONITOR_FLASH). Note that these activity numbers can also be
* timestamped using the continuous measurement method to differentiate between the
* different task switches. The activity numbers are then multiplied by the associated
* processor and flash access power numbers to give the average energy consumed by
* that task.
*
* - Duration measurement: A peripheral event such as the SMIF select signal can be
* used by a profile counter to measure the time spent on XIP communication through the
* SPI interface. This activity number can then be multiplied by the power associated
* with that activity to give the average energy consumed by that block during the
* measurement window. This type of monitoring should only be performed for signals
* that are difficult to track in software. For example, a combination of interrupts
* and time stamps can be used to track the activity of many peripherals in a continuous
* monitoring model. However tracking the activity of signals such the BLE radio
* should be done using the duration measurement method.
*
* - Low power measurement: The profile counters do not support measurement during chip
* deep-sleep, hibernate and off states. i.e. the profile counters are meant for active
* run-time measurements only. In order to measure the time spent in low power modes (LPM),
* a real-time clock (RTC) should be used. Take a timestamp before LPM entry and a
* timestamp upon LPM exit in a continuous measurement model. Then multiply the difference
* by the appropriate LPM power numbers.
*
* \subsection group_profile_usage Driver Usage
*
* At the highest level, the energy profiler must perform the following steps to
* obtain a measurement:
*
* 1. Initialize the profile hardware block.
* 2. Initialize the profile interrupt (profile_interrupt_IRQn).
* 3. Configure, initialize, and enable the profile counters.
* 4. Enable the profile interrupt and start the profiling/measurement window.
* 5. Perform run-time reads of the counters (if needed).
* 6. Disable the profile interrupt and stop the profiling/measurement window.
* 7. Read the counters and gather the results.
* 8. Calculate the energy consumption.
*
* Refer to the SysInt driver on the details of configuring the profile hardware interrupt.
*
* The profile interrupt triggers when a counter overflow event is detected on any of the
* enabled profile counters. A sample interrupt service routine Cy_Profile_ISR() is provided,
* which can be used to update the internal counter states stored in RAM. Refer to the
* Configuration Considerations for more information.
*
* \section group_profile_configuration Configuration Considerations
*
* 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. To address
* this issue, the driver implements a 32-bit overflow counter. Combined with the 32-bit
* register, this gives a 64-bit counter for each monitored source.
*
* When an overflow occurs, the profile hardware generates an interrupt. The interrupt is
* configured using the SysInt driver, where the sample interrupt handler Cy_Profile_ISR()
* can be used as the ISR. The ISR increments the overflow counter for each profiling counter
* and clears the interrupt.
*
* \section group_profile_more_information More Information
*
* See the profiler 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>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>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>
* </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_macros Macros
* \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>
#ifndef CY_IP_MXPROFILE
#error "The PROFILE driver is not supported on this device"
#endif
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/** \addtogroup group_profile_macros
* \{
*/
/** Driver major version */
#define CY_PROFILE_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_PROFILE_DRV_VERSION_MINOR 0
/** Profile driver identifier */
#define CY_PROFILE_ID CY_PDL_DRV_ID(0x1EU)
/** 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
/** \} group_profile_macros */
/**
* \addtogroup group_profile_enums
* \{
*/
/**
* Profile counter reference clock source. Used when duration monitoring.
*/
typedef enum
{
CY_PROFILE_CLK_TIMER = 0, /**< Timer clock (TimerClk) */
CY_PROFILE_CLK_IMO = 1, /**< Internal main oscillator (IMO) */
CY_PROFILE_CLK_ECO = 2, /**< External crystal oscillator (ECO) */
CY_PROFILE_CLK_LF = 3, /**< Low-frequency clock (LFCLK) */
CY_PROFILE_CLK_HF = 4, /**< High-Frequency clock (HFCLK0) */
CY_PROFILE_CLK_PERI = 5, /**< Peripheral clock (PeriClk) */
} cy_en_profile_ref_clk_t;
/**
* Monitor method type.
*/
typedef enum
{
CY_PROFILE_EVENT = 0, /**< Count (edge-detected) module events */
CY_PROFILE_DURATION = 1, /**< Count (level) duration in clock cycles */
} cy_en_profile_duration_t;
/** Profiler status codes */
typedef enum
{
CY_PROFILE_SUCCESS = 0x00U, /**< Operation completed successfully */
CY_PROFILE_BAD_PARAM = CY_PROFILE_ID | CY_PDL_STATUS_ERROR | 1UL /**< Invalid input parameters */
} cy_en_profile_status_t;
/** \} group_profile_enums */
/**
* \addtogroup group_profile_data_structures
* \{
*/
/**
* Profile counter control register structure. For each counter, holds the CTL register fields.
*/
typedef struct
{
cy_en_profile_duration_t cntDuration; /**< 0 = event; 1 = duration */
cy_en_profile_ref_clk_t refClkSel; /**< The reference clock used by the counter */
en_ep_mon_sel_t monSel; /**< The monitor signal to be observed by the counter */
} cy_stc_profile_ctr_ctl_t;
/**
* Software structure for holding a profile counter status and configuration information.
*/
typedef struct
{
uint8_t ctrNum; /**< Profile counter number */
uint8_t used; /**< 0 = available; 1 = used */
cy_stc_profile_ctr_ctl_t ctlRegVals; /**< Initial counter CTL register settings */
PROFILE_CNT_STRUCT_Type * cntAddr; /**< Base address of the counter instance registers */
uint32_t ctlReg; /**< Current CTL register value */
uint32_t cntReg; /**< Current CNT register value */
uint32_t overflow; /**< Extension of cntReg to form a 64-bit counter value */
uint32_t weight; /**< Weighting factor for the counter */
} cy_stc_profile_ctr_t;
/**
* Pointer to a structure holding the status information for a profile 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 ==================== */
/* ========================================================================== */
void Cy_Profile_ISR(void);
/** \} group_profile_functions_interrupt */
/**
* \addtogroup group_profile_functions_general
* \{
*/
__STATIC_INLINE void Cy_Profile_Init(void);
__STATIC_INLINE void Cy_Profile_DeInit(void);
void Cy_Profile_StartProfiling(void);
__STATIC_INLINE void Cy_Profile_DeInit(void);
__STATIC_INLINE void Cy_Profile_StopProfiling(void);
__STATIC_INLINE uint32_t Cy_Profile_IsProfiling(void);
/* ========================================================================== */
/* =============== GENERAL PROFILE FUNCTIONS SECTION ================= */
/* ========================================================================== */
/*******************************************************************************
* Function Name: Cy_Profile_Init
****************************************************************************//**
*
* Initializes and enables the profile hardware.
*
* This function must be called once when energy profiling is desired. The
* operation does not start a profiling session.
*
* \note The profile interrupt must also be configured. \ref Cy_Profile_ISR()
* can be used as its handler.
*
* \funcusage
* \snippet profile/profile_v1_0_sut_01.cydsn/main_cm4.c snippet_Cy_Profile_Init
*
*******************************************************************************/
__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
****************************************************************************//**
*
* Clears the interrupt mask and disables the profile hardware.
*
* This function should be called when energy profiling is no longer desired.
*
* \note The profile interrupt is not disabled by this operation and must be
* disabled separately.
*
* \funcusage
* \snippet profile/profile_v1_0_sut_01.cydsn/main_cm4.c snippet_Cy_Profile_DeInit
*
*******************************************************************************/
__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_StopProfiling
****************************************************************************//**
*
* Stops the profiling/measurement window.
*
* This operation prevents the enabled profile counters from counting.
*
* \note The profile interrupt should be disabled before calling this function.
*
* \funcusage
* \snippet profile/profile_v1_0_sut_01.cydsn/main_cm4.c snippet_Cy_Profile_StopProfiling
*
*******************************************************************************/
__STATIC_INLINE void Cy_Profile_StopProfiling(void)
{
PROFILE->CMD = CY_PROFILE_STOP_TR;
}
/*******************************************************************************
* Function Name: Cy_Profile_IsProfiling
****************************************************************************//**
*
* Reports the active status of the profiling window.
*
* \return 0 = profiling is not active; 1 = profiling is active
*
* \funcusage
* \snippet profile/profile_v1_0_sut_01.cydsn/main_cm4.c snippet_Cy_Profile_IsProfiling
*
*******************************************************************************/
__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
* \{
*/
void Cy_Profile_ClearConfiguration(void);
__STATIC_INLINE void Cy_Profile_ClearCounters(void);
cy_stc_profile_ctr_ptr_t Cy_Profile_ConfigureCounter(en_ep_mon_sel_t monitor, cy_en_profile_duration_t duration, cy_en_profile_ref_clk_t refClk, uint32_t weight);
cy_en_profile_status_t Cy_Profile_FreeCounter(cy_stc_profile_ctr_ptr_t ctrAddr);
cy_en_profile_status_t Cy_Profile_EnableCounter(cy_stc_profile_ctr_ptr_t ctrAddr);
cy_en_profile_status_t Cy_Profile_DisableCounter(cy_stc_profile_ctr_ptr_t ctrAddr);
/* ========================================================================== */
/* =================== COUNTER FUNCTIONS SECTION ====================== */
/* ========================================================================== */
/*******************************************************************************
* Function Name: Cy_Profile_ClearCounters
****************************************************************************//**
*
* Clears all hardware counters to 0.
*
* \funcusage
* \snippet profile/profile_v1_0_sut_01.cydsn/main_cm4.c snippet_Cy_Profile_ClearCounters
*
*******************************************************************************/
__STATIC_INLINE void Cy_Profile_ClearCounters(void)
{
PROFILE->CMD = CY_PROFILE_CLR_ALL_CNT;
}
/** \} group_profile_functions_counter */
/**
* \addtogroup group_profile_functions_calculation
* \{
*/
/* ========================================================================== */
/* ================== CALCULATION FUNCTIONS SECTION =================== */
/* ========================================================================== */
cy_en_profile_status_t Cy_Profile_GetRawCount(cy_stc_profile_ctr_ptr_t ctrAddr, uint64_t *result);
cy_en_profile_status_t Cy_Profile_GetWeightedCount(cy_stc_profile_ctr_ptr_t ctrAddr, uint64_t *result);
uint64_t Cy_Profile_GetSumWeightedCounts(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,893 @@
/***************************************************************************//**
* \file cy_prot.h
* \version 1.10
*
* \brief
* Provides an API declaration of the Protection Unit driver
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
/**
* \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:
* - <b>Security requirements:</b> This includes the prevention of malicious attacks
* to access secure memory or peripherals.
* - <b>Safety requirements:</b> 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.
*
* \section group_prot_protection_type Protection Types
*
* Protection units are hardware configuration structures that control bus accesses
* to the resources that they protect. By combining these individual configuration
* structures, a system is built to allow strict restrictions on the capabilities
* of individual bus masters (e.g. CM0+, CM4, Crypt) and their operating modes.
* This architecture can then be integrated into the overall security system
* of the end application. To build this system, 3 main protection unit types
* are available; MPU, SMPU and PPU. When a resource is accessed (memory/register),
* it must pass the evaluation performed for each category. These access evaluations
* are prioritized, where MPU has the highest priority, followed by SMPU, followed
* by PPU. i.e. if an SMPU and a PPU protect the same resource and if access is
* denied by the SMPU, then the PPU access evaluation is skipped. This can lead to a
* denial-of-service scenario and the application should pay special attention in
* taking ownership of the protection unit configurations.
*
* \subsection group_prot_memory_protection Memory Protection
*
* Memory access control for a bus master is controlled using an MPU. These are
* most often used to distinguish user and privileged accesses from a single bus
* master such as task switching in an OS/kernel. For ARM cores (CM0+, CM4), the
* core MPUs are used to perform this task. For other non-ARM bus masters such
* as Crypto, MPU structs are available, which can be used in a similar manner
* as the ARM core MPUs. These MPUs however must be configured by the ARM cores.
* Other bus masters that do not have an MPU, such as DMA (DW), inherit the access
* control attributes of the bus master that configured the channel. Also note
* that unlike other protection units, MPUs do not support protection context
* evaluation. MPU structs have a descending priority, where larger index struct
* has higher priority access evaluation over lower index structs. E.g. MPU_STRUCT15
* has higher priority than MPU_STRUCT14 and its access will be evaluated before
* MPU_STRUCT14. If both target the same memory, then the higher index (MPU_STRUCT15)
* will be used, and the lower index (MPU_STRUCT14) will be ignored.
*
* \subsection group_prot_shared_memory_protection Shared Memory Protection
*
* In order to protect a region of memory from all bus masters, an SMPU is used.
* This protection effectively allows only those with correct bus master access
* settings to read/write/execute the memory region. This type of protection
* is used in general memory such as Flash and SRAM. Peripheral registers are
* best configured using the peripheral protection units instead. SMPU structs
* have a descending priority, where larger index struct has higher priority
* access evaluation over lower index structs. E.g. SMPU_STRUCT15 has higher priority
* than SMPU_STRUCT14 and its access will be evaluated before SMPU_STRUCT14.
* If both target the same memory, then the higher index (MPU_STRUCT15) will be
* used, and the lower index (SMPU_STRUCT14) will be ignored.
*
* \subsection group_prot_peripheral_protection Peripheral Protection
*
* Peripheral protection is provided by PPUs and allow control of peripheral
* register accesses by bus masters. Four types of PPUs are available.
* - <b>Fixed Group (GR) PPUs</b> 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). Group PPUs have the highest
* priority in the PPU category. Therefore their access evaluations take precedence
* over the other types of PPUs.
* - <b>Programmable (PROG) PPUs</b> 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. Programmable PPUs have the second highest
* priority and take precedence over Region PPUs and Slave PPUs. Similar to SMPUs,
* higher index PROG PPUs have higher priority than lower indexes PROG PPUs.
* - <b>Fixed Region (RG) PPUs</b> are used to protect an entire peripheral slave
* instance from invalid bus master accesses. For example, TCPWM0, TCPWM1,
* SCB0, and SCB1, etc. Region PPUs have the third highest priority and take precedence
* over Slave PPUs.
* - <b>Fixed Slave (SL) PPUs</b> are used to protect specified regions of peripheral
* instances. For example, individual DW channel structs, SMPU structs, and
* IPC structs, etc. Slave PPUs have the lowest priority in the PPU category and
* therefore are evaluated last.
*
* \section group_prot_protection_context Protection Context
*
* Protection context (PC) attribute is present in all bus masters and is evaluated
* when accessing memory protected by an SMPU or a PPU. There are no limitations
* to how the PC values are allocated to the bus masters and this makes it
* possible for multiple bus masters to essentially share protection context
* values. The exception to this rule is the PC value 0.
*
* \subsection group_prot_pc0 PC=0
*
* Protection context 0 is a hardware controlled protection context update
* mechanism that allows only a single entry point for transitioning into PC=0
* value. This mechanism is only present for the secure CM0+ core and is a
* fundamental feature in defining a security solution. While all bus masters
* are configured to PC=0 at device boot, it is up to the security solution
* to transition these bus masters to PC!=0 values. Once this is done, those
* bus masters can no longer revert back to PC=0 and can no longer access
* resources protected at PC=0.
*
* In order to enter PC=0, the CM0+ core must assign an interrupt vector or
* an exception handler address to the CPUSS.CM0_PC0_HANDLER register. This
* allows the hardware to check whether the executing code address matches the
* value in this register. If they match, the current PC value is saved and
* the CM0+ bus master automatically transitions to PC=0. It is then up to
* the executing code to decide if and when it will revert to a PC!=0 value.
* At that point, the only way to re-transition to PC=0 is through the defined
* exception/interrupt handler.
*
* \section group_prot_access_evaluation Access Evaluation
*
* Each protection unit is capable of evaluating several access types. These can
* be used to build a system of logical evaluations for different kinds of
* bus master modes of operations. These access types can be divided into
* three broad access categories.
*
* - <b>User/Privileged access:</b> The ARM convention of user mode versus privileged
* mode is applied in the protection units. For ARM cores, switching between
* user and privileged modes is handled by updating its Control register or
* by exception entries. Other bus masters such as Crypto have their own
* user/privileged settings bit in the bus master control register. This is
* then controlled by the ARM cores. Bus masters that do not have
* user/privileged access controls, such as DMA, inherit their attributes
* from the bus master that configured it. The user/privileged distinction
* is used mainly in the MPUs for single bus master accesses but they can
* also be used in all other protection units.
* - <b>Secure/Non-secure access:</b> The secure/non-secure attribute is another
* identifier to distinguish between two separate modes of operations. Much
* like the user/privileged access, the secure/non-secure mode flag is present
* in the bus master control register. The ARM core does not have this
* attribute in its control register and must use the bus master control
* register instead. Bus masters that inherit their attributes, such as DMA,
* inherit the secure/non-secure attribute. The primary use-case for this
* access evaluation is to define a region to be secure or non-secure using
* an SMPU or a PPU. A bus master with a secure attribute can access
* both secure and non-secure regions, whereas a bus master with non-secure
* attribute can only access non-secure regions.
* - <b>Protection Context access:</b> Protection Context is an attribute
* that serves two purposes; To enter the hardware controlled secure PC=0
* mode of operation from non-secure modes and to provide finer granularity
* to the bus master access definitions. It is used in SMPU and PPU configuration
* to control which bus master protection context can access the resources
* that they protect.
*
* \section group_prot_protection_structure Protection Structure
*
* Each protection unit is comprised of a master struct and a slave struct pair.
* The exception to this rule is MPU structs, which only have the slave struct
* equivalent. The protection units apply their access evaluations in a decreasing
* index order. For example, if SMPU1 and SMPU2 both protect a specific memory region,
* the the higher index (SMPU2) will be evaluated first. In a secure system, the
* higher index protection structs would then provide the high level of security
* and the lower indexes would provide the lower level of security. Refer to the
* \ref group_prot_protection_type section for more information.
*
* \subsection group_prot_slave_struct Slave Struct
*
* The slave struct is used to configure the protection settings for the resource
* of interest (memory/registers). Depending on the type of protection unit,
* the available attributes differ. However all Slave protection units have the
* following general format.
*
* \subsubsection group_prot_slave_addr Slave Struct Address Definition
*
* - Address: For MPU, SMPU and PROG PPU, the address field is used to define
* the base memory region to apply the protection. This field has a dependency
* on the region size, which dictates the alignment of the protection unit. E.g.
* if the region size is 64KB, the address field is aligned to 64KB. Hence
* the lowest bits [15:0] are ignored. For instance, if the address is defined
* at 0x0800FFFF, the protection unit would apply its protection settings from
* 0x08000000. Thus alignment must be checked before defining the protection
* address. The address field for other PPUs are not used, as they are bound
* to their respective peripheral memory locations.
* - Region Size: For MPU, SMPU and PROG PPU, the region size is used to define
* the memory block size to apply the protection settings, starting from the
* defined base address. It is also used to define the 8 sub-regions for the
* chosen memory block. E.g. If the region size is 64KB, each subregion would
* be 8KB. This information can then be used to disable the protection
* settings for select subregions, which gives finer granularity to the
* memory regions. PPUs do not have region size definitions as they are bound
* to their respective peripheral memory locations.
* - Subregions: The memory block defined by the address and region size fields
* is divided into 8 (0 to 7) equally spaced subregions. The protection settings
* of the protection unit can be disabled for these subregions. E.g. for a
* given 64KB of memory block starting from address 0x08000000, disabling
* subregion 0 would result in the protection settings not affecting the memory
* located between 0x08000000 to 0x08001FFF. PPUs do not have subregion
* definitions as they are bound to their respective peripheral memory locations.
*
* \subsubsection group_prot_slave_attr Slave Struct Attribute Definition
*
* - User Permission: Protection units can control the access restrictions
* of the read (R), write (W) and execute (X) (subject to their availability
* depending on the type of protection unit) operations on the memory block
* when the bus master is operating in user mode. PPU structs do not provide
* execute attributes.
* - Privileged Permission: Similar to the user permission, protection units can
* control the access restrictions of the read (R), write (W) and execute (X)
* (subject to their availability depending on the type of protection unit)
* operations on the memory block when the bus master is operating in
* privileged mode. PPU structs do not provide execute attributes.
* - Secure/Non-secure: Applies the secure/non-secure protection settings to
* the defined memory region. Secure protection allows only bus masters that
* access the memory with secure attribute. Non-secure protection allows
* bus masters that have either secure or non-secure attributes.
* - PC match: This attribute allows the protection unit to either apply the
* 3 access evaluations (user/privileged, secure/non-secure, protection context)
* or to only provide an address range match. This is useful when multiple
* protection units protect an overlapping memory region and it's desirable
* to only have access evaluations applied from only one of these protection
* units. For example, SMPU1 protects memory A and SMPU2 protects memory B.
* There exists a region where A and B intersect and this is accessed by a
* bus master. Both SMPU1 and SMPU2 are configured to operate in "match" mode.
* In this scenario, the access evaluation will only be applied by the higher
* index protection unit (i.e. SMPU2) and the access attributes of SMPU1 will
* be ignored. If the bus master then tries to access a memory region A (that
* does not intersect with B), the access evaluation from SMPU1 will be used.
* Note that the PC match functionality is only available in SMPUs.
* - PC mask: Defines the allowed protection context values that can access the
* protected memory. The bus master attribute must be operating in one of the
* protection context values allowed by the protection unit. E.g. If SMPU1 is
* configured to allow only PC=1 and PC=5, a bus master (such as CM4) must
* be operating at PC=1 or PC=5 when accessing the protected memory region.
*
* \subsection group_prot_master_struct Master Struct
*
* The master struct protects its slave struct in the protection unit. This
* architecture makes possible for the slave configuration to be protected from
* reconfiguration by an unauthorized bus master. The configuration attributes
* and the format are similar to that of the slave structs.
*
* \subsubsection group_prot_master_addr Master Struct Address Definition
*
* - Address: The address definition for master struct is fixed to the slave
* struct that it protects.
* - Region Size: The region size is fixed to 256B region.
* - Subregion: This value is fixed to only enable the first 64B subregions,
* which applies the protection settings to the entire protection unit.
*
* \subsubsection group_prot_master_attr Master Struct Attribute Definition
*
* - User Permission: Only the write (W) access attribute is allowed for
* master structs, which controls whether a bus master operating in user
* mode has the write access.
* - Privileged Permission: Only the write (W) access attribute is allowed for
* master structs, which controls whether a bus master operating in privileged
* mode has the write access.
* - Secure/Non-Secure: Same behavior as slave struct.
* - PC match: Same behavior as slave struct.
* - PC mask: Same behavior as slave struct.
*
* \section group_prot_driver_usage Driver Usage
*
* Setting up and using protection units can be summed up in four stages:
*
* - Configure the bus master attributes. This defines the capabilities of
* the bus master when trying to access the protected resources.
* - Configure the slave struct of a given protection unit. This defines
* the protection attributes to be applied to the bus master accessing
* the protected resource and also defines the size and location of the
* memory block to protect.
* - Configure the master struct of the protection unit. This defines the
* attributes to be checked against the bus master that is trying to
* reconfigure the slave struct.
* - Set the active PC value of the bus master and place it in the correct
* mode of operation (user/privileged, secure/non-secure). Then access
* the protected memory.
*
* For example, by configuring the CM0+ bus master configuration to allow
* only protection contexts 2 and 3, the bus master will be able to
* set its protection context only to 2 or 3. During runtime, the CM0+ core
* can set its protection context to 2 by calling Cy_Prot_SetActivePC()
* and access all regions of protected memory that allow PC=2. A fault will
* be triggered if a resource is protected with different protection settings.
*
* Note that 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 definition 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.
*
* Note that the bus master ID (en_prot_master_t) is defined in the device
* config header file.
*
* \section group_prot_configuration Configuration Considerations
*
* When a resource (memory/register) is accessed, it must pass evaluation of
* all three protection unit categories in the following order: MPU->SMPU->PPU.
* The application should ensure that a denial-of-service attack cannot be
* made on the PPU by the SMPU. For this reason, it is recommended that the
* application's security policy limit the ability for the non-secure client
* from configuring the SMPUs.
*
* Within each category, the priority hierarchy must be carefully considered
* to ensure that a higher priority protection unit cannot be configured to
* override the security configuration of a lower index protection unit.
* Therefore if a lower index protection unit is configured, relevant higher
* priority indexes should be configured (or protected from unwanted
* reconfiguration). E.g. If a PPU_SL is configured, PPU_RG and PPU_GR that
* overlaps with the protected registers should also be configured. SImilar
* to SMPUs, it is recommended that the configuration of PPU_PROG be limited.
* Otherwise they can be used to override the protection settings of PPU_RG
* and PPU_SL structs.
*
* All bus masters are set to PC=0 value at device reset and therefore have full
* access to all resources. It is up to the security solution to implement
* what privileges each bus master has. Once transitioned to a PC!=0 value,
* only the CM0+ core is capable of re-entering the PC=0 via the user-defined
* exception entry in the CPUSS.CM0_PC0_HANDLER register.
*
* - SMPU 15 and 14 are configured and enabled to only allow PC=0 accesses at
* device boot.
* - PROG PPU 15, 14, 13 and 12 are configured to only allow PC=0 accesses at
* device boot.
* - GR PPU 0 and 2 are configured to only allow PC=0 accesses at device boot.
*
* \section group_prot_more_information More Information
*
* Refer to Technical Reference Manual (TRM) and the device datasheet.
*
* \section group_prot_MISRA MISRA-C Compliance]
* The Prot driver does not have any driver-specific deviations.
*
* \section group_prot_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td rowspan="2">1.10</td>
* <td>Added input parameter validation to the API functions.<br>
* cy_en_prot_pcmask_t, cy_en_prot_subreg_t and cy_en_prot_pc_t
* types are set to typedef enum</td>
* <td>Improved debugging capability</td>
* </tr>
* <tr>
* <td>Expanded documentation</td>
* <td></td>
* </tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_prot_macros Macros
* \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 <stddef.h>
#include "syslib/cy_syslib.h"
#include "cy_device_headers.h"
#if defined(__cplusplus)
extern "C" {
#endif
/** \addtogroup group_prot_macros
* \{
*/
/** Driver major version */
#define CY_PROT_DRV_VERSION_MAJOR 1
/** Driver minor version */
#define CY_PROT_DRV_VERSION_MINOR 10
/** Prot driver ID */
#define CY_PROT_ID CY_PDL_DRV_ID(0x30u)
/** \} group_prot_macros */
/**
* \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 */
/* Helper function for finding max */
#define CY_PROT_MAX(x,y) (((x)>(y))?(x):(y))
/* 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 */
/* Maximum Master Protection Context */
#define CY_PROT_MS_PC_NR_MAX CY_PROT_MAX(CPUSS_PROT_SMPU_MS0_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS1_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS2_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS3_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS4_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS5_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS6_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS7_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS8_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS9_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS10_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS11_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS12_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS13_PC_NR_MINUS1, \
CY_PROT_MAX(CPUSS_PROT_SMPU_MS14_PC_NR_MINUS1, \
CPUSS_PROT_SMPU_MS15_PC_NR_MINUS1)))))))))))))))
/* Protection Context limit masks */
#define CY_PROT_MS0_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS0_PC_NR_MINUS1)
#define CY_PROT_MS1_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS1_PC_NR_MINUS1)
#define CY_PROT_MS2_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS2_PC_NR_MINUS1)
#define CY_PROT_MS3_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS3_PC_NR_MINUS1)
#define CY_PROT_MS4_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS4_PC_NR_MINUS1)
#define CY_PROT_MS5_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS5_PC_NR_MINUS1)
#define CY_PROT_MS6_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS6_PC_NR_MINUS1)
#define CY_PROT_MS7_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS7_PC_NR_MINUS1)
#define CY_PROT_MS8_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS8_PC_NR_MINUS1)
#define CY_PROT_MS9_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS9_PC_NR_MINUS1)
#define CY_PROT_MS10_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS10_PC_NR_MINUS1)
#define CY_PROT_MS11_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS11_PC_NR_MINUS1)
#define CY_PROT_MS12_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS12_PC_NR_MINUS1)
#define CY_PROT_MS13_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS13_PC_NR_MINUS1)
#define CY_PROT_MS14_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS14_PC_NR_MINUS1)
#define CY_PROT_MS15_PC_LIMIT_MASK (0xFFFFFFFFUL << CPUSS_PROT_SMPU_MS15_PC_NR_MINUS1)
#define CY_PROT_MPU_PC_LIMIT_MASK (0xFFFFFFFFUL << CY_PROT_MS_PC_NR_MAX)
#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_UX_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_PR_ATT0_UX_Msk \
| PERI_PPU_PR_ATT0_PX_Msk \
| PERI_PPU_PR_ATT0_PC_MASK_0_Msk \
))
#define CY_PROT_PPU_PROG_ATT1_MASK ((uint32_t)~(PERI_PPU_PR_ATT1_UX_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_UX_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_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_SL_ATT1_MASK ((uint32_t)~(PERI_PPU_GR_ATT1_UX_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_RG_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_RG_ATT1_MASK ((uint32_t)~(PERI_PPU_GR_ATT1_UX_Msk \
| PERI_PPU_GR_ATT1_PX_Msk \
| PERI_PPU_GR_ATT1_PC_MASK_0_Msk \
| PERI_PPU_GR_ATT1_REGION_SIZE_Msk \
))
/* Parameter check macros */
#define CY_PROT_BUS_MASTER_MAX (16UL)
#define CY_PROT_IS_BUS_MASTER_VALID(busMaster) (CY_PROT_BUS_MASTER_MAX > ((uint32_t)(busMaster)))
#define CY_PROT_IS_MPU_PERM_VALID(permission) (((permission) == CY_PROT_PERM_DISABLED) || \
((permission) == CY_PROT_PERM_R) || \
((permission) == CY_PROT_PERM_W) || \
((permission) == CY_PROT_PERM_RW) || \
((permission) == CY_PROT_PERM_X) || \
((permission) == CY_PROT_PERM_RX) || \
((permission) == CY_PROT_PERM_WX) || \
((permission) == CY_PROT_PERM_RWX))
#define CY_PROT_IS_SMPU_MS_PERM_VALID(permission) (((permission) == CY_PROT_PERM_R) || \
((permission) == CY_PROT_PERM_RW))
#define CY_PROT_IS_SMPU_SL_PERM_VALID(permission) (((permission) == CY_PROT_PERM_DISABLED) || \
((permission) == CY_PROT_PERM_R) || \
((permission) == CY_PROT_PERM_W) || \
((permission) == CY_PROT_PERM_RW) || \
((permission) == CY_PROT_PERM_X) || \
((permission) == CY_PROT_PERM_RX) || \
((permission) == CY_PROT_PERM_WX) || \
((permission) == CY_PROT_PERM_RWX))
#define CY_PROT_IS_PROG_MS_PERM_VALID(permission) (((permission) == CY_PROT_PERM_R) || \
((permission) == CY_PROT_PERM_RW))
#define CY_PROT_IS_PROG_SL_PERM_VALID(permission) (((permission) == CY_PROT_PERM_DISABLED) || \
((permission) == CY_PROT_PERM_R) || \
((permission) == CY_PROT_PERM_W) || \
((permission) == CY_PROT_PERM_RW))
#define CY_PROT_IS_FIXED_MS_PERM_VALID(permission) (((permission) == CY_PROT_PERM_R) || \
((permission) == CY_PROT_PERM_RW))
#define CY_PROT_IS_FIXED_SL_PERM_VALID(permission) (((permission) == CY_PROT_PERM_DISABLED) || \
((permission) == CY_PROT_PERM_R) || \
((permission) == CY_PROT_PERM_W) || \
((permission) == CY_PROT_PERM_RW))
#define CY_PROT_IS_REGION_SIZE_VALID(regionSize) (((regionSize) == CY_PROT_SIZE_256B) || \
((regionSize) == CY_PROT_SIZE_512B) || \
((regionSize) == CY_PROT_SIZE_1KB) || \
((regionSize) == CY_PROT_SIZE_2KB) || \
((regionSize) == CY_PROT_SIZE_4KB) || \
((regionSize) == CY_PROT_SIZE_8KB) || \
((regionSize) == CY_PROT_SIZE_16KB) || \
((regionSize) == CY_PROT_SIZE_32KB) || \
((regionSize) == CY_PROT_SIZE_64KB) || \
((regionSize) == CY_PROT_SIZE_128KB) || \
((regionSize) == CY_PROT_SIZE_256KB) || \
((regionSize) == CY_PROT_SIZE_512KB) || \
((regionSize) == CY_PROT_SIZE_1MB) || \
((regionSize) == CY_PROT_SIZE_2MB) || \
((regionSize) == CY_PROT_SIZE_4MB) || \
((regionSize) == CY_PROT_SIZE_8MB) || \
((regionSize) == CY_PROT_SIZE_16MB) || \
((regionSize) == CY_PROT_SIZE_32MB) || \
((regionSize) == CY_PROT_SIZE_64MB) || \
((regionSize) == CY_PROT_SIZE_128MB) || \
((regionSize) == CY_PROT_SIZE_256MB) || \
((regionSize) == CY_PROT_SIZE_512MB) || \
((regionSize) == CY_PROT_SIZE_1GB) || \
((regionSize) == CY_PROT_SIZE_2GB) || \
((regionSize) == CY_PROT_SIZE_4GB))
/** \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 */

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,412 @@
/***************************************************************************//**
* \file cy_scb_common.c
* \version 2.10
*
* Provides common API implementation of the SCB driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#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 buffer
* 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 *buffer, uint32_t size)
{
uint32_t idx;
if (Cy_SCB_IsRxDataWidthByte(base))
{
uint8_t *buf = (uint8_t *) buffer;
/* 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 *) buffer;
/* 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 are
* read from the receive FIFO.
*
* \param base
* The pointer to the SCB instance.
*
* \param buffer
* 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 *buffer, uint32_t size)
{
/* Get available items in RX FIFO */
uint32_t numToCopy = Cy_SCB_GetNumInRxFifo(base);
/* Adjust items that will be read */
if (numToCopy > size)
{
numToCopy = size;
}
/* Get data available in RX FIFO */
Cy_SCB_ReadArrayNoCheck(base, buffer, 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 buffer
* The pointer to the location to place data read from the 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 *buffer, uint32_t size)
{
uint32_t numCopied;
uint8_t *buf = (uint8_t *) buffer;
bool byteMode = Cy_SCB_IsRxDataWidthByte(base);
/* 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[(byteMode ? (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. It returns how many data elements are 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 whether 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 buffer
* 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 *buffer, uint32_t size)
{
uint32_t idx;
if (Cy_SCB_IsTxDataWidthByte(base))
{
uint8_t *buf = (uint8_t *) buffer;
/* 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 *) buffer;
/* 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. It returns how many data elements were
* placed in the transmit FIFO.
*
* \param base
* The pointer to the SCB instance.
*
* \param buffer
* 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 *buffer, 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, buffer, 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 buffer
* 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 *buffer, uint32_t size)
{
uint32_t numCopied;
uint8_t *buf = (uint8_t *) buffer;
bool byteMode = Cy_SCB_IsTxDataWidthByte(base);
/* 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[(byteMode ? (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 whether 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,570 @@
/***************************************************************************//**
* \file cy_scb_ezi2c.h
* \version 2.10
*
* Provides EZI2C API declarations of the SCB driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
/**
* \addtogroup group_scb_ezi2c
* \{
* Driver API for EZI2C Slave Peripheral
*
* 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 the I2C slave
* device based on the SCB hardware block. This slave device emulates a common
* I2C EEPROM interface that acts like dual-port memory between the external
* master and your code. I2C devices based on the SCB hardware are compatible
* with the 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 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; does not require calling EZI2C API
* at run time.
*
* \section group_scb_ezi2c_configuration Configuration Considerations
* The EZI2C slave driver configuration can be divided to number of sequential
* steps listed below:
* * \ref group_scb_ezi2c_config
* * \ref group_scb_ezi2c_pins
* * \ref group_scb_ezi2c_clock
* * \ref group_scb_ezi2c_data_rate
* * \ref group_scb_ezi2c_intr
* * \ref group_scb_ezi2c_enable
*
* \note
* EZI2C slave driver is built on top of the SCB hardware block. The SCB3
* instance is used as an example for all code snippets. Modify the code to
* match your design.
*
* \subsection group_scb_ezi2c_config Configure EZI2C slave
* To set up the EZI2C slave driver, provide the configuration parameters in the
* \ref cy_stc_scb_ezi2c_config_t structure. The primary slave address
* slaveAddress1 must be provided. The other parameters are optional for
* operation. To initialize the driver, call \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.
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\ezi2c_snippets.c EZI2C_CFG
*
* Set up the EZI2C slave buffer before enabling its
* operation by using \ref Cy_SCB_EZI2C_SetBuffer1 for the primary slave address
* and \ref Cy_SCB_EZI2C_SetBuffer2 for the secondary (if the secondary is enabled).
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\ezi2c_snippets.c EZI2C_CFG_BUFFER
*
* \subsection group_scb_ezi2c_pins Assign and Configure Pins
* Only dedicated SCB pins can be used for I2C operation. The HSIOM
* register must be configured to connect the block to the pins. Also the I2C pins
* must be configured in Open-Drain, Drives Low mode (this pin configuration
* implies usage of external pull-up resistors):
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\ezi2c_snippets.c EZI2C_CFG_PINS
*
* \note
* The alternative pins configuration is Resistive Pull-ups which implies usage
* internal pull-up resistors. This configuration is not recommended because
* resistor value is fixed and cannot be used for all supported data rates.
* Refer to device datasheet parameter RPULLUP for resistor value specifications.
*
* \subsection group_scb_ezi2c_clock Assign Clock Divider
* The clock source must be connected to the SCB block to oversample input and
* output signals. You must use one of the 8-bit or 16-bit dividers <em><b>(the
* source clock of this divider must be Clk_Peri)</b></em>. Use the
* \ref group_sysclk driver API to do that.
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\ezi2c_snippets.c EZI2C_CFG_ASSIGN_CLOCK
*
* \subsection group_scb_ezi2c_data_rate Configure Data Rate
* To get EZI2C slave to operate at the desired data rate, the source clock must be
* fast enough to provide sufficient oversampling. Therefore, the clock divider
* must be configured to provide desired clock frequency. Use the
* \ref group_sysclk driver API to do that.
* Refer to the technical reference manual (TRM) section I2C sub-section
* Oversampling and Bit Rate to get information about how to configure the I2C to run
* at the desired data rate.
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\ezi2c_snippets.c EZI2C_CFG_DATA_RATE
*
* \subsection group_scb_ezi2c_intr Configure Interrupt
* The interrupt is mandatory for the EZI2C slave operation.
* The \ref Cy_SCB_EZI2C_Interrupt function must be called in the interrupt
* handler for the selected SCB instance. Also, this interrupt must be enabled
* in the NVIC or it will not work.
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\ezi2c_snippets.c EZI2C_INTR_A
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\ezi2c_snippets.c EZI2C_INTR_B
*
* \subsection group_scb_ezi2c_enable Enable EZI2C slave
* Finally, enable the EZI2C slave operation by calling \ref Cy_SCB_EZI2C_Enable.
* Now the I2C device responds to the assigned address.
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\ezi2c_snippets.c EZI2C_ENABLE
*
* \section group_scb_ezi2c_use_cases Common Use Cases
* The EZI2C slave operation might not require calling any EZI2C slave function
* because the I2C master is able to access the slave buffer. The application
* can directly access it as well. Note that this is an application-level task
* to ensure the buffer content integrity.
*
* \subsection group_scb_ezi2c_master_wr Master Write operation
* This operation starts with sending a base address that 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, there is a sequence of bytes 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 that 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.
*
* \image html scb_ezi2c_write.png
*
* \subsection group_scb_ezi2c_master_rd Master Read operation
* This 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 are 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.
*
* \image html scb_ezi2c_read.png
*
* The I2C master may use the ReStart or Stop/Start conditions to combine the
* operations. The write operation 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.
* \image html scb_ezi2c_set_ba_read.png
*
* \section group_scb_ezi2c_lp Low Power Support
* The EZI2C slave provides the callback functions to handle power mode
* transition. The callback \ref Cy_SCB_EZI2C_DeepSleepCallback must be called
* during execution of \ref Cy_SysPm_DeepSleep;
* \ref Cy_SCB_EZI2C_HibernateCallback must be called during execution of
* \ref Cy_SysPm_Hibernate. To trigger the callback execution, the callback must
* be registered before calling the power mode transition function. Refer to
* \ref group_syspm driver for more information about power mode transitions and
* callback registration.
*
* \note
* Only applicable for <b>rev-08 of the CY8CKIT-062-BLE</b>.
* For proper operation, when the EZI2C slave is configured to be a wakeup
* source from Deep Sleep mode, the \ref Cy_SCB_EZI2C_DeepSleepCallback must
* be copied and modified. Refer to the function description to get the details.
*
* \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>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>The functions \ref Cy_SCB_EZI2C_DeepSleepCallback and
* \ref Cy_SCB_EZI2C_HibernateCallback are callback of
* \ref cy_en_syspm_status_t type. The cast operation safety in these
* functions becomes the user's responsibility because pointers are
* initialized when callback is registered in SysPm driver.</td>
* </tr>
* <tr>
* <td>14.1</td>
* <td>R</td>
* <td>There shall be no unreachable code.</td>
* <td>The SCB block parameters can be a constant false or true depending on
* the selected device and cause code to be unreachable.</td>
* </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>
* <tr>
* <td>14.7</td>
* <td>R</td>
* <td>A function shall have a single point of exit at the end of the
* function.</td>
* <td>The functions can return from several points. This is done to improve
* code clarity when returning error status code if input parameter
* validation fails.</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>2.10</td>
* <td>None.</td>
* <td>SCB I2C driver updated.</td>
* </tr>
* <tr>
* <td rowspan="2"> 2.0</td>
* <td>Added parameters validation for public API.</td>
* <td></td>
* </tr>
* <tr>
* <td>Replaced variables that have limited range of values with enumerated
* types.</td>
* <td></td>
* </tr>
* <tr>
* <td>1.0</td>
* <td>Initial version.</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_scb_ezi2c_macros Macros
* \defgroup group_scb_ezi2c_functions Functions
* \{
* \defgroup group_scb_ezi2c_general_functions General
* \defgroup group_scb_ezi2c_slave_functions Slave
* \defgroup group_scb_ezi2c_low_power_functions Low Power Callbacks
* \}
* \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 slave status codes */
typedef enum
{
/** Operation completed successfully */
CY_SCB_EZI2C_SUCCESS = 0U,
/** One or more of input parameters are invalid */
CY_SCB_EZI2C_BAD_PARAM = (CY_SCB_ID | CY_PDL_STATUS_ERROR | CY_SCB_EZI2C_ID | 1U),
} cy_en_scb_ezi2c_status_t;
/** Number of Addresses */
typedef enum
{
CY_SCB_EZI2C_ONE_ADDRESS, /**< Only one address */
CY_SCB_EZI2C_TWO_ADDRESSES /**< Two addresses */
} cy_en_scb_ezi2c_num_of_addr_t;
/** Size of Sub-Address */
typedef enum
{
CY_SCB_EZI2C_SUB_ADDR8_BITS, /**< Sub-address is 8 bits */
CY_SCB_EZI2C_SUB_ADDR16_BITS /**< Sub-address is 16 bits */
} cy_en_scb_ezi2c_sub_addr_size_t;
/** \cond INTERNAL */
/** EZI2C slave FSM states */
typedef enum
{
CY_SCB_EZI2C_STATE_IDLE,
CY_SCB_EZI2C_STATE_ADDR,
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 slave configuration structure */
typedef struct cy_stc_scb_ezi2c_config
{
/** The number of supported addresses either */
cy_en_scb_ezi2c_num_of_addr_t numberOfAddresses;
/** The 7-bit right justified primary slave address */
uint8_t slaveAddress1;
/** The 7-bit right justified secondary slave address */
uint8_t slaveAddress2;
/** The size of the sub-address, can either be 8 or 16 bits */
cy_en_scb_ezi2c_sub_addr_size_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;
} cy_stc_scb_ezi2c_config_t;
/** EZI2C slave context structure.
* All fields for the context structure are internal. Firmware never reads or
* writes these values. Firmware allocates the structure and provides the
* address of the structure to the driver in function calls. Firmware must
* ensure that the defined instance of this structure remains in scope
* while the drive is in use.
*/
typedef struct cy_stc_scb_ezi2c_context
{
/** \cond INTERNAL */
volatile cy_en_scb_ezi2c_state_t state; /**< The driver state */
volatile uint32_t status; /**< The slave status */
uint8_t address1; /**< The primary slave address (7-bits right justified) */
uint8_t address2; /**< The secondary slave address (7-bits right justified) */
cy_en_scb_ezi2c_sub_addr_size_t subAddrSize; /**< The sub-address size */
uint32_t idx; /**< The index within the buffer during operation */
uint32_t baseAddr1; /**< The valid base address for the primary slave address */
uint32_t baseAddr2; /**< The valid base address for the secondary slave address */
bool addr1Active; /**< Defines whether the request is intended for the primary slave address */
uint8_t *curBuf; /**< The pointer to the current location in the buffer (while it is accessed) */
uint32_t bufSize; /**< Specifies how many bytes are left in the current buffer */
uint8_t *buf1; /**< The pointer to the buffer exposed on the request intended for the primary slave address */
uint32_t buf1Size; /**< The buffer size assigned to the primary slave address */
uint32_t buf1rwBondary; /**< The Read/Write boundary within the buffer assigned to the primary slave address */
uint8_t *buf2; /**< The pointer to the buffer exposed on the request intended for the secondary slave address */
uint32_t buf2Size; /**< The buffer size assigned to the secondary slave address */
uint32_t buf2rwBondary; /**< The Read/Write boundary within the buffer assigned for the secondary slave address */
/** \endcond */
} cy_stc_scb_ezi2c_context_t;
/** \} group_scb_ezi2c_data_structures */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_scb_ezi2c_general_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);
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_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);
/** \} group_scb_ezi2c_general_functions */
/**
* \addtogroup group_scb_ezi2c_slave_functions
* \{
*/
void Cy_SCB_EZI2C_SetBuffer1(CySCB_Type const *base, uint8_t *buffer, uint32_t size, uint32_t rwBoundary,
cy_stc_scb_ezi2c_context_t *context);
void Cy_SCB_EZI2C_SetBuffer2(CySCB_Type const *base, uint8_t *buffer, uint32_t size, uint32_t rwBoundary,
cy_stc_scb_ezi2c_context_t *context);
uint32_t Cy_SCB_EZI2C_GetActivity(CySCB_Type const *base, cy_stc_scb_ezi2c_context_t *context);
void Cy_SCB_EZI2C_Interrupt(CySCB_Type *base, cy_stc_scb_ezi2c_context_t *context);
/** \} group_scb_ezi2c_slave_functions */
/**
* \addtogroup group_scb_ezi2c_low_power_functions
* \{
*/
cy_en_syspm_status_t Cy_SCB_EZI2C_DeepSleepCallback(cy_stc_syspm_callback_params_t *callbackParams);
cy_en_syspm_status_t Cy_SCB_EZI2C_HibernateCallback(cy_stc_syspm_callback_params_t *callbackParams);
/** \} group_scb_ezi2c_low_power_functions */
/***************************************
* API Constants
***************************************/
/**
* \addtogroup group_scb_ezi2c_macros
* \{
*/
/**
* \defgroup group_scb_ezi2c_macros_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.
* \{
*/
/**
* The Read transfer intended for the primary slave address is complete.
* The error condition status bit must be checked to ensure that the Read
* transfer was completed successfully.
*/
#define CY_SCB_EZI2C_STATUS_READ1 (0x01UL)
/**
* The Write transfer intended for the primary slave address is complete.
* The buffer content was modified.
* The error condition status bit must be checked to ensure that the Write
* transfer was completed successfully.
*/
#define CY_SCB_EZI2C_STATUS_WRITE1 (0x02UL)
/**
* The Read transfer intended for the secondary slave address is complete.
* The error condition status bit must be checked to ensure that the Read
* transfer was completed successfully.
*/
#define CY_SCB_EZI2C_STATUS_READ2 (0x04UL)
/**
* The Write transfer intended for the secondary slave address is complete.
* The buffer content was modified.
* The error condition status bit must be checked to ensure that the 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 the error are: a misplaced Start or Stop
* condition or lost arbitration while the slave drives SDA.
* When CY_SCB_EZI2C_STATUS_ERR is set, the slave buffer may contain an
* invalid byte. Discard the buffer content in this case.
*/
#define CY_SCB_EZI2C_STATUS_ERR (0x20UL)
/** \} group_scb_ezi2c_macros_get_activity */
/**
* This value is returned by the slave when the buffer is not configured or
* the master requests more bytes than are 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_RX_CTRL (CY_SCB_I2C_RX_CTRL)
#define CY_SCB_EZI2C_TX_CTRL (CY_SCB_I2C_TX_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))
/* Disable Address interrupt source */
#define CY_SCB_EZI2C_SLAVE_INTR_NO_ADDR (CY_SCB_EZI2C_SLAVE_INTR & ((uint32_t) ~CY_SCB_SLAVE_INTR_I2C_ADDR_MATCH))
/* FIFO size */
#define CY_SCB_EZI2C_FIFO_SIZE(base) CY_SCB_FIFO_SIZE(base)
#define CY_SCB_EZI2C_HALF_FIFO_SIZE(base) (CY_SCB_FIFO_SIZE(base) / 2UL)
#define CY_SCB_EZI2C_ONE_ADDRESS_MASK (0xFFUL)
#define CY_SCB_EZI2C_IS_NUM_OF_ADDR_VALID(numAddr) ( (CY_SCB_EZI2C_ONE_ADDRESS == (numAddr)) || \
(CY_SCB_EZI2C_TWO_ADDRESSES == (numAddr)) )
#define CY_SCB_EZI2C_IS_SUB_ADDR_SIZE_VALID(subAddrSize) ( (CY_SCB_EZI2C_SUB_ADDR8_BITS == (subAddrSize)) || \
(CY_SCB_EZI2C_SUB_ADDR16_BITS == (subAddrSize)) )
/** \endcond */
/** \} group_scb_ezi2c_macros */
/***************************************
* Inline Function Implementation
***************************************/
/**
* \addtogroup group_scb_ezi2c_general_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_general_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

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

File diff suppressed because it is too large Load Diff

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