Initial public release.

This commit is contained in:
Joe Kearney 2025-02-01 19:22:12 -06:00
parent 7b169e8116
commit dac4af8d25
255 changed files with 68595 additions and 2 deletions

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,288 @@
/* Include Files */
#include "KTag.h"
QueueHandle_t xQueueAudio;
TaskHandle_t Audio_Task_Handle;
static const uint8_t START_BYTE = 0x7E;
static const uint8_t VERSION_BYTE = 0xFF;
static const uint8_t END_BYTE = 0xEF;
// Valid volumes are 0 - 30.
static const uint8_t COMMAND_SPECIFY_VOLUME = 0x06;
static const uint8_t COMMAND_PAUSE = 0x0E;
static const uint8_t COMMAND_PLAY_TRACK_IN_FOLDER = 0x0F;
__attribute__((always_inline)) inline uint16_t CalculateChecksum(uint8_t * buffer, uint8_t length)
{
uint16_t checksum = 0;
for (uint_fast8_t i = 0; i < length; i++)
{
checksum += buffer[i];
}
return (0 - checksum);
}
static void Send_Command(uint8_t command, bool requireFeedback, uint16_t parameter)
{
uint8_t buffer[10];
uint16_t checksum;
buffer[0] = START_BYTE;
buffer[1] = VERSION_BYTE;
buffer[2] = 6; // count
buffer[3] = command;
buffer[4] = requireFeedback;
buffer[5] = (uint8_t)(parameter >> 8);
buffer[6] = (uint8_t)(parameter);
checksum = CalculateChecksum(&buffer[1], 6);
buffer[7] = (uint8_t)(checksum >> 8);
buffer[8] = (uint8_t)(checksum);
buffer[9] = END_BYTE;
for (uint_fast8_t i = 0; i < 10; i++)
{
UART_Audio_Put(buffer[i]);
}
}
SystemKResult_T Perform_Audio_Action(AudioAction_T * action)
{
if (xQueueSend(xQueueAudio, action, 0) == pdTRUE)
{
return SYSTEMK_RESULT_SUCCESS;
}
else
{
return SYSTEMK_RESULT_QUEUE_IS_FULL;
}
}
void Init_Audio(void)
{
UART_Audio_Start();
xQueueAudio = xQueueCreate(5, sizeof(AudioAction_T));
}
void Audio_Task(void * pvParameters)
{
portBASE_TYPE xStatus;
while (IsNVMInitialized() == false)
{
vTaskDelay(100 / portTICK_PERIOD_MS);
}
Send_Command(COMMAND_SPECIFY_VOLUME, false, NVM_VOLUME);
while (true)
{
AudioAction_T action;
xStatus = xQueueReceive(xQueueAudio, &action, 0);
if (xStatus == pdPASS)
{
switch (action.ID)
{
case AUDIO_SET_VOLUME:
{
uint8_t volume = *((uint8_t *)action.Data);
if (volume <= 30)
{
Send_Command(COMMAND_SPECIFY_VOLUME, false, volume);
}
}
break;
case AUDIO_SILENCE:
Send_Command(COMMAND_PAUSE, false, 0x0000);
break;
case AUDIO_PLAY_STARTUP_SOUND:
// Play track "001" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0101);
break;
case AUDIO_PLAY_SHOT_FIRED:
// Play track "002" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0102);
break;
case AUDIO_PLAY_TAG_RECEIVED:
// Play track "003" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0103);
break;
case AUDIO_PLAY_TAGGED_OUT:
// Play track "004" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0104);
break;
case AUDIO_PLAY_MISFIRE:
// Play track "005" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0105);
break;
case AUDIO_PRONOUNCE_NUMBER_0_TO_100:
{
uint8_t file_index = *((uint8_t *)action.Data);
if (file_index > 100)
{
file_index = 100;
}
else if (file_index == 0)
{
file_index = 101;
}
// The numbers are stored in folder "10".
// 001.mp3 is "one", 100.mp3 is "one hundred", and 101.mp3 is "zero".
uint16_t filenumber = 0x0A00 + file_index;
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, filenumber);
}
break;
case AUDIO_PLAY_MENU_PROMPT:
// Play track "006" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0106);
break;
case AUDIO_PLAY_SELECTION_INDICATOR:
// Play track "007" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0107);
break;
case AUDIO_PLAY_HEALTH_REMAINING:
// Play track "008" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0108);
break;
case AUDIO_PLAY_ELECTRONIC_DANCE_MUSIC:
// Play track "009" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0109);
break;
default:
case AUDIO_PLAY_GENERIC_ERROR:
// Play track "010" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x010A);
break;
case AUDIO_PLAY_VOLUME_PROMPT:
// Play track "011" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x010B);
break;
case AUDIO_PLAY_RIGHT_HANDED:
// Play track "012" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x010C);
break;
case AUDIO_PLAY_LEFT_HANDED:
// Play track "013" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x010D);
break;
case AUDIO_PLAY_GAME_ON:
// Play track "014" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x010E);
break;
case AUDIO_PLAY_HARDWARE_SETTINGS_PROMPT:
// Play track "015" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x010F);
break;
case AUDIO_PLAY_GAME_SETTINGS_PROMPT:
// Play track "016" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0110);
break;
case AUDIO_PLAY_BONK:
// Play track "017" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0111);
break;
case AUDIO_PLAY_NEAR_MISS:
// Play track "018" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0112);
break;
case AUDIO_PLAY_PLAYER_ID_PROMPT:
// Play track "019" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0113);
break;
case AUDIO_PLAY_TEAM_ID_PROMPT:
// Play track "020" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0114);
break;
case AUDIO_PLAY_FRIENDLY_FIRE:
// Play track "021" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0115);
break;
case AUDIO_PLAY_STARTING_THEME:
// Play track "022" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0116);
break;
case AUDIO_PLAY_BOOP:
// Play track "023" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0117);
break;
case AUDIO_PLAY_BEEP:
// Play track "024" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0118);
break;
case AUDIO_PLAY_REPROGRAMMING:
// Play track "025" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x0119);
break;
case AUDIO_PLAY_BOMB:
// Play track "026" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x011A);
break;
case AUDIO_PLAY_GAME_OVER:
// Play track "027" in folder "01".
Send_Command(COMMAND_PLAY_TRACK_IN_FOLDER, false, 0x011B);
break;
}
if (action.Play_To_Completion == true)
{
do
{
vTaskDelay(100 / portTICK_PERIOD_MS);
} while (Is_Audio_Playing() == true);
KEvent_T command_received_event = {.ID = KEVENT_AUDIO_COMPLETED, .Data = (void *)action.ID};
Post_KEvent(&command_received_event);
}
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
bool Is_Audio_Playing()
{
bool result = false;
// The signal is active low.
if (Cy_GPIO_Read(Pin_Audio_Busy_PORT, Pin_Audio_Busy_NUM) == 0)
{
result = true;
}
return result;
}

View file

@ -0,0 +1,7 @@
extern QueueHandle_t xQueueAudio;
extern TaskHandle_t Audio_Task_Handle;
void Init_Audio(void);
void Audio_Task(void * pvParameters);
bool Is_Audio_Playing();

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,79 @@
/** \dir "BLE"
*
* \brief This directory contains source code for managing Bluetooth Low Energy communications.
*
*/
/** \file
* \brief This file defines the interface to the Bluetooth Low Energy communications used by this software.
*
*/
#ifndef COMM_BLE_H
#define COMM_BLE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
// Define this to print out BLE trace statements to the console.
//#define TRACE_BLE
//#define VERBOSE_BLE_TRACE
#define COMM_BLE_TASK_STACK_SIZE_in_bytes 4096
typedef enum
{
COMM_BLE_DEFAULT,
COMM_BLE_INITIALIZING,
COMM_BLE_IDLE,
COMM_BLE_SCANNING_FOR_KTAG_PACKETS,
COMM_BLE_ADVERTISING_AS_PERIPHERAL,
COMM_BLE_ADVERTISING_AS_BROADCASTER,
COMM_BLE_SCANNING_AND_ADVERTISING
} COMM_BLE_StateID_T;
typedef enum
{
COMM_BLE_COMMAND_NO_OP,
COMM_BLE_REQUEST_STATE_CHANGE,
COMM_BLE_PROCESS_BLE_EVENTS,
COMM_BLE_SCAN_FOR_KTAG_PACKETS,
COMM_BLE_ADVERTISE_AS_BROADCASTER,
COMM_BLE_ADVERTISE_AS_PERIPHERAL,
COMM_BLE_STOP_ADVERTISING,
COMM_BLE_SCAN_AND_ADVERTISE,
// COMM_BLE_COMMAND_IS_OUT_OF_RANGE is one more than the last valid command.
COMM_BLE_COMMAND_IS_OUT_OF_RANGE
} COMM_BLE_Command_ID_T;
typedef struct
{
COMM_BLE_Command_ID_T ID;
void * Data;
} COMM_BLE_Command_T;
/* Include Files */
/* Public Variables */
extern cy_stc_ble_conn_handle_t appConnHandle[CY_BLE_CONN_COUNT];
extern volatile uint8_t COMM_BLE_IASAlertLevel;
extern QueueHandle_t COMM_BLE_CommandQueue;
//! Handle of the COMM_BLE_Task() given when the task was created.
extern TaskHandle_t COMM_BLE_Task_Handle;
/* Public Functions */
void COMM_BLE_Init(void);
void COMM_BLE_Task(void * pvParameters);
void COMM_BLE_RequestState(COMM_BLE_StateID_T state);
#ifdef __cplusplus
}
#endif
#endif // COMM_BLE_H

View file

@ -0,0 +1,252 @@
/* Include Files */
#include "KTag.h"
/* Local Definitions and Constants */
/* Public Variables */
/* Private Variables */
static bool removeBondListFlag = false;
/* Private Function Prototypes */
/* Public Functions */
/*******************************************************************************
* Function Name: App_DisplayBondList()
********************************************************************************
*
* Summary:
* This function displays the bond list.
*
*******************************************************************************/
void App_DisplayBondList(void)
{
#ifdef TRACE_BLE
cy_en_ble_api_result_t apiResult;
cy_stc_ble_gap_peer_addr_info_t bondedDeviceInfo[CY_BLE_MAX_BONDED_DEVICES];
cy_stc_ble_gap_bonded_device_list_info_t bondedDeviceList =
{
.bdHandleAddrList = bondedDeviceInfo
};
uint8_t deviceCount;
/* Find out whether the device has bonded information stored already or not */
apiResult = Cy_BLE_GAP_GetBondList(&bondedDeviceList);
if (apiResult != CY_BLE_SUCCESS)
{
COMM_Console_Print_String("[BLE] Cy_BLE_GAP_GetBondList API Error: 0x");
COMM_Console_Print_UInt32AsHex(apiResult);
COMM_Console_Print_String("\n");
}
else
{
deviceCount = bondedDeviceList.noOfDevices;
if(deviceCount != 0u)
{
uint8_t counter;
COMM_Console_Print_String("[BLE] Bond list:\n");
do
{
COMM_Console_Print_String(" ");
COMM_Console_Print_UInt8(deviceCount);
COMM_Console_Print_String(". ");
deviceCount--;
if(bondedDeviceList.bdHandleAddrList[deviceCount].bdAddr.type == CY_BLE_GAP_ADDR_TYPE_RANDOM)
{
COMM_Console_Print_String("Peer Random Address:");
}
else
{
COMM_Console_Print_String("Peer Public Address:");
}
for (counter = CY_BLE_GAP_BD_ADDR_SIZE; counter > 0u; counter--)
{
COMM_Console_Print_String(" ");
COMM_Console_Print_UInt8AsHex(bondedDeviceList.bdHandleAddrList[deviceCount].bdAddr.bdAddr[counter - 1u]);
}
COMM_Console_Print_String(", bdHandle: 0x");
COMM_Console_Print_UInt8AsHex(bondedDeviceList.bdHandleAddrList[deviceCount].bdHandle);
COMM_Console_Print_String("\n");
} while (deviceCount != 0u);
COMM_Console_Print_String("\n");
}
}
#endif // TRACE_BLE
}
/*******************************************************************************
* Function Name: App_RemoveDevidesFromBondList
********************************************************************************
*
* Summary:
* Remove devices from the bond list.
*
*******************************************************************************/
void App_RemoveDevicesFromBondList(void)
{
#if(CY_BLE_BONDING_REQUIREMENT == CY_BLE_BONDING_YES)
cy_en_ble_api_result_t apiResult;
cy_stc_ble_gap_bd_addr_t peerBdAddr = { .type = 0u };
#ifdef TRACE_BLE
COMM_Console_Print_String("[BLE] Cleaning Bond List...\n\n");
#endif // TRACE_BLE
/* Remove all bonded devices in the list */
apiResult = Cy_BLE_GAP_RemoveBondedDevice(&peerBdAddr);
if (apiResult != CY_BLE_SUCCESS)
{
#ifdef TRACE_BLE
COMM_Console_Print_String("[BLE] Cy_BLE_GAP_RemoveBondedDevice API Error: 0x");
COMM_Console_Print_UInt32AsHex(apiResult);
COMM_Console_Print_String("\n");
#endif // TRACE_BLE
}
else
{
#ifdef TRACE_BLE
COMM_Console_Print_String("[BLE] Cy_BLE_GAP_RemoveBondedDevice complete.\n\n");
#endif // TRACE_BLE
}
#else
#ifdef TRACE_BLE
COMM_Console_Print_String("[BLE] Bonding is disabled...no need to remove bonded devices.\n\n");
#endif // TRACE_BLE
#endif /* (CY_BLE_BONDING_REQUIREMENT == CY_BLE_BONDING_YES) */
/* Clean flag */
removeBondListFlag = false;
}
/*******************************************************************************
* Function Name: App_GetCountOfBondedDevices()
********************************************************************************
*
* Summary:
* This function returns the count of bonded devices
*
* Return:
* uint32_t The count of bonded devices
*
*******************************************************************************/
uint32_t App_GetCountOfBondedDevices(void)
{
cy_en_ble_api_result_t apiResult;
cy_stc_ble_gap_peer_addr_info_t bondedDeviceInfo[CY_BLE_MAX_BONDED_DEVICES];
cy_stc_ble_gap_bonded_device_list_info_t bondedDeviceList =
{
.bdHandleAddrList = bondedDeviceInfo
};
uint32_t deviceCount = 0u;
/* Find out whether the device has bonded information stored already or not */
apiResult = Cy_BLE_GAP_GetBondList(&bondedDeviceList);
if (apiResult != CY_BLE_SUCCESS)
{
#ifdef TRACE_BLE
COMM_Console_Print_String("[BLE] Cy_BLE_GAP_GetBondList API Error: 0x");
COMM_Console_Print_UInt32AsHex(apiResult);
COMM_Console_Print_String("\n");
#endif // TRACE_BLE
}
else
{
deviceCount = bondedDeviceList.noOfDevices;
}
return (deviceCount);
}
/*******************************************************************************
* Function Name: App_IsDeviceInBondList()
********************************************************************************
*
* Summary:
* This function check if device with bdHandle is in the bond list
*
* Parameters:
* bdHandle - bond device handler
*
* Return:
* bool - true value when bdHandle exists in bond list
*
*******************************************************************************/
bool App_IsDeviceInBondList(uint32_t bdHandle)
{
cy_en_ble_api_result_t apiResult;
cy_stc_ble_gap_peer_addr_info_t bondedDeviceInfo[CY_BLE_MAX_BONDED_DEVICES];
cy_stc_ble_gap_bonded_device_list_info_t bondedDeviceList =
{
.bdHandleAddrList = bondedDeviceInfo
};
bool deviceIsDetected = false;
uint32_t deviceCount;
/* Find out whether the device has bonding information stored already or not */
apiResult = Cy_BLE_GAP_GetBondList(&bondedDeviceList);
if (apiResult != CY_BLE_SUCCESS)
{
#ifdef TRACE_BLE
COMM_Console_Print_String("[BLE] Cy_BLE_GAP_GetBondList API Error: 0x");
COMM_Console_Print_UInt32AsHex(apiResult);
COMM_Console_Print_String("\n");
#endif // TRACE_BLE
}
else
{
deviceCount = bondedDeviceList.noOfDevices;
if(deviceCount != 0u)
{
do
{
deviceCount--;
if(bdHandle == bondedDeviceList.bdHandleAddrList[deviceCount].bdHandle)
{
deviceIsDetected = 1u;
}
} while(deviceCount != 0u);
}
}
return(deviceIsDetected);
}
/*******************************************************************************
* Function Name: App_SetRemoveBondListFlag()
********************************************************************************
* Summary:
* Set flag for removing bond list
*
*******************************************************************************/
void App_SetRemoveBondListFlag(void)
{
removeBondListFlag = true;
}
/*******************************************************************************
* Function Name: App_IsRemoveBondListFlag()
********************************************************************************
* Summary:
* Get value of remove bond list flag
*
* Return:
* true - remove bond list flag is set
* false - remove bond list flag is clear
*
*******************************************************************************/
bool App_IsRemoveBondListFlag(void)
{
return ((removeBondListFlag == true) ? true : false);
}
/* Private Functions */

View file

@ -0,0 +1,32 @@
/** \file
* \brief This file declares Bluetooth Low Energy bond list helper functions.
*
*/
#ifndef COMM_BLE_BOND_H
#define COMM_BLE_BOND_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
/* Include Files */
/* Public Variables */
/* Public Functions */
void App_DisplayBondList(void);
void App_RemoveDevicesFromBondListBySW2Press(uint32_t seconds);
void App_RemoveDevicesFromBondList(void);
void App_SetRemoveBondListFlag(void);
bool App_IsRemoveBondListFlag(void);
bool App_IsDeviceInBondList(uint32_t bdHandle);
uint32_t App_GetCountOfBondedDevices(void);
#ifdef __cplusplus
}
#endif
#endif // COMM_BLE_BOND_H

View file

@ -0,0 +1,177 @@
/* Include Files */
#include "KTag.h"
/* Local Definitions and Constants */
#define UART_CIRCULAR_BUFFER_SIZE 1024
#define BLE_UART_BUFFER_CHARACTERISTIC_SIZE 20
/* Public Variables */
/* Private Variables */
static uint_fast16_t UART_Tx_Notifications_Enabled = 0;
static uint8_t UART_Tx_Buffer_Storage[UART_CIRCULAR_BUFFER_SIZE];
static UTIL_CircularBuffer_T UART_Tx_Buffer;
static uint8_t BLE_UART_Tx_Buffer[BLE_UART_BUFFER_CHARACTERISTIC_SIZE];
static uint8_t Rx_Buffer[BLE_UART_BUFFER_CHARACTERISTIC_SIZE + 1];
/* Private Function Prototypes */
/* Public Functions */
void COMM_BLE_UART_Init(void)
{
UTIL_InitCircularBuffer(&UART_Tx_Buffer, UART_Tx_Buffer_Storage, UART_CIRCULAR_BUFFER_SIZE);
}
//! Sends a message over the BLE UART.
void COMM_BLE_UART_PutString(const char8 * string, uint16_t length)
{
for (uint8_t i = 0; i < length; i++)
{
(void) UTIL_PushToCircularBuffer(&UART_Tx_Buffer, *string++);
}
}
//! Sends a single character over the BLE UART.
void COMM_BLE_UART_PutChar(char8 character)
{
(void) UTIL_PushToCircularBuffer(&UART_Tx_Buffer, character);
}
void COMM_BLE_UART_MaybeSendData(void)
{
int8_t length = 0;
if (UTIL_IsCircularBufferEmpty(&UART_Tx_Buffer) == false)
{
while ((length < BLE_UART_BUFFER_CHARACTERISTIC_SIZE) && (UTIL_IsCircularBufferEmpty(&UART_Tx_Buffer) == false))
{
uint8_t value;
if (UTIL_PopFromCircularBuffer(&UART_Tx_Buffer, &value) == UTIL_CIRCULARBUFFERRESULT_SUCCESS)
{
BLE_UART_Tx_Buffer[length] = value;
length++;
}
}
}
if (length > 0)
{
for (uint_fast8_t i = 0; i < CY_BLE_CONN_COUNT; i++)
{
if (Cy_BLE_GetConnectionState(appConnHandle[i]) >= CY_BLE_CONN_STATE_CONNECTED)
{
cy_stc_ble_gatt_handle_value_pair_t tempHandle;
tempHandle.attrHandle = CY_BLE_NORDIC_UART_SERVICE_TX_CHAR_HANDLE;
tempHandle.value.val = (uint8 *) BLE_UART_Tx_Buffer;
tempHandle.value.actualLen = length;
tempHandle.value.len = length;
Cy_BLE_GATTS_WriteAttributeValueLocal(&tempHandle);
}
}
// Send notification to each client that has TX notifications enabled.
for (uint_fast8_t i = 0; i < CY_BLE_CONN_COUNT; i++)
{
if ((Cy_BLE_GetConnectionState(appConnHandle[i]) >= CY_BLE_CONN_STATE_CONNECTED) &&
Cy_BLE_GATTS_IsNotificationEnabled(&appConnHandle[i],
CY_BLE_NORDIC_UART_SERVICE_TX_TXCCCD_DESC_HANDLE))
{
cy_stc_ble_gatt_handle_value_pair_t tempHandle;
tempHandle.attrHandle = CY_BLE_NORDIC_UART_SERVICE_TX_CHAR_HANDLE;
tempHandle.value.val = (uint8 *) BLE_UART_Tx_Buffer;
tempHandle.value.actualLen = length;
tempHandle.value.len = length;
Cy_BLE_GATTS_SendNotification(&appConnHandle[i], &tempHandle);
}
}
}
}
//! BLE event handler for the BLE UART feature.
/*!
* This function should be called *before* events are handled in the event handler passed to
* Cy_BLE_Start(). If it returns `false`, then the rest of the event handler should proceed.
*
* \param event BLE stack event code received from the BLE middleware (one of cy_en_ble_event_t).
* \param eventParam pointer to an event-specific data structure containing the relevant event information.
* \return true if this handler has completely handled the event, and no further
* handling is necessary; false otherwise.
*/
bool COMM_BLE_UART_HandleEvent(uint32 event, void * eventParam)
{
static cy_stc_ble_gatts_write_cmd_req_param_t * writeReqParameter;
bool handled = false;
/* Take an action based on the current event */
switch ((cy_en_ble_event_t)event)
{
// Handle a write request.
case CY_BLE_EVT_GATTS_WRITE_REQ:
writeReqParameter = (cy_stc_ble_gatts_write_cmd_req_param_t*)eventParam;
// Request to write the UART.
// https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.2.0%2Fble_sdk_app_nus_eval.html&cp=5_5_0_4_1_2_24
if (writeReqParameter->handleValPair.attrHandle == CY_BLE_NORDIC_UART_SERVICE_RX_CHAR_HANDLE)
{
// Only update the value and write the response if the requested write is allowed.
if (CY_BLE_GATT_ERR_NONE == Cy_BLE_GATTS_WriteAttributeValuePeer(&writeReqParameter->connHandle, &writeReqParameter->handleValPair))
{
uint16_t i;
for (i = 0; (i < BLE_UART_BUFFER_CHARACTERISTIC_SIZE) && (i < writeReqParameter->handleValPair.value.len); i++)
{
Rx_Buffer[i] = writeReqParameter->handleValPair.value.val[i];
}
// NULL-terminate the buffer.
Rx_Buffer[i] = 0x00;
Cy_BLE_GATTS_WriteRsp(writeReqParameter->connHandle);
COMM_Console_Execute_Internal_Command(Rx_Buffer);
}
handled = true;
}
// Request for UART Tx notifications.
if (writeReqParameter->handleValPair.attrHandle == CY_BLE_NORDIC_UART_SERVICE_TX_TXCCCD_DESC_HANDLE)
{
if (CY_BLE_GATT_ERR_NONE == Cy_BLE_GATTS_WriteAttributeValuePeer(&writeReqParameter->connHandle, &writeReqParameter->handleValPair))
{
UART_Tx_Notifications_Enabled = writeReqParameter->handleValPair.value.val[0] & 0x01;
if (UART_Tx_Notifications_Enabled)
{
COMM_Console_Print_String("[BLE] UART Tx notifications enabled.\n");
}
else
{
COMM_Console_Print_String("[BLE] UART Tx notifications disabled.\n");
}
Cy_BLE_GATTS_WriteRsp(writeReqParameter->connHandle);
}
handled = true;
}
break;
default:
// (`handled` is already set to false.)
break;
}
return handled;
}
/* Private Functions */

View file

@ -0,0 +1,30 @@
/** \file
* \brief This file declares interface functions to a BLE UART implementation.
*
*/
#ifndef COMM_BLE_UART_H
#define COMM_BLE_UART_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
/* Include Files */
/* Public Variables */
/* Public Functions */
void COMM_BLE_UART_Init(void);
void COMM_BLE_UART_PutString(const char8 * string, uint16_t length);
void COMM_BLE_UART_PutChar(char8 character);
void COMM_BLE_UART_MaybeSendData(void);
bool COMM_BLE_UART_HandleEvent(uint32 event, void * eventParam);
#ifdef __cplusplus
}
#endif
#endif // COMM_BLE_UART_H

View file

@ -0,0 +1,50 @@
/** \dir "COMM"
*
* \brief This directory contains source code for the communication interfaces used by this software.
*
*/
/** \file
* \brief This file defines the interface to the communications used by this software.
*
* This file should be included by any file outside the COMM package wishing to make use
* of any of the configuration information provided by the COMM package.
*
*/
#ifndef COMM_H
#define COMM_H
#ifdef __cplusplus
extern "C" {
#endif
/* Include Files */
#include "COMM_IPC_Messages.h"
#include "BLE/COMM_BLE.h"
#include "BLE/COMM_BLE_Bond.h"
#include "BLE/COMM_BLE_UART.h"
#include "COMM_Console.h"
#include "COMM_Console_Util.h"
#include "COMM_I2C_Bus.h"
#include "COMM_Util.h"
#include "ConsoleCommands/COMM_ConsoleCommands.h"
#include "ConsoleCommands/COMM_BLE_ConsoleCommands.h"
#include "ConsoleCommands/COMM_NVM_ConsoleCommands.h"
#include "ConsoleCommands/COMM_RTOS_ConsoleCommands.h"
#include "ConsoleCommands/COMM_STATE_ConsoleCommands.h"
/* Preprocessor and Type Definitions */
#define DebugPrintf(...)
#define Task_DebugPrintf(...)
/* Public Variables */
/* Public Functions */
#ifdef __cplusplus
}
#endif
#endif // COMM_H

View file

@ -0,0 +1,639 @@
/** \file
* \brief This file implements a simple serial debug console and command interpreter.
*/
/** \defgroup CONSOLE Console
*
* \brief Serial debug console command interpreter.
*
* \todo Describe the command interpreter.
*
* @{
* @}
*/
/* Include Files */
#include "KTag.h"
/* Local Definitions and Constants */
//! Text representations of numeric digits, used by COMM_Console_Print_UInt32().
static const char8 DIGITS[] = "0123456789ABCDEF";
#if (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
//! Maximum number of characters (save one) able to be printed by COMM_Console_Print_String().
#define MAX_CONSOLE_STRING_LENGTH 81
//! States in the COMM_Console_Task() state machine.
typedef enum
{
COMM_STATE_INITIALIZING = 0,
COMM_STATE_DISPLAY_POWERUP_INFO,
COMM_STATE_IDLE,
COMM_STATE_COMMAND_TOO_LONG,
COMM_STATE_IDENTIFY_COMMAND,
COMM_STATE_EXECUTE_COMMAND,
COMM_STATE_UNKNOWN_COMMAND
} COMM_Console_State_T;
/* Public Variables */
char8 Command_Buffer[COMM_CONSOLE_COMMAND_MAX_LENGTH];
uint_fast16_t Command_Buffer_Index = 0;
TaskHandle_t COMM_Console_Task_Handle;
/* Private Variables */
//! Current state of the COMM_Console_Task() state machine.
static COMM_Console_State_T Current_State = COMM_STATE_INITIALIZING;
//! Next state of the COMM_Console_Task() state machine.
static COMM_Console_State_T Next_State = COMM_STATE_INITIALIZING;
//! Index into the #COMM_Console_Command_Table for the command currently being handled.
/*!
* If #Current_Command is set to UINT_FAST16_MAX, the command being handled is unknown, or no command is being handled.
*/
static uint_fast16_t Current_Command = 0;
/* Private Function Prototypes */
static void ConsoleISR(void);
static bool ConsoleCommandMatches(const char8 * const command_name);
static void ReverseString(char8 * value, uint32_t length);
/* Inline Functions */
//! Swaps the characters in x and y.
static inline void Swap_Char8(char8 * x, char8 * y)
{
uint8_t temp = *x;
*x = *y;
*y = temp;
}
static inline void Reset_Command_Buffer()
{
taskENTER_CRITICAL();
for (uint_fast16_t i = 0; i < COMM_CONSOLE_COMMAND_MAX_LENGTH; i++)
{
Command_Buffer[i] = COMM_CONSOLE_STRING_TERMINATOR;
}
Command_Buffer_Index = 0;
taskEXIT_CRITICAL();
}
/* Public Functions */
//! Initializes the console.
/*!
* \ingroup CONSOLE
*/
void COMM_Console_Init(void)
{
// Enable the pullup on the Rx pin to keep the noise down.
Cy_GPIO_SetDrivemode(UART_Console_rx_PORT, UART_Console_rx_NUM, CY_GPIO_DM_PULLUP);
UART_Console_Start();
/// Unmask only the RX FIFO not empty interrupt bit.
UART_Console_HW->INTR_RX_MASK = SCB_INTR_RX_MASK_NOT_EMPTY_Msk;
Cy_SysInt_Init(&Int_UART_Console_cfg, ConsoleISR);
NVIC_ClearPendingIRQ(Int_UART_Console_cfg.intrSrc);
NVIC_EnableIRQ(Int_UART_Console_cfg.intrSrc);
}
//! Parses and handle console commands in the background.
/*!
* \ingroup CONSOLE
*
* The [UML State Machine Diagram](http://www.uml-diagrams.org/state-machine-diagrams.html) below
* shows how the console messages processed by this code. Note that all of the *Character Rx'd*
* transitions occur in the #UART_Console_SPI_UART_ISR_EntryCallback() itself on the PSoC4, in
* #ConsoleRxISR() on the PSoC5, and in #ConsoleISR() on the PSoC6, to improve overall performance.
*
* \startuml{COMM_Console_Task.png} "Console Task"
*
* skinparam headerFontSize 18
* skinparam state {
* BackgroundColor #eeeeee
* BackgroundColor<<Error>> #ffaaaa
* FontName Impact
* FontSize 18
* }
* skinparam note {
* FontName "Comic Sans MS"
* FontStyle italic
* }
*
* state "Initializing" as STATE_INITIALIZING
* [*] --> STATE_INITIALIZING
* note left of STATE_INITIALIZING : Wait for the rest of the system to come online.
* state "Display Powerup Info" as STATE_DISPLAY_POWERUP_INFO
* STATE_DISPLAY_POWERUP_INFO : do/ print OS version
* STATE_DISPLAY_POWERUP_INFO : do/ print configuration (debug or release)
* STATE_INITIALIZING --> STATE_DISPLAY_POWERUP_INFO : after(100ms)
* state "Idle" as STATE_IDLE
* STATE_IDLE : do/ RTOS_Sleep()
* STATE_DISPLAY_POWERUP_INFO --> STATE_IDLE
* state STATE_IS_EOM <<choice>>
* note top of STATE_IS_EOM : This happens in\nUART_Console_SPI_UART_ISR_ExitCallback() on PSoC4,\nConsoleRxISR() on PSoC5,\nand ConsoleISR() on PSoC6.
* STATE_IDLE --> STATE_IS_EOM : character rx'd
* state STATE_IS_COMMAND_BUFFER_FULL <<choice>>
* note top of STATE_IS_COMMAND_BUFFER_FULL : This happens in\nUART_Console_SPI_UART_ISR_ExitCallback() on PSoC4,\nConsoleRxISR() on PSoC5,\nand ConsoleISR() on PSoC6.
* STATE_IS_EOM --> STATE_IS_COMMAND_BUFFER_FULL : [else]
* state "Identify Command" as STATE_IDENTIFY_COMMAND
* STATE_IDENTIFY_COMMAND : do/ look for command in the COMM_Console_Command_Table[]
* STATE_IS_EOM --> STATE_IDENTIFY_COMMAND : [rx'd character is EOM]
* STATE_IDLE --> STATE_IDENTIFY_COMMAND : COMM_Console_Execute_Internal_Command()
* state "Command Too Long" as STATE_COMMAND_TOO_LONG
* STATE_COMMAND_TOO_LONG : do/ print error message
* STATE_COMMAND_TOO_LONG : do/ reset command buffer
* STATE_IS_COMMAND_BUFFER_FULL --> STATE_COMMAND_TOO_LONG : [command buffer is full]
* STATE_IS_COMMAND_BUFFER_FULL --> STATE_IDLE : [else]/\nAppend received character to command buffer
* STATE_COMMAND_TOO_LONG --> STATE_IDLE
* state "Execute Command" as STATE_EXECUTE_COMMAND
* STATE_EXECUTE_COMMAND : do/ execute console command
* STATE_EXECUTE_COMMAND : exit/ reset command buffer
* STATE_EXECUTE_COMMAND --> STATE_IDLE
* STATE_IDENTIFY_COMMAND --> STATE_EXECUTE_COMMAND : [command matched]
* state "Unknown Command" as STATE_UNKNOWN_COMMAND
* STATE_UNKNOWN_COMMAND : do/ print error message
* STATE_UNKNOWN_COMMAND : do/ reset command buffer
* STATE_IDENTIFY_COMMAND --> STATE_UNKNOWN_COMMAND : [else]
* STATE_UNKNOWN_COMMAND --> STATE_IDLE
*
* left footer Key: UML 2.5\nLast modified 2020-12-14
* \enduml
*
* \return None (infinite loop)
*/
void COMM_Console_Task(void * pvParameters)
{
static TickType_t xTicksToWait = pdMS_TO_TICKS(10);
static uint32_t * NotificationValue;
while(true)
{
(void) xTaskNotifyWait(0, 0, (uint32_t *)&NotificationValue, xTicksToWait);
// Change to the next state atomically.
taskENTER_CRITICAL();
Current_State = Next_State;
taskEXIT_CRITICAL();
switch (Current_State)
{
default:
case COMM_STATE_INITIALIZING:
Next_State = COMM_STATE_DISPLAY_POWERUP_INFO;
vTaskDelay(pdMS_TO_TICKS(10));
xTicksToWait = 1;
break;
case COMM_STATE_DISPLAY_POWERUP_INFO:
COMM_Console_Print_String("[COMM] ");
COMM_RTOS_HandleConsoleVersion(NULL, 0);
vTaskDelay(pdMS_TO_TICKS(10));
COMM_Console_Print_String("[COMM] Console ready (awaiting commands).\n");
Next_State = COMM_STATE_IDLE;
xTicksToWait = 1;
break;
case COMM_STATE_IDLE:
xTicksToWait = pdMS_TO_TICKS(100);
break;
case COMM_STATE_COMMAND_TOO_LONG:
COMM_Console_Print_String("[COMM] ERROR: Command \"");
COMM_Console_Print_String(Command_Buffer);
COMM_Console_Print_String("\" too long!\n");
Reset_Command_Buffer();
Next_State = COMM_STATE_IDLE;
xTicksToWait = 1;
break;
case COMM_STATE_IDENTIFY_COMMAND:
Current_Command = UINT_FAST16_MAX;
for (uint_fast16_t i = 0; i < COMM_N_CONSOLE_COMMANDS; i++)
{
if (ConsoleCommandMatches(COMM_Console_Command_Table[i].Command_Name) == true)
{
Current_Command = i;
Next_State = COMM_STATE_EXECUTE_COMMAND;
xTicksToWait = 1;
break;
}
}
if (Current_Command == UINT_FAST16_MAX)
{
// No matching command was found.
Next_State = COMM_STATE_UNKNOWN_COMMAND;
xTicksToWait = 1;
}
break;
case COMM_STATE_EXECUTE_COMMAND:
if (COMM_Console_Command_Table[Current_Command].Execute_Command != NULL)
{
COMM_Console_Command_Result_T result = COMM_Console_Command_Table[Current_Command].Execute_Command(Command_Buffer, Command_Buffer_Index);
if (result == COMM_CONSOLE_CMD_RESULT_PARAMETER_ERROR)
{
COMM_Console_Print_String("ERROR: Parameter error!\n");
}
}
Reset_Command_Buffer();
Next_State = COMM_STATE_IDLE;
xTicksToWait = 1;
break;
case COMM_STATE_UNKNOWN_COMMAND:
COMM_Console_Print_String("ERROR: Command \"");
COMM_Console_Print_String(Command_Buffer);
COMM_Console_Print_String("\" not recognized! Try '?' for help.\n");
Reset_Command_Buffer();
Next_State = COMM_STATE_IDLE;
xTicksToWait = 1;
break;
}
}
}
SystemKResult_T HW_Execute_Console_Command(const uint8_t * const command)
{
COMM_Console_Execute_Internal_Command(command);
return SYSTEMK_RESULT_SUCCESS;
}
//! Executes a (potentially cross-task) console command.
/*!
* This function is used to initiate a console command from a software source internal to this
* CPU. This provides a way to use preexisting console commands on TX-only consoles.
*
* \note If two calls to this function are made back-to-back (before the COMM_Console_Task() has an
* opportunity to run), only the second command will be executed, as it will have overwritten the
* first. Allow time for the console commands to execute between calls to this function.
*
* \param command String containing the command to be executed.
*/
void COMM_Console_Execute_Internal_Command(const uint8_t * const command)
{
bool finished = false;
uint_fast16_t i = 0;
taskENTER_CRITICAL();
while ( (finished == false) &&
(i < COMM_CONSOLE_COMMAND_MAX_LENGTH) &&
(command[i] != COMM_CONSOLE_END_OF_MESSAGE ) &&
(command[i] != COMM_CONSOLE_STRING_TERMINATOR )
)
{
Command_Buffer[i] = command[i];
i++;
}
Command_Buffer_Index = i;
// If there is still room, terminate the command.
if (i < COMM_CONSOLE_COMMAND_MAX_LENGTH)
{
Command_Buffer[i] = COMM_CONSOLE_END_OF_MESSAGE;
}
taskEXIT_CRITICAL();
Next_State = COMM_STATE_IDENTIFY_COMMAND;
xTaskNotifyGive(COMM_Console_Task_Handle);
}
//! Prints a NULL-terminated string to the serial console.
void COMM_Console_Print_String(const char8 * const text)
{
for (size_t i = 0; i < MAX_CONSOLE_STRING_LENGTH; i++)
{
// Check for the end of the string. If there is no NULL terminator, up to
// MAX_CONSOLE_STRING_LENGTH characters of randomness will be printed.
if (text[i] == COMM_CONSOLE_STRING_TERMINATOR)
{
break;
}
// Send out the string, one character at a time.
COMM_Console_PutChar(text[i]);
}
}
//! Prints a 32-bit unsigned integer to the serial console.
void COMM_Console_Print_UInt32(uint32_t value)
{
// The largest string for a unit32_t is 10 characters (4294967296).
char8 buffer[10+1];
uint_fast8_t buffer_index = 0;
while (value > 9)
{
uint8_t digit_index = value % 10;
buffer[buffer_index] = DIGITS[digit_index];
value = value / 10;
buffer_index++;
}
buffer[buffer_index] = DIGITS[value];
buffer_index++;
ReverseString(buffer, buffer_index);
// NULL-terminate the string.
buffer[buffer_index] = 0;
COMM_Console_Print_String(buffer);
}
//! Prints a 32-bit signed integer to the serial console.
void COMM_Console_Print_SInt32(int32_t value)
{
if (value < 0)
{
value *= -1;
COMM_Console_PutChar('-');
}
COMM_Console_Print_UInt32(value);
}
//! Prints a 32-bit unsigned integer to the serial console using a hexadecimal representation.
void COMM_Console_Print_UInt32AsHex(uint32_t value)
{
// The largest hexadecimal string for a unit32_t is 8 characters (FFFFFFFF).
char8 buffer[8+1];
uint_fast8_t buffer_index = 0;
while (value > 15)
{
uint8_t digit_index = value % 16;
buffer[buffer_index] = DIGITS[digit_index];
value = value / 16;
buffer_index++;
}
buffer[buffer_index] = DIGITS[value];
buffer_index++;
ReverseString(buffer, buffer_index);
// NULL-terminate the string.
buffer[buffer_index] = 0;
COMM_Console_PutChar('0');
COMM_Console_PutChar('x');
COMM_Console_Print_String(buffer);
}
//! Prints a 64-bit unsigned integer to the serial console.
void COMM_Console_Print_UInt64(uint64_t value)
{
// The largest string for a unit64_t is 20 characters (18446744073709551615).
char8 buffer[20+1];
uint_fast8_t buffer_index = 0;
while (value > 9)
{
uint8_t digit_index = value % 10;
buffer[buffer_index] = DIGITS[digit_index];
value = value / 10;
buffer_index++;
}
buffer[buffer_index] = DIGITS[value];
buffer_index++;
ReverseString(buffer, buffer_index);
// NULL-terminate the string.
buffer[buffer_index] = 0;
COMM_Console_Print_String(buffer);
}
//! Prints a 64-bit unsigned integer to the serial console using a hexadecimal representation.
void COMM_Console_Print_UInt64AsHex(uint64_t value)
{
// The largest hexadecimal string for a unit64_t is 16 characters (FFFFFFFFFFFFFFFF).
char8 buffer[16+1];
uint_fast8_t buffer_index = 0;
while (value > 15)
{
uint8_t digit_index = value % 16;
buffer[buffer_index] = DIGITS[digit_index];
value = value / 16;
buffer_index++;
}
buffer[buffer_index] = DIGITS[value];
buffer_index++;
ReverseString(buffer, buffer_index);
// NULL-terminate the string.
buffer[buffer_index] = 0;
COMM_Console_PutChar('0');
COMM_Console_PutChar('x');
COMM_Console_Print_String(buffer);
}
//! Prints a floating-point number to the serial console.
/*!
* With thanks to Rick Regan and his [Quick and Dirty Floating-Point to Decimal Conversion](https://www.exploringbinary.com/quick-and-dirty-floating-point-to-decimal-conversion/).
*/
void COMM_Console_Print_Float(float value)
{
#define MAX_INTEGRAL_DIGITS 12
#define MAX_FRACTIONAL_DIGITS 6
#define BUFFER_SIZE (MAX_INTEGRAL_DIGITS + MAX_FRACTIONAL_DIGITS + 2)
char8 buffer[BUFFER_SIZE];
char8 integral_buffer_reversed[MAX_INTEGRAL_DIGITS];
uint16_t buffer_index = 0;
double integral_value;
double fractional_value;
bool overflow = false;
if (value < 0.0)
{
COMM_Console_Print_String("-");
value *= -1.0;
}
// Break the given value into fractional and integral parts.
fractional_value = modf(value, &integral_value);
if (integral_value > 0)
{
// Convert the integral part.
while ((integral_value > 0) && (buffer_index < MAX_INTEGRAL_DIGITS))
{
integral_buffer_reversed[buffer_index++] = '0' + (int)fmod(integral_value, 10);
integral_value = floor(integral_value / 10);
}
// If there is still an integral part remaining, and overflow has occurred.
if (integral_value > 0)
{
overflow = true;
}
// Reverse and append the integral part.
for (uint16_t i = 0; i < buffer_index; i++)
{
buffer[i] = integral_buffer_reversed[buffer_index-i-1];
}
}
else
{
// Append a leading zero.
buffer[buffer_index++] = '0';
}
// Append the decimal point.
buffer[buffer_index++] = '.';
// Convert the fractional part, even if it is zero, and leave room for the NULL terminator.
while (buffer_index < (BUFFER_SIZE - 1))
{
fractional_value *= 10;
buffer[buffer_index++] = '0' + (int)fractional_value;
fractional_value = modf(fractional_value, &integral_value);
}
// Append the NULL terminator.
buffer[buffer_index] = 0;
if (overflow == true)
{
COMM_Console_Print_String("OVERFLOW");
}
else
{
COMM_Console_Print_String(buffer);
}
}
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
//! Converts a byte to a two-character hexadecimal representation.
/*!
* \param buffer Buffer into which to place the resulting sting. It needs to be at least three
* characters wide.
* \param byte The byte to be converted.
*/
void COMM_Console_ByteToHex(char8 * buffer, uint8_t byte)
{
if (byte < 16)
{
buffer[0] = '0';
buffer[1] = DIGITS[byte];
buffer[2] = 0;
}
else
{
buffer[0] = DIGITS[byte / 16];
buffer[1] = DIGITS[byte % 16];
buffer[2] = 0;
}
}
#if (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
/* Private Functions */
static void ConsoleISR(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
// Check for the "Rx FIFO not empty" interrput.
if ((UART_Console_HW->INTR_RX_MASKED & SCB_INTR_RX_MASKED_NOT_EMPTY_Msk ) != 0)
{
// Clear the "Rx FIFO not empty" interrput.
UART_Console_HW->INTR_RX = UART_Console_HW->INTR_RX & SCB_INTR_RX_NOT_EMPTY_Msk;
// Get the character.
uint32_t value = UART_Console_Get();
// Check if there is actually data. Sometimes the flag is set when there is no data (why?).
if (value != CY_SCB_UART_RX_NO_DATA)
{
char8 rx_data = (char8) value;
// Determine what to do with it.
if (Command_Buffer_Index < COMM_CONSOLE_COMMAND_MAX_LENGTH)
{
if (rx_data == COMM_CONSOLE_END_OF_MESSAGE)
{
Command_Buffer[Command_Buffer_Index] = COMM_CONSOLE_STRING_TERMINATOR;
Next_State = COMM_STATE_IDENTIFY_COMMAND;
vTaskNotifyGiveFromISR(COMM_Console_Task_Handle, &xHigherPriorityTaskWoken);
}
else
{
Command_Buffer[Command_Buffer_Index] = rx_data;
Command_Buffer_Index++;
}
}
else
{
Next_State = COMM_STATE_COMMAND_TOO_LONG;
vTaskNotifyGiveFromISR(COMM_Console_Task_Handle, &xHigherPriorityTaskWoken);
}
}
}
NVIC_ClearPendingIRQ(Int_UART_Console_cfg.intrSrc);
// If the state needs to change, a context switch might be required.
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
static bool ConsoleCommandMatches(const char8 * const command_name)
{
uint32_t i = 0;
bool is_match = false;
if (Command_Buffer[i] == command_name[i])
{
is_match = true;
i++;
}
while ( (is_match == true) &&
(i < COMM_CONSOLE_COMMAND_MAX_LENGTH) &&
(Command_Buffer[i] != COMM_CONSOLE_PARAMETER_DELIMITER) &&
(Command_Buffer[i] != COMM_CONSOLE_END_OF_MESSAGE ) &&
(Command_Buffer[i] != COMM_CONSOLE_STRING_TERMINATOR )
)
{
if ( Command_Buffer[i] != command_name[i] )
{
is_match = false;
}
i++;
}
return is_match;
}
//! Reverses a string in place.
/*!
* \param value Pointer to the string to be reversed.
* \param length Length of the string, including the NULL terminator.
*/
static void ReverseString(char8 * value, uint32_t length)
{
if (length > 1)
{
uint_fast32_t start = 0;
uint_fast32_t end = length - 1;
while (start < end)
{
Swap_Char8(value + start, value + end);
start++;
end--;
}
}
}
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)

View file

@ -0,0 +1,144 @@
/** \file
* \brief This file defines the interface to a simple serial debug console and command interpreter.
*
* \note As always, <project.h> and <CONFIG.h> should be included <I>before</I> this file.
*/
#ifndef COMM_CONSOLE_H
#define COMM_CONSOLE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Include Files */
/* Preprocessor and Type Definitions */
#define COMM_CONSOLE_TASK_STACK_SIZE_in_bytes 512
#define COMM_Console_PutChar UART_and_BLE_PutChar
#define COMM_Console_PutString UART_and_BLE_PutString
#define COMM_CONSOLE_COMMAND_MAX_LENGTH 50
//! Character signifying the end of a console message.
#define COMM_CONSOLE_END_OF_MESSAGE ('\n')
//! Character used between parameters in a console message.
#define COMM_CONSOLE_PARAMETER_DELIMITER (' ')
//! Character signifying the end of a string.
#define COMM_CONSOLE_STRING_TERMINATOR ('\0')
//! Result of executing a console command callback.
typedef enum
{
COMM_CONSOLE_CMD_RESULT_UNKNOWN = 0,
COMM_CONSOLE_CMD_RESULT_SUCCESS = 1,
COMM_CONSOLE_CMD_RESULT_PARAMETER_ERROR = 2
} COMM_Console_Command_Result_T;
//! Result of parsing a console command parameter.
typedef enum
{
COMM_CONSOLE_PARAMETER_RESULT_UNKNOWN = 0,
COMM_CONSOLE_PARAMETER_RESULT_SUCCESS = 1,
COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_ERROR = 2,
COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_END = 3
} COMM_Console_Parameter_Result_T;
//! Prototype of a console command callback.
/*!
* \ingroup CONSOLE
* All console commands must use this signature.
*
* \param[in] data Pointer to the string containg the console command (and any arguments).
* \param[in] size Size (in char8) of the data string.
* \return #COMM_CONSOLE_CMD_RESULT_SUCCESS on success
* \return #COMM_Console_Command_Result_T otherwise
*/
typedef COMM_Console_Command_Result_T (* const COMM_Console_Command_Handler_T)(char8 * data, uint32_t size);
typedef struct
{
const char8 * const Command_Name;
const char8 * const Help;
COMM_Console_Command_Handler_T Execute_Command;
} COMM_Console_Command_Table_Entry_T;
/* Public Variables */
//! Handle of the COMM_Console_Task() given when the task was created.
extern TaskHandle_t COMM_Console_Task_Handle;
/* Public Functions */
void COMM_Console_Init(void);
void COMM_Console_Task(void * pvParameters);
void COMM_Console_Execute_Internal_Command(const uint8_t * const command);
void COMM_Console_Print_String(const char8 * const text);
void COMM_Console_Print_UInt32(uint32_t value);
void COMM_Console_Print_SInt32(int32_t value);
void COMM_Console_Print_UInt32AsHex(uint32_t value);
void COMM_Console_Print_UInt64(uint64_t value);
void COMM_Console_Print_UInt64AsHex(uint64_t value);
void COMM_Console_Print_Float(float value);
void COMM_Console_ByteToHex(char8 * buffer, uint8_t byte);
/* Inline Functions */
//! Prints an 8-bit unsigned integer to the serial console.
inline void COMM_Console_Print_UInt8(uint8_t value)
{
COMM_Console_Print_UInt32((uint32_t) value);
}
//! Prints an 8-bit unsigned integer to the serial console using a hexadecimal representation.
inline void COMM_Console_Print_UInt8AsHex(uint8_t value)
{
COMM_Console_Print_UInt32AsHex((uint32_t) value);
}
//! Prints an 8-bit signed integer to the serial console.
inline void COMM_Console_Print_Int8(int8_t value)
{
COMM_Console_Print_SInt32((int32_t) value);
}
//! Prints a 16-bit unsigned integer to the serial console.
inline void COMM_Console_Print_UInt16(uint16_t value)
{
COMM_Console_Print_UInt32((uint32_t) value);
}
//! Prints a 16-bit unsigned integer to the serial console using a hexadecimal representation.
inline void COMM_Console_Print_UInt16AsHex(uint16_t value)
{
COMM_Console_Print_UInt32AsHex((uint32_t) value);
}
//! Prints a 16-bit signed integer to the serial console.
inline void COMM_Console_Print_Int16(int16_t value)
{
COMM_Console_Print_SInt32((int32_t) value);
}
static inline void UART_and_BLE_PutChar(uint8 txDataByte)
{
UART_Console_Put(txDataByte);
COMM_BLE_UART_PutChar(txDataByte);
}
static inline void UART_and_BLE_PutString(const char8 string[])
{
UART_Console_PutString(string);
COMM_BLE_UART_PutString(string, strlen(string));
}
#ifdef __cplusplus
}
#endif
#endif // COMM_CONSOLE_H

View file

@ -0,0 +1,254 @@
/** \file
* \brief This file implements utility functions used by the command interpreter.
*/
/**
* \ingroup CONSOLE
*/
/* Include Files */
#include "KTag.h"
#if (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
/* Local Definitions and Constants */
/* Public Variables */
/* Private Variables */
/* Private Function Prototypes */
/* Public Functions */
//! Find the start location of the nth parameter in the buffer.
/*!
* \note The command itself is parameter 0.
*/
COMM_Console_Parameter_Result_T COMM_Console_FindNthParameter(const char * const buffer, const uint8_t parameterNumber, const char ** parameterLocation)
{
uint32_t buffer_index = 0;
uint32_t parameter_index = 0;
COMM_Console_Parameter_Result_T result = COMM_CONSOLE_PARAMETER_RESULT_SUCCESS;
while (parameterNumber != parameter_index)
{
if (buffer[buffer_index] == COMM_CONSOLE_PARAMETER_DELIMITER)
{
parameter_index++;
}
else if (buffer[buffer_index] == COMM_CONSOLE_END_OF_MESSAGE)
{
result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_ERROR;
break;
}
else if (buffer[buffer_index] == COMM_CONSOLE_STRING_TERMINATOR)
{
result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_ERROR;
break;
}
buffer_index++;
}
if (result == COMM_CONSOLE_PARAMETER_RESULT_SUCCESS)
{
*parameterLocation = &buffer[buffer_index];
}
return result;
}
COMM_Console_Parameter_Result_T COMM_Console_DecodeParameterUInt8(const char * const buffer, uint8_t * const parameterUInt8)
{
uint8_t value = 0;
COMM_Console_Parameter_Result_T result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_ERROR;
// Strings containing uint8s range from "0" to "255". The large number has three characters.
uint_fast16_t MAX_CHARACTERS = 3;
uint_fast16_t index = 0;
while (index < (MAX_CHARACTERS + 1))
{
if ((buffer[index] >= '0') && (buffer[index] <= '9'))
{
value *= 10;
value += buffer[index] - '0';
index++;
}
else if ( (buffer[index] == COMM_CONSOLE_PARAMETER_DELIMITER) ||
(buffer[index] == COMM_CONSOLE_STRING_TERMINATOR) ||
(buffer[index] == COMM_CONSOLE_END_OF_MESSAGE) )
{
result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_END;
break;
}
else
{
result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_ERROR;
break;
}
}
if (result == COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_END)
{
result = COMM_CONSOLE_PARAMETER_RESULT_SUCCESS;
*parameterUInt8 = value;
}
return result;
}
COMM_Console_Parameter_Result_T COMM_Console_DecodeParameterUInt16(const char * const buffer, uint16_t * const parameterUInt16)
{
uint16_t value = 0;
COMM_Console_Parameter_Result_T result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_ERROR;
// Strings containing uint16s range from "0" to "65535". The large number has five characters.
uint_fast16_t MAX_CHARACTERS = 5;
uint_fast16_t index = 0;
while (index < (MAX_CHARACTERS + 1))
{
if ((buffer[index] >= '0') && (buffer[index] <= '9'))
{
value *= 10;
value += buffer[index] - '0';
index++;
}
else if ( (buffer[index] == COMM_CONSOLE_PARAMETER_DELIMITER) ||
(buffer[index] == COMM_CONSOLE_STRING_TERMINATOR) ||
(buffer[index] == COMM_CONSOLE_END_OF_MESSAGE) )
{
result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_END;
break;
}
else
{
result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_ERROR;
break;
}
}
if (result == COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_END)
{
result = COMM_CONSOLE_PARAMETER_RESULT_SUCCESS;
*parameterUInt16 = value;
}
return result;
}
COMM_Console_Parameter_Result_T COMM_Console_DecodeParameterInt32(const char * const buffer, int32_t * const parameterInt32)
{
int32_t value = 0;
COMM_Console_Parameter_Result_T result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_ERROR;
bool is_negative = false;
// Strings containing int32s range from "-2147483648" to "2147483647". The negative number has eleven characters.
uint_fast16_t MAX_CHARACTERS = 11;
uint_fast16_t index = 0;
if (buffer[index] == '-')
{
is_negative = true;
index++;
}
while (index < (MAX_CHARACTERS + 1))
{
if ((buffer[index] >= '0') && (buffer[index] <= '9'))
{
value *= 10;
value += buffer[index] - '0';
index++;
}
else if ( (buffer[index] == COMM_CONSOLE_PARAMETER_DELIMITER) ||
(buffer[index] == COMM_CONSOLE_STRING_TERMINATOR) ||
(buffer[index] == COMM_CONSOLE_END_OF_MESSAGE) )
{
result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_END;
break;
}
else
{
result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_ERROR;
break;
}
}
if (is_negative == true)
{
value *= -1;
}
if (result == COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_END)
{
result = COMM_CONSOLE_PARAMETER_RESULT_SUCCESS;
*parameterInt32 = value;
}
return result;
}
COMM_Console_Parameter_Result_T COMM_Console_DecodeParameterUInt32(const char * const buffer, uint32_t * const parameterUInt32)
{
uint32_t value = 0;
COMM_Console_Parameter_Result_T result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_ERROR;
// Strings containing uint32s range from "0" to "4294967296". The large number has ten characters.
uint_fast16_t MAX_CHARACTERS = 10;
uint_fast16_t index = 0;
while (index < (MAX_CHARACTERS + 1))
{
if ((buffer[index] >= '0') && (buffer[index] <= '9'))
{
value *= 10;
value += buffer[index] - '0';
index++;
}
else if ( (buffer[index] == COMM_CONSOLE_PARAMETER_DELIMITER) ||
(buffer[index] == COMM_CONSOLE_STRING_TERMINATOR) ||
(buffer[index] == COMM_CONSOLE_END_OF_MESSAGE) )
{
result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_END;
break;
}
else
{
result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_ERROR;
break;
}
}
if (result == COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_END)
{
result = COMM_CONSOLE_PARAMETER_RESULT_SUCCESS;
*parameterUInt32 = value;
}
return result;
}
COMM_Console_Parameter_Result_T COMM_Console_DecodeHexParameterUInt64(const char * const buffer, uint64_t * const parameterUInt64)
{
COMM_Console_Parameter_Result_T result = COMM_CONSOLE_PARAMETER_RESULT_SUCCESS;
struct _reent context;
context._errno = 0;
*parameterUInt64 = _strtoull_r(&context, buffer, NULL, 16);
if (context._errno != 0)
{
result = COMM_CONSOLE_PARAMETER_RESULT_PARAMETER_ERROR;
}
return result;
}
/* Private Functions */
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)

View file

@ -0,0 +1,50 @@
/** \file
* \brief Utility functions used by the command interpreter.
*
* \note As always, <project.h> and <RTOS.h> should be included <I>before</I> this file.
*/
#ifndef COMM_CONSOLE_UTIL_H
#define COMM_CONSOLE_UTIL_H
#ifdef __cplusplus
extern "C" {
#endif
#if (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
/* Include Files */
/* Preprocessor and Type Definitions */
/* Public Variables */
/* Public Functions */
COMM_Console_Parameter_Result_T COMM_Console_FindNthParameter(const char * const buffer, const uint8_t parameterNumber, const char ** parameterLocation);
COMM_Console_Parameter_Result_T COMM_Console_DecodeParameterUInt8(const char * const buffer, uint8_t * const parameterUInt8);
COMM_Console_Parameter_Result_T COMM_Console_DecodeParameterUInt16(const char * const buffer, uint16_t * const parameterUInt16);
COMM_Console_Parameter_Result_T COMM_Console_DecodeParameterInt32(const char * const buffer, int32_t * const parameterInt32);
COMM_Console_Parameter_Result_T COMM_Console_DecodeParameterUInt32(const char * const buffer, uint32_t * const parameterUInt32);
COMM_Console_Parameter_Result_T COMM_Console_DecodeHexParameterUInt64(const char * const buffer, uint64_t * const parameterUInt64);
//! Returns `true` if this character marks the end of a console message; `false` otherwise.
inline bool COMM_Console_IsEndOfMessage(char8 character)
{
bool result = false;
if ( (character == COMM_CONSOLE_END_OF_MESSAGE) ||
(character == COMM_CONSOLE_STRING_TERMINATOR) )
{
result = true;
}
return result;
}
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
#ifdef __cplusplus
}
#endif
#endif // COMM_CONSOLE_UTIL_H

View file

@ -0,0 +1,33 @@
/** \file
* \brief This file implements the I²C bus.
*
* See COMM_I2C_Bus.h for a detailed description of the functionality implemented by this code.
*/
/* Include Files */
#include "KTag.h"
/* Local Definitions and Constants */
/* Public Variables */
SemaphoreHandle_t COMM_I2C_Bus_Mutex = NULL;
/* Private Variables */
/* Private Function Prototypes */
/* Public Functions */
//! Initializes the I²C bus.
/*!
*
*/
void COMM_I2C_Init(void)
{
COMM_I2C_Bus_Mutex = xSemaphoreCreateMutex();
I2C_Start();
}
/* Private Functions */

View file

@ -0,0 +1,29 @@
/** \file
* \brief This file defines the interface to the I²C bus.
*
*/
#ifndef COMM_I2C_BUS_H
#define COMM_I2C_BUS_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
/* Include Files */
/* Public Variables */
extern SemaphoreHandle_t COMM_I2C_Bus_Mutex;
/* Public Functions */
void COMM_I2C_Init(void);
#ifdef __cplusplus
}
#endif
#endif // COMM_I2C_BUS_H

View file

@ -0,0 +1,285 @@
/** \file
* \brief This file implements messaging using inter-processor communication (IPC).
*
* \see https://community.cypress.com/thread/36182.
*/
/**
* \ingroup CONSOLE
*/
/* Include Files */
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <project.h>
#include "COMM_IPC_Messages.h"
/* Private Function Prototypes */
#if (__CORTEX_M == 0)
static void Message_Received_for_CM0(uint32_t * msg);
static void Message_Received_by_CM4(void);
#endif // (__CORTEX_M == 0)
#if (__CORTEX_M == 4)
static void Message_Received_for_CM4(uint32_t * msg);
static void Message_Received_by_CM0(void);
#endif // (__CORTEX_M == 4)
static void IPC_UserPipeInit(void);
static void IPC_UserPipeISR(void);
/* Local Definitions and Constants */
//! Number of clients supported on the user pipe.
#define CY_IPC_USRPIPE_CLIENT_CNT (uint32_t)(8u)
#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_CM0_EP (uint32_t)(2u)
#define CY_IPC_EP_USRPIPE_ADDR_CM4_EP (uint32_t)(3u)
#if (CY_CPU_CORTEX_M0P)
#define IPC_EP_USRPIPE_ADDR CY_IPC_EP_USRPIPE_ADDR_CM0_EP
#else
#define IPC_EP_USRPIPE_ADDR CY_IPC_EP_USRPIPE_ADDR_CM4_EP
#endif /* (CY_CPU_CORTEX_M0P) */
/* User Pipe Configuration */
#define IPC_USRPIPE_CHAN_MASK_CM0 (uint32_t)(0x0001ul << CY_IPC_CHAN_USRPIPE_CM0)
#define IPC_USRPIPE_CHAN_MASK_CM4 (uint32_t)(0x0001ul << CY_IPC_CHAN_USRPIPE_CM4)
#define IPC_USRPIPE_INTR_MASK (uint32_t)( IPC_USRPIPE_CHAN_MASK_CM0 | IPC_USRPIPE_CHAN_MASK_CM4 )
#define IPC_INTR_USRPIPE_PRIOR_CM0 (uint32_t)(1u) /* Notifier Priority */
#define IPC_INTR_USRPIPE_PRIOR_CM4 (uint32_t)(1u) /* Notifier Priority */
#define IPC_INTR_USRPIPE_MUX_CM0 (uint32_t)(7u) /* IPC CYPRESS PIPE */
#define IPC_USRPIPE_CONFIG_CM0 (uint32_t)(IPC_USRPIPE_INTR_MASK << CY_IPC_PIPE_CFG_IMASK_Pos)\
|(CY_IPC_INTR_USRPIPE_CM0 << CY_IPC_PIPE_CFG_INTR_Pos )\
|(CY_IPC_CHAN_USRPIPE_CM0)
#define IPC_USRPIPE_CONFIG_CM4 (uint32_t)(IPC_USRPIPE_INTR_MASK << CY_IPC_PIPE_CFG_IMASK_Pos)\
|(CY_IPC_INTR_USRPIPE_CM4 << CY_IPC_PIPE_CFG_INTR_Pos )\
|(CY_IPC_CHAN_USRPIPE_CM4)
#define USRPIPE_CONFIG \
{\
/* .ep0ConfigData */ {\
/* .ipcNotifierNumber */ CY_IPC_INTR_USRPIPE_CM0,\
/* .ipcNotifierPriority */ IPC_INTR_USRPIPE_PRIOR_CM0,\
/* .ipcNotifierMuxNumber */ IPC_INTR_USRPIPE_MUX_CM0,\
/* .epAddress */ CY_IPC_EP_USRPIPE_ADDR_CM0_EP,\
/* .epConfig */ IPC_USRPIPE_CONFIG_CM0\
},\
/* .ep1ConfigData */ {\
/* .ipcNotifierNumber */ CY_IPC_INTR_USRPIPE_CM4,\
/* .ipcNotifierPriority */ IPC_INTR_USRPIPE_PRIOR_CM4,\
/* .ipcNotifierMuxNumber */ 0u,\
/* .epAddress */ CY_IPC_EP_USRPIPE_ADDR_CM4_EP,\
/* .epConfig */ IPC_USRPIPE_CONFIG_CM4\
},\
/* .endpointClientsCount */ CY_IPC_USRPIPE_CLIENT_CNT,\
/* .endpointsCallbacksArray */ ipc_pipe_CbArray,\
/* .userPipeIsrHandler */ &IPC_UserPipeISR\
}
//! Client ID for messages from the CM0 to the CM4
#define COMM_IPC_CM0_TO_CM4_CLIENT_ID 0
//! Client ID for messages from the CM4 to the CM0
#define COMM_IPC_CM4_TO_CM0_CLIENT_ID 1
/* Public Variables */
/* Private Variables */
#if (__CORTEX_M == 0)
static COMM_IPCMessage_T MessageBuffer =
{
.ClientID = _VAL2FLD(CY_IPC_PIPE_MSG_CLIENT, COMM_IPC_CM0_TO_CM4_CLIENT_ID) | _VAL2FLD(CY_IPC_PIPE_MSG_USR, 0) | _VAL2FLD(CY_IPC_PIPE_MSG_RELEASE, IPC_USRPIPE_INTR_MASK),
.MessageID = COMM_SMM_DefaultNoMessage,
.Data = NULL
};
static volatile bool OK_to_send_from_CM0_to_CM4 = true;
#endif // (__CORTEX_M == 0)
#if (__CORTEX_M == 4)
static COMM_IPCMessage_T MessageBuffer =
{
.ClientID = _VAL2FLD(CY_IPC_PIPE_MSG_CLIENT, COMM_IPC_CM4_TO_CM0_CLIENT_ID) | _VAL2FLD(CY_IPC_PIPE_MSG_USR, 0) | _VAL2FLD(CY_IPC_PIPE_MSG_RELEASE, IPC_USRPIPE_INTR_MASK),
.MessageID = COMM_SMM_DefaultNoMessage,
.Data = NULL
};
static volatile bool OK_to_send_from_CM4_to_CM0 = true;
#endif // (__CORTEX_M == 4)
/* Public Functions */
#if (__CORTEX_M == 0)
//! Initializes the inter-processor communications on the Cortex-M0 core.
/*!
* This should be called *before* calling Cy_SysEnableCM4().
*/
void COMM_InitIPCMessages(void)
{
IPC_UserPipeInit();
// Register a callback to handle messages from CM4.
Cy_IPC_Pipe_RegisterCallback(IPC_EP_USRPIPE_ADDR,
Message_Received_for_CM0,
CY_IPC_EP_CYPIPE_CM4_ADDR);
}
#endif // (__CORTEX_M == 0)
#if (__CORTEX_M == 4)
//! Initializes the inter-processor communications on the Cortex-M4 core.
void COMM_InitIPCMessages(void)
{
IPC_UserPipeInit();
// Register a callback to handle messages from CM0.
Cy_IPC_Pipe_RegisterCallback(IPC_EP_USRPIPE_ADDR,
Message_Received_for_CM4,
CY_IPC_EP_CYPIPE_CM0_ADDR);
}
#endif // (__CORTEX_M == 4)
//! Sends an inter-processor communication message to the other core.
bool COMM_SendMessageToOtherCore(COMM_IPCMessageID_T message_ID, void * message_data)
{
bool message_sent = false;
MessageBuffer.MessageID = message_ID;
MessageBuffer.Data = message_data;
#if (__CORTEX_M == 0)
if (OK_to_send_from_CM0_to_CM4 == true)
{
OK_to_send_from_CM0_to_CM4 = false;
uint32_t timeout_in_us = 2000;
cy_en_ipc_pipe_status_t ipcStatus;
do
{
ipcStatus = Cy_IPC_Pipe_SendMessage(CY_IPC_EP_USRPIPE_ADDR_CM4_EP,
CY_IPC_EP_USRPIPE_ADDR_CM0_EP,
(uint32_t *) &MessageBuffer,
Message_Received_by_CM4);
Cy_SysLib_DelayUs(1u);
timeout_in_us--;
} while((ipcStatus != CY_IPC_PIPE_SUCCESS) && (timeout_in_us != 0));
message_sent = true;
}
#endif // (__CORTEX_M == 0)
#if (__CORTEX_M == 4)
if (OK_to_send_from_CM4_to_CM0 == true)
{
OK_to_send_from_CM4_to_CM0 = false;
uint32_t timeout_in_us = 2000;
cy_en_ipc_pipe_status_t ipcStatus;
do
{
ipcStatus = Cy_IPC_Pipe_SendMessage(CY_IPC_EP_USRPIPE_ADDR_CM0_EP,
CY_IPC_EP_USRPIPE_ADDR_CM4_EP,
(uint32_t *) &MessageBuffer,
Message_Received_by_CM0);
Cy_SysLib_DelayUs(1u);
timeout_in_us--;
} while((ipcStatus != CY_IPC_PIPE_SUCCESS) && (timeout_in_us != 0));
message_sent = true;
}
#endif // (__CORTEX_M == 4)
return message_sent;
}
/* Private Functions */
#if (__CORTEX_M == 0)
//! Callback for messages received by the CM0 core from the CM4 core.
/*!
* \note This code is executed inside an interrupt handler.
*/
static void Message_Received_for_CM0(uint32_t * msg)
{
switch (((COMM_IPCMessage_T *)msg)->MessageID)
{
default:
case COMM_SMM_DefaultNoMessage:
case COMM_SMM_NoMessage:
break;
case COMM_SMM_RebootImmediately:
// Perform a software reset of both cores.
NVIC_SystemReset();
break;
}
}
static void Message_Received_by_CM4(void)
{
OK_to_send_from_CM0_to_CM4 = true;
}
#endif // (__CORTEX_M == 0)
#if (__CORTEX_M == 4)
//! Callback for messages received by the CM4 core from the CM0 core.
/*!
* \note This code is executed inside an interrupt handler.
*/
static void Message_Received_for_CM4(uint32_t * msg)
{
switch (((COMM_IPCMessage_T *)msg)->MessageID)
{
default:
case COMM_SMM_DefaultNoMessage:
case COMM_SMM_NoMessage:
break;
case COMM_SMM_RebootImmediately:
// This message does nothing on CM4
break;
}
}
static void Message_Received_by_CM0(void)
{
OK_to_send_from_CM4_to_CM0 = true;
}
#endif // (__CORTEX_M == 4)
//! Initializes the IPC user pipe.
static void IPC_UserPipeInit(void)
{
static cy_ipc_pipe_callback_ptr_t ipc_pipe_CbArray[CY_IPC_USRPIPE_CLIENT_CNT];
static const cy_stc_ipc_pipe_config_t userPipeConfig = USRPIPE_CONFIG;
uint32_t savedIntrStatus = Cy_SysLib_EnterCriticalSection();
Cy_IPC_Pipe_Init(&userPipeConfig);
Cy_SysLib_ExitCriticalSection(savedIntrStatus);
}
//! Interrupt service routine for the user pipe.
void IPC_UserPipeISR(void)
{
Cy_IPC_Pipe_ExecuteCallback(IPC_EP_USRPIPE_ADDR);
}

View file

@ -0,0 +1,49 @@
/** \file
* \brief This file contains definitions and prototypes for messaging using inter-processor
* communication (IPC).
*/
#ifndef COMM_IPC_MESSAGES_H
#define COMM_IPC_MESSAGES_H
#ifdef __cplusplus
extern "C" {
#endif
/* Include Files */
/* Preprocessor and Type Definitions */
typedef enum
{
//! This is not an actual message. Upon receipt, do nothing.
COMM_SMM_DefaultNoMessage = 0,
//! Reboot the system immediately upon receipt of this message (Data is "don't care").
COMM_SMM_RebootImmediately,
//! This is not an actual message. Upon receipt, do nothing.
COMM_SMM_NoMessage = 0xFFFFFFFF,
} COMM_IPCMessageID_T;
typedef struct
{
//! The client ID number is the index into the callback array.
uint32_t ClientID;
//! The message ID represents the meaning of the message being sent.
COMM_IPCMessageID_T MessageID;
//! The contents of Data are different for each message ID. See #COMM_IPCMessageID_T for more details.
void * Data;
} COMM_IPCMessage_T;
/* Public Variables */
/* Public Functions */
void COMM_InitIPCMessages(void);
bool COMM_SendMessageToOtherCore(COMM_IPCMessageID_T message_ID, void * message_data);
#ifdef __cplusplus
}
#endif
#endif // COMM_IPC_MESSAGES_H

View file

@ -0,0 +1,48 @@
/** \file
* \brief This file implements utility functions used by the communications package.
*/
/**
* \ingroup CONSOLE
*/
/* Include Files */
#include "KTag.h"
/* Local Definitions and Constants */
/* Public Variables */
/* Private Variables */
static char8 uint64_buffer[20+1];
/* Private Function Prototypes */
/* Public Functions */
//! Converts a UInt64 to a NULL-terminated string.
/*!
* This function is necessary because newlib-nano does not support "%llu" / #PRIu64.
* \see https://answers.launchpad.net/gcc-arm-embedded/+question/257014
*
* \note This function is not reentrant!
*
* \param value pointer to the digital input object.
* \return pointer to a NULL-terminated string containing the base-10 textual representation of #value.
*/
char8 * COMM_UInt64ToDecimal(uint64_t value)
{
char8 * p = uint64_buffer + sizeof(uint64_buffer);
*(--p) = 0x00;
for (bool first_time = true; value || first_time; first_time = false)
{
const uint32_t digit = value % 10;
const char c = '0' + digit;
*(--p) = c;
value = value / 10;
}
return p;
}
/* Private Functions */

View file

@ -0,0 +1,27 @@
/** \file
* \brief Utility functions used by the communications package.
*
* \note As always, <project.h> and <RTOS.h> should be included <I>before</I> this file.
*/
#ifndef COMM_UTIL_H
#define COMM_UTIL_H
#ifdef __cplusplus
extern "C" {
#endif
/* Include Files */
/* Preprocessor and Type Definitions */
/* Public Variables */
/* Public Functions */
char8 * COMM_UInt64ToDecimal(uint64_t value);
#ifdef __cplusplus
}
#endif
#endif // COMM_UTIL_H

View file

@ -0,0 +1,78 @@
/** \file
* \brief This file defines the serial console commands for the Bluetooth Low Energy subsystem.
*/
/* Include Files */
#include "KTag.h"
#if (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED) && (CONFIG__FEATURE_BLE == CONFIG__FEATURE_ENABLED)
/* Local Definitions and Constants */
/* Private Function Prototypes */
/* Public Variables */
/* Private Variables */
/* Public Functions */
/* Private Functions */
//! Console command handler for subcommands of the 'ble' command.
COMM_Console_Command_Result_T COMM_HandleBLECommand(char8 * data, uint32_t size)
{
// data[0] through data[3] is 'ble '.
if (data[4] == '?')
{
COMM_Console_Print_String("ble ? Display this help.\n");
COMM_Console_Print_String("ble cmd <id> Inject the BLE command with ID <id>.\n");
}
else if ( (data[4] == 'c') &&
(data[5] == 'm') &&
(data[6] == 'd') )
{
if (COMM_Console_IsEndOfMessage(data[7]))
{
COMM_Console_Print_String("ERROR: missing BLE command ID!\n");
}
else if (data[7] == ' ')
{
uint16_t id = 0;
if (COMM_Console_DecodeParameterUInt16(&(data[8]), &id) == COMM_CONSOLE_PARAMETER_RESULT_SUCCESS)
{
if ((id > COMM_BLE_COMMAND_NO_OP) && (id < COMM_BLE_COMMAND_IS_OUT_OF_RANGE))
{
COMM_BLE_Command_T command = {.ID = id, .Data = (void *)0x00};
xQueueSend(COMM_BLE_CommandQueue, &command, 0);
}
else
{
COMM_Console_Print_String("ERROR: specified BLE command ID (");
COMM_Console_Print_UInt16(id);
COMM_Console_Print_String(") is invalid!\n");
}
}
else
{
COMM_Console_Print_String("ERROR: could not comprehend BLE command ID!\n");
}
}
else
{
COMM_Console_Print_String("ERROR: unrecognized or mangled command!\n");
}
}
else
{
COMM_Console_Print_String("ERROR: Unknown BLE command!\n");
}
return COMM_CONSOLE_CMD_RESULT_SUCCESS;
}
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED) && (CONFIG__FEATURE_BLE == CONFIG__FEATURE_ENABLED)

View file

@ -0,0 +1,29 @@
/** \file
* \brief This file declares the serial console commands for the Bluetooth Low Energy subsystem.
*/
#ifndef COMM_BLE_CONSOLECOMMANDS_H
#define COMM_BLE_CONSOLECOMMANDS_H
#ifdef __cplusplus
extern "C" {
#endif
#if (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
/* Include Files */
/* Preprocessor and Type Definitions */
/* Public Variables */
/* Public Functions */
COMM_Console_Command_Result_T COMM_HandleBLECommand(char8 * data, uint32_t size);
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
#ifdef __cplusplus
}
#endif
#endif // COMM_BLE_CONSOLECOMMANDS_H

View file

@ -0,0 +1,72 @@
/** \file
* \brief This file defines the serial console commands for this CPU.
*/
/* Include Files */
#include "KTag.h"
#if (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
/* Local Definitions and Constants */
/* Private Function Prototypes */
static COMM_Console_Command_Result_T HandleConsoleHelp(char8 * data, uint32_t size);
static COMM_Console_Command_Result_T HandleConsoleComment(char8 * data, uint32_t size);
static COMM_Console_Command_Result_T HandleConsoleUptime(char8 * data, uint32_t size);
/* Public Variables */
const COMM_Console_Command_Table_Entry_T COMM_Console_Command_Table[] =
{
{"?", " Show this help.", HandleConsoleHelp},
{"#", " Comment (Do not omit the space after the #.)", HandleConsoleComment},
{"event", " Generate an event in the high-level state machine (\'event ?\' for help).", COMM_HandleEventCommand},
{"ble", " Interact with the Bluetooth Low Energy subsystem (try \'ble ?\').", COMM_HandleBLECommand},
{"up", " Display uptime.", HandleConsoleUptime},
{"cpu (r)", " Display CPU usage ('r' to reset maximum).", COMM_RTOS_HandleConsoleCPU},
{"stack", " Display stack usage.", COMM_RTOS_HandleConsoleStack},
{"version", " Display RTOS version.", COMM_RTOS_HandleConsoleVersion},
{"reboot", " Performs a software reset on both cores.", COMM_RTOS_HandleConsoleReboot},
{"nvm", " Interact with the Nonvolatile Memory (try \'nvm ?\').", COMM_NVM_HandleConsoleNVMCommand},
};
//! Size of the #COMM_Console_Command_Table array (i.e. the number of console commands).
const uint_fast16_t COMM_N_CONSOLE_COMMANDS = (uint_fast16_t) (sizeof(COMM_Console_Command_Table) / sizeof(COMM_Console_Command_Table_Entry_T));
/* Private Variables */
/* Public Functions */
/* Private Functions */
static COMM_Console_Command_Result_T HandleConsoleHelp(char8 * data, uint32_t size)
{
for (uint_fast16_t i = 0; i < COMM_N_CONSOLE_COMMANDS; i++)
{
COMM_Console_Print_String(COMM_Console_Command_Table[i].Command_Name);
COMM_Console_Print_String(" ");
COMM_Console_Print_String(COMM_Console_Command_Table[i].Help);
COMM_Console_Print_String("\n");
vTaskDelay(pdMS_TO_TICKS(10));
}
return COMM_CONSOLE_CMD_RESULT_SUCCESS;
}
static COMM_Console_Command_Result_T HandleConsoleComment(char8 * data, uint32_t size)
{
COMM_Console_Print_String("Comment.\n");
return COMM_CONSOLE_CMD_RESULT_SUCCESS;
}
static COMM_Console_Command_Result_T HandleConsoleUptime(char8 * data, uint32_t size)
{
#if (configTICK_RATE_HZ != 1000)
#error This code assumes configTICK_RATE_HZ is set to 1000 (== 1ms ticks)!
#endif // (configTICK_RATE_HZ != 1000)
COMM_Console_Print_String("Up ");
COMM_Console_Print_UInt32(xTaskGetTickCount());
COMM_Console_Print_String(" milliseconds.\n");
return COMM_CONSOLE_CMD_RESULT_SUCCESS;
}
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)

View file

@ -0,0 +1,30 @@
/** \file
* \brief This file configures the serial console commands on this CPU.
*/
#ifndef COMM_CONSOLECOMMANDS_H
#define COMM_CONSOLECOMMANDS_H
#ifdef __cplusplus
extern "C" {
#endif
#if (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
/* Include Files */
/* Preprocessor and Type Definitions */
/* Public Variables */
extern const COMM_Console_Command_Table_Entry_T COMM_Console_Command_Table[];
extern const uint_fast16_t COMM_N_CONSOLE_COMMANDS;
/* Public Functions */
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
#ifdef __cplusplus
}
#endif
#endif // COMM_CONSOLECOMMANDS_H

View file

@ -0,0 +1,207 @@
/** \file
* \brief This file defines the serial console commands for the Nonvolatile Memory.
*/
/* Include Files */
#include "KTag.h"
#if (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
/* Local Definitions and Constants */
/* Private Function Prototypes */
/* Public Variables */
/* Private Variables */
/* Public Functions */
/* Private Functions */
//! Console command handler for subcommands of the 'nvm' command.
COMM_Console_Command_Result_T COMM_NVM_HandleConsoleNVMCommand(char8 * data, uint32_t size)
{
// data[0] through data[3] is 'nvm '.
if (data[4] == '?')
{
COMM_Console_Print_String("nvm ? Display this help.\n");
vTaskDelay(pdMS_TO_TICKS(10));
COMM_Console_Print_String("nvm dump Display the entire Nonvolatile Memory.\n");
vTaskDelay(pdMS_TO_TICKS(10));
COMM_Console_Print_String("nvm names Display the NVM parameter names.\n");
vTaskDelay(pdMS_TO_TICKS(10));
COMM_Console_Print_String("nvm get <parameter> Display an individual parameter from NVM.\n");
vTaskDelay(pdMS_TO_TICKS(10));
COMM_Console_Print_String("nvm set <parameter> <value> Assign a value to an individual parameter in NVM (be careful!).\n");
vTaskDelay(pdMS_TO_TICKS(10));
}
else if ((data[4] == 'd') && (data[5] == 'u') && (data[6] == 'm') && (data[7] == 'p'))
{
for (uint8_t i = 0; i < NVM_N_ONCHIP_EEPROM_ENTRIES; i++)
{
COMM_Console_Print_String("NVM[");
COMM_Console_Print_UInt16(i);
COMM_Console_Print_String("]: ");
for (uint8_t j = 0; j < NVM_OnChipEEPROMEntries[i]->Size; j++)
{
char8 buffer[3];
COMM_Console_ByteToHex(buffer, *(NVM_OnChipEEPROMEntries[i]->Value + j));
COMM_Console_Print_String("0x");
COMM_Console_Print_String(buffer);
COMM_Console_Print_String(" ");
}
COMM_Console_Print_String("\n");
}
}
else if ((data[4] == 'n') && (data[5] == 'a') && (data[6] == 'm') && (data[7] == 'e') && (data[8] == 's'))
{
COMM_Console_Print_String("Valid NVM parameters:\n");
vTaskDelay(pdMS_TO_TICKS(10));
COMM_Console_Print_String(" test_1\n");
vTaskDelay(pdMS_TO_TICKS(10));
COMM_Console_Print_String(" test_2\n");
vTaskDelay(pdMS_TO_TICKS(10));
COMM_Console_Print_String(" volume\n");
vTaskDelay(pdMS_TO_TICKS(10));
}
else if ((data[4] == 'g') && (data[5] == 'e') && (data[6] == 't') && (data[7] == ' '))
{
if (strncmp(&data[8], "volume", 6) == 0)
{
COMM_Console_Print_String("Volume: ");
COMM_Console_Print_UInt8(NVM_VOLUME);
COMM_Console_Print_String("\n");
}
else if (strncmp(&data[8], "test_1", 6) == 0)
{
COMM_Console_Print_String("Test 1: ");
COMM_Console_Print_UInt16(NVM_ONCHIP_TEST_1);
COMM_Console_Print_String("\n");
}
else if (strncmp(&data[8], "test_2", 6) == 0)
{
COMM_Console_Print_String("Test 2: ");
COMM_Console_Print_UInt32(NVM_ONCHIP_TEST_2);
COMM_Console_Print_String("\n");
}
else if (strncmp(&data[8], "test_3", 6) == 0)
{
COMM_Console_Print_String("Test 3: ");
COMM_Console_Print_UInt16(NVM_EXTERNAL_TEST_3);
COMM_Console_Print_String("\n");
}
else if (strncmp(&data[8], "test_4", 6) == 0)
{
COMM_Console_Print_String("Test 4: ");
COMM_Console_Print_UInt32(NVM_EXTERNAL_TEST_4);
COMM_Console_Print_String("\n");
}
else
{
COMM_Console_Print_String("ERROR: Unknown NVM parameter!\n");
}
}
else if ((data[4] == 's') && (data[5] == 'e') && (data[6] == 't') && (data[7] == ' '))
{
if (strncmp(&data[8], "volume", 6) == 0)
{
uint8_t volume = 0;
if (COMM_Console_DecodeParameterUInt8(&(data[15]), &volume) == COMM_CONSOLE_PARAMETER_RESULT_SUCCESS)
{
NVM_VOLUME = volume;
NVM_SaveExternalEEPROMEntry(NVM_VOLUME_ENTRY_PTR);
COMM_Console_Print_String("Volume changed to ");
COMM_Console_Print_UInt8(NVM_VOLUME);
COMM_Console_Print_String("\n");
}
else
{
COMM_Console_Print_String("ERROR: Parameter value unrecognized or missing!\n");
}
}
else if (strncmp(&data[8], "test_1", 6) == 0)
{
uint16_t test_value = 0;
if (COMM_Console_DecodeParameterUInt16(&(data[15]), &test_value) == COMM_CONSOLE_PARAMETER_RESULT_SUCCESS)
{
NVM_ONCHIP_TEST_1 = test_value;
NVM_SaveOnChipEEPROMEntry(NVM_ONCHIP_TEST_1_ENTRY_PTR);
COMM_Console_Print_String("Test 1 value changed to ");
COMM_Console_Print_UInt16(NVM_ONCHIP_TEST_1);
COMM_Console_Print_String("\n");
}
else
{
COMM_Console_Print_String("ERROR: Parameter value unrecognized or missing!\n");
}
}
else if (strncmp(&data[8], "test_2", 6) == 0)
{
uint32_t test_value = 0;
if (COMM_Console_DecodeParameterUInt32(&(data[15]), &test_value) == COMM_CONSOLE_PARAMETER_RESULT_SUCCESS)
{
NVM_ONCHIP_TEST_2 = test_value;
NVM_SaveOnChipEEPROMEntry(NVM_ONCHIP_TEST_2_ENTRY_PTR);
COMM_Console_Print_String("Test 2 value changed to ");
COMM_Console_Print_UInt32(NVM_ONCHIP_TEST_2);
COMM_Console_Print_String("\n");
}
else
{
COMM_Console_Print_String("ERROR: Parameter value unrecognized or missing!\n");
}
}
else if (strncmp(&data[8], "test_3", 6) == 0)
{
uint16_t test_value = 0;
if (COMM_Console_DecodeParameterUInt16(&(data[15]), &test_value) == COMM_CONSOLE_PARAMETER_RESULT_SUCCESS)
{
NVM_EXTERNAL_TEST_3 = test_value;
NVM_SaveExternalEEPROMEntry(NVM_EXTERNAL_TEST_3_ENTRY_PTR);
COMM_Console_Print_String("Test 3 value changed to ");
COMM_Console_Print_UInt16(NVM_EXTERNAL_TEST_3);
COMM_Console_Print_String("\n");
}
else
{
COMM_Console_Print_String("ERROR: Parameter value unrecognized or missing!\n");
}
}
else if (strncmp(&data[8], "test_4", 6) == 0)
{
uint32_t test_value = 0;
if (COMM_Console_DecodeParameterUInt32(&(data[15]), &test_value) == COMM_CONSOLE_PARAMETER_RESULT_SUCCESS)
{
NVM_EXTERNAL_TEST_4 = test_value;
NVM_SaveExternalEEPROMEntry(NVM_EXTERNAL_TEST_4_ENTRY_PTR);
COMM_Console_Print_String("Test 4 value changed to ");
COMM_Console_Print_UInt32(NVM_EXTERNAL_TEST_4);
COMM_Console_Print_String("\n");
}
else
{
COMM_Console_Print_String("ERROR: Parameter value unrecognized or missing!\n");
}
}
else
{
COMM_Console_Print_String("ERROR: Unknown NVM parameter!\n");
}
}
else
{
COMM_Console_Print_String("ERROR: Unknown NVM command!\n");
}
return COMM_CONSOLE_CMD_RESULT_SUCCESS;
}
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)

View file

@ -0,0 +1,29 @@
/** \file
* \brief This file declares the serial console commands for the Nonvolatile Memory.
*/
#ifndef COMM_NVM_CONSOLECOMMANDS_H
#define COMM_NVM_CONSOLECOMMANDS_H
#ifdef __cplusplus
extern "C" {
#endif
#if (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
/* Include Files */
/* Preprocessor and Type Definitions */
/* Public Variables */
/* Public Functions */
COMM_Console_Command_Result_T COMM_NVM_HandleConsoleNVMCommand(char8 * data, uint32_t size);
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
#ifdef __cplusplus
}
#endif
#endif // COMM_NVM_CONSOLECOMMANDS_H

View file

@ -0,0 +1,109 @@
/** \file
* \brief This file defines the serial console commands for the RTOS package.
*/
/* Include Files */
#include "KTag.h"
#if (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
/* Local Definitions and Constants */
/* Private Function Prototypes */
/* Public Variables */
/* Private Variables */
/* Public Functions */
/* Private Functions */
COMM_Console_Command_Result_T COMM_RTOS_HandleConsoleVersion(char8 * data, uint32_t size)
{
COMM_Console_Print_String("PSoC 6 running FreeRTOS ");
COMM_Console_Print_String(tskKERNEL_VERSION_NUMBER);
#ifdef NDEBUG
COMM_Console_Print_String(" (Release, compiled ");
#else
COMM_Console_Print_String(" (Debug, compiled ");
#endif // NDEBUG
COMM_Console_Print_String(__DATE__);
COMM_Console_Print_String(" ");
COMM_Console_Print_String(__TIME__);
COMM_Console_Print_String(").\n");
return COMM_CONSOLE_CMD_RESULT_SUCCESS;
}
COMM_Console_Command_Result_T COMM_RTOS_HandleConsoleStack(char8 * data, uint32_t size)
{
for (uint_fast8_t i = 0; i < CONFIG_N_TASK_HANDLES; i++)
{
TaskStatus_t status;
vTaskGetInfo(*CONFIG_TaskHandles[i], &status, pdTRUE, eInvalid);
COMM_Console_Print_String(status.pcTaskName);
COMM_Console_Print_String(": ");
COMM_Console_Print_UInt16(status.usStackHighWaterMark);
COMM_Console_Print_String("\n");
}
// Repeat for the Idle Task.
{
TaskStatus_t status;
vTaskGetInfo(xTaskGetIdleTaskHandle(), &status, pdTRUE, eInvalid);
COMM_Console_Print_String(status.pcTaskName);
COMM_Console_Print_String(": ");
COMM_Console_Print_UInt16(status.usStackHighWaterMark);
COMM_Console_Print_String("\n");
}
return COMM_CONSOLE_CMD_RESULT_SUCCESS;
}
COMM_Console_Command_Result_T COMM_RTOS_HandleConsoleCPU(char8 * data, uint32_t size)
{
// data[0] through data[3] is 'cpu '.
if (data[4] == 'r')
{
//COMM_Console_Print_String("Max CPU reset.\n");
COMM_Console_Print_String("(Not yet implemented.)\n");
}
else
{
for (uint_fast8_t i = 0; i < CONFIG_N_TASK_HANDLES; i++)
{
TaskStatus_t status;
vTaskGetInfo(*CONFIG_TaskHandles[i], &status, pdTRUE, eInvalid);
COMM_Console_Print_String(status.pcTaskName);
COMM_Console_Print_String(": ");
COMM_Console_Print_UInt32(status.ulRunTimeCounter);
COMM_Console_Print_String("\n");
}
// Repeat for the Idle Task.
{
TaskStatus_t status;
vTaskGetInfo(xTaskGetIdleTaskHandle(), &status, pdTRUE, eInvalid);
COMM_Console_Print_String(status.pcTaskName);
COMM_Console_Print_String(": ");
COMM_Console_Print_UInt16(status.ulRunTimeCounter);
COMM_Console_Print_String("\n");
}
}
return COMM_CONSOLE_CMD_RESULT_SUCCESS;
}
COMM_Console_Command_Result_T COMM_RTOS_HandleConsoleReboot(char8 * data, uint32_t size)
{
(void) COMM_SendMessageToOtherCore(COMM_SMM_RebootImmediately, NULL);
// Not that it matters...
return COMM_CONSOLE_CMD_RESULT_SUCCESS;
}
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)

View file

@ -0,0 +1,32 @@
/** \file
* \brief This file declares the serial console commands for the RTOS package.
*/
#ifndef COMM_RTOS_CONSOLECOMMANDS_H
#define COMM_RTOS_CONSOLECOMMANDS_H
#ifdef __cplusplus
extern "C" {
#endif
#if (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
/* Include Files */
/* Preprocessor and Type Definitions */
/* Public Variables */
/* Public Functions */
COMM_Console_Command_Result_T COMM_RTOS_HandleConsoleVersion(char8 * data, uint32_t size);
COMM_Console_Command_Result_T COMM_RTOS_HandleConsoleStack(char8 * data, uint32_t size);
COMM_Console_Command_Result_T COMM_RTOS_HandleConsoleCPU(char8 * data, uint32_t size);
COMM_Console_Command_Result_T COMM_RTOS_HandleConsoleReboot(char8 * data, uint32_t size);
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
#ifdef __cplusplus
}
#endif
#endif // COMM_RTOS_CONSOLECOMMANDS_H

View file

@ -0,0 +1,189 @@
/** \file
* \brief This file defines the serial console commands for the high-level state machine.
*/
/* Include Files */
#include "KTag.h"
#if (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
/* Local Definitions and Constants */
/* Private Function Prototypes */
static void Simulate_Hit(uint8_t team_ID, uint16_t damage);
/* Public Variables */
/* Private Variables */
/* Public Functions */
//! Console command handler for the 'event' command.
COMM_Console_Command_Result_T COMM_HandleEventCommand(char8 * data, uint32_t size)
{
// data[0] through data[5] is 'event '.
if (data[6] == '?')
{
COMM_Console_Print_String("event ? Display this help.\n");
vTaskDelay(pdMS_TO_TICKS(10));
COMM_Console_Print_String("event raw <id> Inject the event with ID <id>.\n");
vTaskDelay(pdMS_TO_TICKS(10));
COMM_Console_Print_String("event tag <n> Send <n> tag(s).\n");
vTaskDelay(pdMS_TO_TICKS(10));
COMM_Console_Print_String("event hit <t> <d> Simulate a hit from team <t> for <d> damage.\n");
vTaskDelay(pdMS_TO_TICKS(10));
}
else if ( (data[6] == 'r') &&
(data[7] == 'a') &&
(data[8] == 'w') )
{
if (COMM_Console_IsEndOfMessage(data[9]))
{
COMM_Console_Print_String("ERROR: missing event ID!\n");
}
else if (data[9] == ' ')
{
uint16_t id = 0;
if (COMM_Console_DecodeParameterUInt16(&(data[10]), &id) == COMM_CONSOLE_PARAMETER_RESULT_SUCCESS)
{
if ((id > KEVENT_NO_EVENT) && (id < KEVENT_IS_OUT_OF_RANGE))
{
KEvent_T raw_event = { .ID = id, .Data = (void *)0x00 };
Post_KEvent(&raw_event);
}
else
{
COMM_Console_Print_String("ERROR: specified event ID (");
COMM_Console_Print_UInt16(id);
COMM_Console_Print_String(") is invalid!\n");
}
}
else
{
COMM_Console_Print_String("ERROR: could not comprehend event ID!\n");
}
}
else
{
COMM_Console_Print_String("ERROR: unrecognized or mangled command!\n");
}
}
else if ( (data[6] == 't') &&
(data[7] == 'a') &&
(data[8] == 'g') )
{
if (COMM_Console_IsEndOfMessage(data[9]))
{
if (Send_Tag() == SYSTEMK_RESULT_SUCCESS)
{
COMM_Console_Print_String("Tag sent.\n");
}
else
{
COMM_Console_Print_String("Error: Couldn't send tag!\n");
}
}
else if (data[9] == ' ')
{
uint16_t times = 0;
if (COMM_Console_DecodeParameterUInt16(&(data[10]), &times) == COMM_CONSOLE_PARAMETER_RESULT_SUCCESS)
{
while (times > 0)
{
if (Send_Tag() == SYSTEMK_RESULT_SUCCESS)
{
COMM_Console_Print_String("Tag sent.\n");
}
else
{
COMM_Console_Print_String("Error: Couldn't send tag!\n");
}
//! \todo Why can't the console command 'event tag <n>' send tags faster than once per second?
vTaskDelay(1000 / portTICK_PERIOD_MS);
times--;
}
}
else
{
COMM_Console_Print_String("ERROR: could not comprehend tag repetitions!\n");
}
}
else
{
COMM_Console_Print_String("ERROR: unrecognized or mangled command!\n");
}
}
else if ( (data[6] == 'h') &&
(data[7] == 'i') &&
(data[8] == 't') )
{
if (COMM_Console_IsEndOfMessage(data[9]))
{
Simulate_Hit(1, 10);
COMM_Console_Print_String("Hit!\n");
}
else if (data[9] == ' ')
{
uint8_t team_ID = 0;
uint16_t damage = 10;
if (COMM_Console_DecodeParameterUInt8(&(data[10]), &team_ID) == COMM_CONSOLE_PARAMETER_RESULT_SUCCESS)
{
const char * damage_location;
// Damage is the first parameter after team ID.
if (COMM_Console_FindNthParameter(&(data[10]), 1, &damage_location) == COMM_CONSOLE_PARAMETER_RESULT_SUCCESS)
{
if (COMM_Console_DecodeParameterUInt16(damage_location, &damage) != COMM_CONSOLE_PARAMETER_RESULT_SUCCESS)
{
COMM_Console_Print_String("ERROR: could not comprehend damage--using default.\n");
damage = 10;
}
}
Simulate_Hit(team_ID, damage);
COMM_Console_Print_String("Hit!\n");
}
else
{
COMM_Console_Print_String("ERROR: could not comprehend team ID!\n");
}
}
else
{
COMM_Console_Print_String("ERROR: unrecognized or mangled command!\n");
}
}
else
{
COMM_Console_Print_String("ERROR: Unknown event command!\n");
}
return COMM_CONSOLE_CMD_RESULT_SUCCESS;
}
/* Private Functions */
static void Simulate_Hit(uint8_t team_ID, uint16_t damage)
{
static DecodedPacket_T Simulated_Tag_Rx_Buffer;
static KEvent_T tag_received_event;
Simulated_Tag_Rx_Buffer.Tag.type = DECODED_PACKET_TYPE_TAG_RECEIVED;
Simulated_Tag_Rx_Buffer.Tag.protocol = LASER_X_PROTOCOL;
Simulated_Tag_Rx_Buffer.Tag.player_ID = 0x00;
Simulated_Tag_Rx_Buffer.Tag.team_ID = team_ID;
Simulated_Tag_Rx_Buffer.Tag.damage = damage;
Simulated_Tag_Rx_Buffer.Tag.color = GetColorFromTeamID(team_ID);
tag_received_event.ID = KEVENT_TAG_RECEIVED;
tag_received_event.Data = &Simulated_Tag_Rx_Buffer;
Post_KEvent(&tag_received_event);
}
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)

View file

@ -0,0 +1,29 @@
/** \file
* \brief This file declares the serial console commands for the high-level state machine.
*/
#ifndef COMM_STATE_CONSOLECOMMANDS_H
#define COMM_STATE_CONSOLECOMMANDS_H
#ifdef __cplusplus
extern "C" {
#endif
#if (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
/* Include Files */
/* Preprocessor and Type Definitions */
/* Public Variables */
/* Public Functions */
COMM_Console_Command_Result_T COMM_HandleEventCommand(char8 * data, uint32_t size);
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
#ifdef __cplusplus
}
#endif
#endif // COMM_STATE_CONSOLECOMMANDS_H

View file

@ -0,0 +1,84 @@
/** \dir "CONFIG"
*
* \brief This directory contains configuration files for this software.
*
*/
/** \file
* \brief This file includes project-wide for this software.
*
* This file should be included by every file outside the CONFIG package!
*
* \note As always, <project.h> should be included <I>before</I> this file.
*/
#ifndef CONFIG_H
#define CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
#include "CONFIG_RTOS.h"
//! Value of audio volume represeting the maximum volume possible for this device.
#define CONFIG_KTAG_MAX_AUDIO_VOLUME 30
//! Value of audio volume represeting the minimum volume possible for this device.
#define CONFIG_KTAG_MIN_AUDIO_VOLUME 5
//! Time (in milliseconds) after starting a game before the countdown begins.
//#define CONFIG_KTAG_T_DEFAULT_START_GAME_in_ms (30 * 1000)
#define CONFIG_KTAG_T_DEFAULT_START_GAME_in_ms (3 * 1000)
//! true if the hardware includes internal (on-chip) NVM.
#define CONFIG__HAS_INTERNAL_NVM true
//! true if the hardware includes an external (I2C) NVM chip.
#define CONFIG__HAS_EXTERNAL_NVM true
// '||' || '|| '||''|. TM
// || ... || || || ... .. ... ... .... ...
// || || || ||'''|. ||' '' || || '|. |
// || || || || || || || || '|.|
// .||.....| .||. .||. .||...|' .||. '|..'|. '|
#if (defined LIL_BRUV) || (defined LITTLE_BOY_BLUE)
//! Number of NeoPixel channels supported.
#define CONFIG_KTAG_N_NEOPIXEL_CHANNELS 1
//! Maximum number of NeoPixels on a single channel.
#define CONFIG_KTAG_MAX_NEOPIXELS_PER_CHANNEL 5
// /\ /\\ /\ /\\ TM
// ( ) || || ( ) || || |''||''| '||''|. ..|'''.|
// // || || // || || || || || .|' '
// // || || // || || || ||...|' ||
// /( || || /( || || || || '|. .
// {___ \\/ {___ \\/ .||. .||. ''|....'
#elif (defined TWENTY20TPC)
//! Number of NeoPixel channels supported.
#define CONFIG_KTAG_N_NEOPIXEL_CHANNELS 4
//! Maximum number of NeoPixels on a single channel.
#define CONFIG_KTAG_MAX_NEOPIXELS_PER_CHANNEL 8
#else
#error "No recognized KTag models defined. Supported models are: LIL_BRUV, LITTLE_BOY_BLUE, and TWENTY20TPC."
#endif
//! Time between NeoPixel animation frames, in milliseconds.
#define CONFIG_KTAG_ANIMATION_STEP_TIME_IN_ms 10
#ifdef __cplusplus
}
#endif
#endif // CONFIG_H

View file

@ -0,0 +1,113 @@
/** \file
* \brief This file defines and registers the tasks used by the Real-Time Operating System.
*
* See CONFIG_RTOS.h for a detailed description of the functionality implemented by this code.
*/
/* Include Files */
#include "KTag.h"
/* Local Definitions and Constants */
/*---------------------------------------------------------------------------*/
/* Task priorities: Low priority numbers denote low priority tasks.
*
* Low == 0 == tskIDLE_PRIORITY
* ...
* High == (configMAX_PRIORITIES - 1)
*
* See http://www.freertos.org/RTOS-task-priority.html for more information.
*/
#define CAPSENSE_TASK_PRIORITY (tskIDLE_PRIORITY + 3)
#define SAMPLE_TASK_PRIORITY (tskIDLE_PRIORITY + 2)
#define FIRE_CONTROL_TASK_PRIORITY (tskIDLE_PRIORITY + 1)
#define AUDIO_TASK_PRIORITY (tskIDLE_PRIORITY + 2)
#define NEOPIXELS_TASK_PRIORITY (tskIDLE_PRIORITY + 2)
#define TAG_SENSORS_TASK_PRIORITY (tskIDLE_PRIORITY + 5)
#define SWITCHES_TASK_PRIORITY (tskIDLE_PRIORITY + 2)
#define NVM_EXTERNAL_TASK_PRIORITY (tskIDLE_PRIORITY + 2)
#define NVM_ON_CHIP_EEPROM_TASK_PRIORITY (tskIDLE_PRIORITY + 1)
#define COMM_CONSOLE_TASK_PRIORITY (tskIDLE_PRIORITY + 2)
#define COMM_BLE_TASK_PRIORITY (tskIDLE_PRIORITY + 4)
/* External Variables [Only if necessary!] */
/* External Function Prototypes [Only if necessary!] */
/* Public Variables */
//! Array of all the handles for the configured RTOS tasks.
TaskHandle_t * const CONFIG_TaskHandles[] = {&HW_CapSense_Task_Handle,
&Fire_Control_Task_Handle,
&Sample_Task_Handle,
&Audio_Task_Handle,
&NeoPixels_Task_Handle,
&Tag_Sensors_Task_Handle,
&Switches_Task_Handle,
&State_Machine_Task_Handle,
&NVM_ExternalEEPROM_Task_Handle,
&NVM_OnChipEEPROM_Task_Handle,
&COMM_Console_Task_Handle,
&COMM_BLE_Task_Handle};
//! Size of the #CONFIG_TaskHandles array (i.e. the number of configured tasks).
const uint8_t CONFIG_N_TASK_HANDLES = (uint8_t) (sizeof(CONFIG_TaskHandles) / sizeof(TaskHandle_t *));
/* Private Variables */
/* Private Function Prototypes */
/* Public Functions */
void CONFIG_InitTasks(void)
{
HW_CapSense_Init();
COMM_I2C_Init();
NVM_InitExternalEEPROM();
NVM_InitOnChipEEPROM();
Sample_Task_Init();
Init_Fire_Control();
Tag_Sensors_Init();
Init_Audio();
Switches_Init();
COMM_Console_Init();
COMM_BLE_Init();
}
//! Registers tasks with the kernel, and then runs them.
/*!
* This function should not return.
*/
void CONFIG_RunTasks(void)
{
(void) xTaskCreate(HW_CapSense_Task, "CapSense Task", HW_CAPSENSE_TASK_STACK_SIZE_in_bytes, NULL, CAPSENSE_TASK_PRIORITY, &HW_CapSense_Task_Handle);
(void) xTaskCreate(Fire_Control_Task, "Fire Control Task", configMINIMAL_STACK_SIZE, NULL, FIRE_CONTROL_TASK_PRIORITY, &Fire_Control_Task_Handle);
(void) xTaskCreate(Sample_Task, "Sample Task", configMINIMAL_STACK_SIZE, NULL, SAMPLE_TASK_PRIORITY, &Sample_Task_Handle);
(void) xTaskCreate(Audio_Task, "Audio Task", configMINIMAL_STACK_SIZE, NULL, AUDIO_TASK_PRIORITY, &Audio_Task_Handle);
(void) xTaskCreate(NeoPixels_Task, "NeoPixels Task", configMINIMAL_STACK_SIZE, NULL, NEOPIXELS_TASK_PRIORITY, &NeoPixels_Task_Handle);
(void) xTaskCreate(Tag_Sensors_Task, "Tag Sensors Task", configMINIMAL_STACK_SIZE, NULL, TAG_SENSORS_TASK_PRIORITY, &Tag_Sensors_Task_Handle);
(void) xTaskCreate(Switches_Task, "Switches Task", configMINIMAL_STACK_SIZE, NULL, SWITCHES_TASK_PRIORITY, &Switches_Task_Handle);
(void) xTaskCreate(NVM_OnChipEEPROMTask, "NVMOn", NVM_ON_CHIP_EEPROM_TASK_STACK_SIZE_in_bytes, NULL, NVM_ON_CHIP_EEPROM_TASK_PRIORITY, &NVM_OnChipEEPROM_Task_Handle);
(void) xTaskCreate(NVM_ExternalEEPROMTask, "NVMEx", NVM_EXTERNAL_EEPROM_TASK_STACK_SIZE_in_bytes, NULL, NVM_EXTERNAL_TASK_PRIORITY, &NVM_ExternalEEPROM_Task_Handle);
(void) xTaskCreate(COMM_Console_Task, "Console Task", COMM_CONSOLE_TASK_STACK_SIZE_in_bytes, NULL, COMM_CONSOLE_TASK_PRIORITY, &COMM_Console_Task_Handle);
(void) xTaskCreate(COMM_BLE_Task, "BLE Task", COMM_BLE_TASK_STACK_SIZE_in_bytes, NULL, COMM_BLE_TASK_PRIORITY, &COMM_BLE_Task_Handle);
if (Initialize_SystemK() != SYSTEMK_RESULT_SUCCESS)
{
KLOG_ERROR("CONFIG", "Failed to initilaize SystemK!");
}
/* This should not return. */
vTaskStartScheduler();
// Something went wrong.
#ifdef DEBUG
// Break into the debugger.
__BKPT(0);
#else // DEBUG
__NVIC_SystemReset();
#endif // DEBUG
}
/* Private Functions */

View file

@ -0,0 +1,29 @@
/** \file
* \brief This file configures the Real-Time Operating System (RTOS).
*/
#ifndef CONFIG_RTOS_H
#define CONFIG_RTOS_H
#ifdef __cplusplus
extern "C" {
#endif
/* Include Files */
/* Preprocessor and Type Definitions */
/* Public Variables */
extern TaskHandle_t * const CONFIG_TaskHandles[];
extern const uint8_t CONFIG_N_TASK_HANDLES;
/* Public Functions */
void CONFIG_InitTasks(void);
void CONFIG_RunTasks(void);
#ifdef __cplusplus
}
#endif
#endif // CONFIG_RTOS_H

View file

@ -0,0 +1,223 @@
/* Include Files */
#include "KTag.h"
#define FIRE_CONTROL_REGISTER__IR_OFF 0b00000
#define FIRE_CONTROL_REGISTER__IR_ON_MODULATED_LOW_POWER 0b00011
#define FIRE_CONTROL_REGISTER__IR_ON_MODULATED_HIGH_POWER 0b00101
#define FIRE_CONTROL_REGISTER__IR_ON_MODULATED_MAX_POWER 0b11111
#define FIRE_CONTROL_REGISTER__IR_ON_UNMODULATED_LOW_POWER 0b00010
#define FIRE_CONTROL_REGISTER__IR_ON_UNMODULATED_HIGH_POWER 0b00100
#define FIRE_CONTROL_REGISTER__IR_ON_UNMODULATED_MAX_POWER 0b00110
#define TRIGGER_STATUS_REGISTER__NO_ACTION 0x00
#define TRIGGER_STATUS_REGISTER__TRIGGER_PULLED 0x01
#define TRIGGER_STATUS_REGISTER__TRIGGER_RELEASED 0x02
void Trigger_Interrupt_ISR();
void Bit_Stream_Timer_ISR();
TimedPulseTrain_T * Shot_Buffer;
TagPacket_T Shot_Packet;
TaskHandle_t Fire_Control_Task_Handle;
static TimedPulseTrain_T * Active_Pulse_Train = NULL;
static uint8_t Active_Bitstream_Index = 0;
static TickType_t TicksAtTriggerPress;
static inline void Initiate_Pulse_Train(TimedPulseTrain_T * pulsetrain)
{
Bit_Stream_Timer_Disable();
Active_Pulse_Train = pulsetrain;
Active_Bitstream_Index = 0;
if (Active_Pulse_Train->bitstream[Active_Bitstream_Index].symbol == MARK)
{
Fire_Control_Register_Write(FIRE_CONTROL_REGISTER__IR_ON_MODULATED_MAX_POWER);
}
else
{
Fire_Control_Register_Write(FIRE_CONTROL_REGISTER__IR_OFF);
}
Bit_Stream_Timer_SetPeriod(Active_Pulse_Train->bitstream[0].duration);
Bit_Stream_Timer_SetCounter(0);
Active_Bitstream_Index++;
Bit_Stream_Timer_Enable();
Bit_Stream_Timer_TriggerStart();
}
static inline void Next_Bit(void)
{
static BaseType_t xHigherPriorityTaskWoken = pdFALSE;
Bit_Stream_Timer_Disable();
if (Active_Pulse_Train->bitstream[Active_Bitstream_Index].duration != LAST_PULSE)
{
if (Active_Pulse_Train->bitstream[Active_Bitstream_Index].symbol == MARK)
{
Fire_Control_Register_Write(FIRE_CONTROL_REGISTER__IR_ON_MODULATED_MAX_POWER);
}
else
{
Fire_Control_Register_Write(FIRE_CONTROL_REGISTER__IR_OFF);
}
if (Active_Bitstream_Index < ((2*MAX_PULSES) - 2))
{
Bit_Stream_Timer_SetPeriod(Active_Pulse_Train->bitstream[Active_Bitstream_Index].duration);
Bit_Stream_Timer_SetCounter(0);
Active_Bitstream_Index++;
Bit_Stream_Timer_Enable();
Bit_Stream_Timer_TriggerStart();
}
else
{
// The bitstream is too long!
// Turn the IR Emitter off, and wait a long time.
Fire_Control_Register_Write(FIRE_CONTROL_REGISTER__IR_OFF);
xSemaphoreGiveFromISR(NeoPixels_Semaphore, &xHigherPriorityTaskWoken);
Bit_Stream_Timer_SetPeriod(UINT16_MAX);
Bit_Stream_Timer_SetCounter(0);
Active_Pulse_Train = NULL;
Bit_Stream_Timer_Enable();
Bit_Stream_Timer_TriggerStart();
}
}
else
{
// Turn the IR Emitter off, and wait a long time.
Fire_Control_Register_Write(FIRE_CONTROL_REGISTER__IR_OFF);
xSemaphoreGiveFromISR(NeoPixels_Semaphore, &xHigherPriorityTaskWoken);
Bit_Stream_Timer_SetPeriod(UINT16_MAX);
Bit_Stream_Timer_SetCounter(0);
Active_Pulse_Train = NULL;
Bit_Stream_Timer_Enable();
Bit_Stream_Timer_TriggerStart();
}
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void Init_Fire_Control(void)
{
// Register and enable the ISRs.
Cy_SysInt_Init(&Trigger_Interrupt_cfg, Trigger_Interrupt_ISR);
Cy_SysInt_Init(&Bit_Stream_Timer_Interrupt_cfg, Bit_Stream_Timer_ISR);
NVIC_EnableIRQ(Trigger_Interrupt_cfg.intrSrc);
NVIC_EnableIRQ(Bit_Stream_Timer_Interrupt_cfg.intrSrc);
// Initialize the hardware.
Bit_Stream_Timer_Clock_Enable();
Bit_Stream_Timer_Init(&Bit_Stream_Timer_config);
Bit_Stream_Timer_SetPeriod(2);
Bit_Stream_Timer_Start();
SW_CLK_Enable();
PWM_IR_Modulation_Start();
Fire_Control_Register_Write(FIRE_CONTROL_REGISTER__IR_OFF);
}
void Fire_Control_Task(void * pvParameters)
{
while (true)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
SystemKResult_T Prepare_Tag()
{
Shot_Packet.player_ID = NVM_PLAYER_ID;
Shot_Packet.team_ID = NVM_TEAM_ID;
Weapon_t weapon = GetWeaponFromID(NVM_WEAPON_ID);
Shot_Packet.color = (uint32_t)PROTOCOLS_GetColor(weapon.Protocol, Shot_Packet.team_ID, Shot_Packet.player_ID);
Shot_Packet.protocol = weapon.Protocol;
Shot_Packet.damage = weapon.Damage_Per_Shot;
Shot_Buffer = PROTOCOLS_EncodePacket(&Shot_Packet);
Fire_Control_Set_Modulation_Frequency(PROTOCOLS_GetModulationFrequency(weapon.Protocol));
return SYSTEMK_RESULT_SUCCESS;
}
SystemKResult_T Send_Tag()
{
xSemaphoreTake(NeoPixels_Semaphore, portMAX_DELAY);
Initiate_Pulse_Train(Shot_Buffer);
KEvent_T tag_sent_event = { .ID = KEVENT_TAG_SENT, .Data = (void *)0x00 };
Post_KEvent(&tag_sent_event);
return SYSTEMK_RESULT_SUCCESS;
}
void Fire_Control_Set_Modulation_Frequency(ModulationFrequency_T freq)
{
PWM_IR_Modulation_TriggerKill();
if (freq == FREQUENCY_38kHz)
{
PWM_IR_Modulation_SetPeriod0(314);
//PWM_IR_Modulation_SetCompare0(314/2); // 50% Duty Cycle
PWM_IR_Modulation_SetCompare0((314 * 3)/10); // 30% Duty Cycle
}
else // (freq == FREQUENCY_56kHz)
{
PWM_IR_Modulation_SetPeriod0(213);
//PWM_IR_Modulation_SetCompare0(213/2); // 50% Duty Cycle
PWM_IR_Modulation_SetCompare0((213 * 3)/10); // 30% Duty Cycle
}
PWM_IR_Modulation_TriggerStart();
}
//! ISR for the trigger input.
void Trigger_Interrupt_ISR()
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
// Clear the interrupt.
NVIC_ClearPendingIRQ(Trigger_Interrupt_cfg.intrSrc);
// Read the trigger register to know if this was a pull or a release.
uint8_t trigger_status = Trigger_Status_Reg_Read();
if ((trigger_status & TRIGGER_STATUS_REGISTER__TRIGGER_PULLED) == TRIGGER_STATUS_REGISTER__TRIGGER_PULLED)
{
TicksAtTriggerPress = xTaskGetTickCountFromISR();
KEvent_T switch_event = {.ID = KEVENT_CENTER_SWITCH_PRESSED, .Data = NULL};
Post_KEvent_From_ISR(&switch_event, &xHigherPriorityTaskWoken);
}
else if ((trigger_status & TRIGGER_STATUS_REGISTER__TRIGGER_RELEASED) == TRIGGER_STATUS_REGISTER__TRIGGER_RELEASED)
{
uint32_t triggerPressDurationInms = pdTICKS_TO_MS(xTaskGetTickCountFromISR() - TicksAtTriggerPress);
KEvent_T switch_event = {.ID = KEVENT_CENTER_SWITCH_RELEASED, .Data = (void *) triggerPressDurationInms};
Post_KEvent_From_ISR(&switch_event, &xHigherPriorityTaskWoken);
}
else
{
// What happened!!?
}
// If an event was enqueued above, a context switch might be required.
// xHigherPriorityTaskWoken was initialized to pdFALSE on interrupt entry. If calling
// xSemaphoreGiveFromISR() caused a task to unblock, and the unblocked task has a
// priority equal to or higher than the currently running task (the task that was
// interrupted by this ISR), then xHigherPriorityTaskWoken will have been set to pdTRUE
// and portEND_SWITCHING_ISR() will request a context switch to the newly unblocked task.
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
void Bit_Stream_Timer_ISR()
{
// Get all the enabled pending interrupts...
uint32_t source = Bit_Stream_Timer_GetInterruptStatusMasked();
// ...and clear them.
Bit_Stream_Timer_ClearInterrupt(source);
if (Active_Pulse_Train != NULL)
{
Next_Bit();
}
}

View file

@ -0,0 +1,13 @@
#ifndef FIRE_CONTROL_H
#define FIRE_CONTROL_H
#include <stdbool.h>
#include <stdint.h>
extern TaskHandle_t Fire_Control_Task_Handle;
void Init_Fire_Control(void);
void Fire_Control_Task(void * pvParameters);
void Fire_Control_Set_Modulation_Frequency(ModulationFrequency_T freq);
#endif // FIRE_CONTROL_H

View file

@ -0,0 +1,228 @@
/*
* FreeRTOS Kernel V10.0.1
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
#include "syslib/cy_syslib.h"
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_TICKLESS_IDLE 0
#define configCPU_CLOCK_HZ SystemCoreClock
#define configTICK_RATE_HZ 1000u
#define configMAX_PRIORITIES 15
#define configMINIMAL_STACK_SIZE 512
#define configMAX_TASK_NAME_LEN 16
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configQUEUE_REGISTRY_SIZE 10
#define configUSE_QUEUE_SETS 0
#define configUSE_TIME_SLICING 0
#define configUSE_NEWLIB_REENTRANT 0
#define configENABLE_BACKWARD_COMPATIBILITY 0
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
/* Memory allocation related definitions. */
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTOTAL_HEAP_SIZE (64*1024)
#define configAPPLICATION_ALLOCATED_HEAP 0
/* Hook function related definitions. */
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 0
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
/* Run time and task stats gathering related definitions. */
#define configGENERATE_RUN_TIME_STATS 1
#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
//! Debug Exception and Monitor Control register
#define CORE_DBG_EXC_MON_CTL (*(uint32_t *)0xE000EDFC)
//! DWT Control Register
#define DWT_CTRL (*(uint32_t *)0xE0001000)
//! DWT Current PC Sampler Cycle Count Register
/*!
* Use the DWT Current PC Sampler Cycle Count Register to count the number of core cycles. This
* count can measure elapsed execution time.
*/
#define DWT_CYCCNT (*(uint32_t *)0xE0001004)
//! Initializes the Data Watchpoint and Trace Unit and starts the CYCCNT counter.
static inline void vCONFIGURE_TIMER_FOR_RUN_TIME_STATS(void)
{
// If the Data Watchpoint and Trace Unit is present, #DWT_CTRL will be non-zero.
if (DWT_CTRL != 0)
{
// Set bit 24 (TRCENA) on the CORE_DBG_EXC_MON_CTL register to enable use of the DWT.
CORE_DBG_EXC_MON_CTL |= (1 << 24);
// Initialize the count register.
DWT_CYCCNT = 0;
// Set bit 0 (CYCCNTENA) on the DWT_CTRL register to enable the CYCCNT counter.
DWT_CTRL |= (1 << 0);
}
}
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS vCONFIGURE_TIMER_FOR_RUN_TIME_STATS
//! Returns the current value of the DWT Current PC Sampler Cycle Count Register
/*!
* Use the DWT Current PC Sampler Cycle Count Register to count the number of core cycles. This
* count can measure elapsed execution time.
*/
static inline uint32_t ulGET_RUN_TIME_COUNTER_VALUE(void)
{
return DWT_CYCCNT;
}
#define portGET_RUN_TIME_COUNTER_VALUE ulGET_RUN_TIME_COUNTER_VALUE
/* Co-routine related definitions. */
#define configUSE_CO_ROUTINES 1
#define configMAX_CO_ROUTINE_PRIORITIES 2
/* Software timer related definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY 3
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
/* FreeRTOS MPU specific definitions. */
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
/*
Interrupt nesting behavior configuration.
This is explained here: http://www.freertos.org/a00110.html
Priorities are controlled by two macros:
- configKERNEL_INTERRUPT_PRIORITY determines the priority of the RTOS daemon task
- configMAX_API_CALL_INTERRUPT_PRIORITY dictates the priority of ISRs that make API calls
Notes:
1. Interrupts that do not call API functions should be >= configKERNEL_INTERRUPT_PRIORITY
and will nest.
2. Interrupts that call API functions must have priority between KERNEL_INTERRUPT_PRIORITY
and MAX_API_CALL_INTERRUPT_PRIORITY (inclusive).
3. Interrupts running above MAX_API_CALL_INTERRUPT_PRIORITY are never delayed by the OS.
*/
/*
PSoC 6 __NVIC_PRIO_BITS = 3
0 (high)
1 MAX_API_CALL_INTERRUPT_PRIORITY 001xxxxx (0x3F)
2
3
4
5
6
7 (low) KERNEL_INTERRUPT_PRIORITY 111xxxxx (0xFF)
!!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html
If you call a FreeRTOS API function from an interrupt with priority higher than
MAX_API_CALL_INTERRUPT_PRIORITY FreeRTOS will generate an exception. If you need
to call a FreeRTOS API function from your systems highest priority interrupt
you must reduce all interrupt priorities to MAX_API_CALL_INTERRUPT_PRIORITY or
lower.
If your system pipe (IPC) interrupt priority is less than or equal to
MAX_API_CALL_INTERRUPT_PRIORITY then care must be taken with code that writes to
flash (including the Flash/BLE/Emulated EEPROM/Bootloader drivers from Cypress
PDL). The duration of critical sections must be kept short - see the
Configuration Considerations section of the flash driver in the PDL API
Reference.
*/
/* Put KERNEL_INTERRUPT_PRIORITY in top __NVIC_PRIO_BITS bits of CM4 register */
#define configKERNEL_INTERRUPT_PRIORITY 0xFF
/*
Put MAX_SYSCALL_INTERRUPT_PRIORITY in top __NVIC_PRIO_BITS bits of CM4 register
NOTE For IAR compiler make sure that changes of this macro is reflected in
file portable\IAR\CM4F\portasm.s in PendSV_Handler: routine
*/
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 0x3F
/* configMAX_API_CALL_INTERRUPT_PRIORITY is a new name for configMAX_SYSCALL_INTERRUPT_PRIORITY
that is used by newer ports only. The two are equivalent. */
#define configMAX_API_CALL_INTERRUPT_PRIORITY configMAX_SYSCALL_INTERRUPT_PRIORITY
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_xResumeFromISR 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xEventGroupSetBitFromISR 1
#define INCLUDE_xTimerPendFunctionCall 0
#define INCLUDE_xTaskAbortDelay 0
#define INCLUDE_xTaskGetHandle 0
#define INCLUDE_xTaskResumeFromISR 1
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names - or at least those used in the unmodified vector table. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
#endif /* FREERTOS_CONFIG_H */

View file

@ -0,0 +1,50 @@
/** \dir "HW"
*
* \brief This directory contains source code interfacing to the lowest level of the hardware on this CPU.
*
*/
/** \file
* \brief This file defines the interface to the low-level hardware used by this software.
*
* This file should be included by any file outside the HW package wishing to make use
* of any of the HW functionality.
*
* \note As always, <project.h> and <CONFIG.h> should be included <I>before</I> this file.
*/
#ifndef HW_H
#define HW_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
//! Represents the states of a Digital Input or Digital Output.
typedef enum
{
//! Represents low voltage (logic '0') on a digital input or output.
HW_DIGITAL_STATE_LOW = 0,
//! Represents high voltage (logic '1') on a digital input or output.
HW_DIGITAL_STATE_HIGH = 1,
//! Used when the state of a digital input or output cannot be determined.
HW_DIGITAL_STATE_UNKNOWN = 2
} HW_DigitalState_T;
/* Include Files */
#include "HW_CapSense.h"
/* Public Variables */
/* Public Functions */
#ifdef __cplusplus
}
#endif
#endif // HW_H

View file

@ -0,0 +1,125 @@
/* Include Files */
#include "KTag.h"
/* Local Definitions and Constants */
#define CAPSENSE_TASK_PERIOD_IN_ms 50
/* Public Variables */
TaskHandle_t HW_CapSense_Task_Handle;
/* Private Variables */
static const TickType_t CapSense_Task_Delay = CAPSENSE_TASK_PERIOD_IN_ms / portTICK_PERIOD_MS;
static bool CapSense_One_Pressed = false;
static bool CapSense_Two_Pressed = false;
/* Private Function Prototypes */
/* Public Functions */
//! Initializes the capacitive touch sensing.
void HW_CapSense_Init(void)
{
}
//! Capacitive touch sensing task: Manages the capsense, using the PSoC API functions.
/*!
*
*/
void HW_CapSense_Task(void * pvParameters)
{
TickType_t xLastWakeTime;
// Initialize the xLastWakeTime variable with the current time.
xLastWakeTime = xTaskGetTickCount();
// Start up the capsense component, and initiate the first scan.
// Note that this can't be done in HW_CapSense_Init(), since it requires interrupts to be enabled.
CapSense_Start();
CapSense_ScanAllWidgets();
vTaskDelayUntil(&xLastWakeTime, CapSense_Task_Delay);
while (true)
{
// Check to see if the CapSense hardware is still busy with a previous scan.
if (CapSense_IsBusy() == CapSense_NOT_BUSY)
{
// Process all the widgets and read the touch information.
CapSense_ProcessAllWidgets();
// Perform the on-change logic for "Button One".
if (CapSense_IsSensorActive(CapSense_BUTTON0_WDGT_ID, CapSense_BUTTON0_SNS0_ID))
{
if (CapSense_One_Pressed == false)
{
KEvent_T switch_event = {.ID = KEVENT_CAPSENSE_ONE_PRESSED, .Data = NULL};
Post_KEvent(&switch_event);
}
CapSense_One_Pressed = true;
}
else
{
if (CapSense_One_Pressed == true)
{
KEvent_T switch_event = {.ID = KEVENT_CAPSENSE_ONE_RELEASED, .Data = NULL};
Post_KEvent(&switch_event);
}
CapSense_One_Pressed = false;
}
// Perform the on-change logic for "Button Two".
if (CapSense_IsSensorActive(CapSense_BUTTON0_WDGT_ID, CapSense_BUTTON0_SNS1_ID))
{
if (CapSense_Two_Pressed == false)
{
KEvent_T switch_event = {.ID = KEVENT_CAPSENSE_TWO_PRESSED, .Data = NULL};
Post_KEvent(&switch_event);
}
CapSense_Two_Pressed = true;
}
else
{
if (CapSense_Two_Pressed == true)
{
KEvent_T switch_event = {.ID = KEVENT_CAPSENSE_TWO_RELEASED, .Data = NULL};
Post_KEvent(&switch_event);
}
CapSense_Two_Pressed = false;
}
// Initiate the next scan.
CapSense_ScanAllWidgets();
}
vTaskDelayUntil(&xLastWakeTime, CapSense_Task_Delay);
}
}
//! Gets the state of the given CapSense button.
/*!
* \param button the button in question
* \return true if the button was pressed last time it was checked; false otherwise
*/
bool HW_IsCapsenseButtonPressed(HW_CapSenseButton_T button)
{
bool pressed = false;
if ((button == HW_CAPSENSE_BUTTON_ONE) && (CapSense_One_Pressed == true))
{
pressed = true;
}
else if ((button == HW_CAPSENSE_BUTTON_TWO) && (CapSense_Two_Pressed == true))
{
pressed = true;
}
return pressed;
}
/* Private Functions */

View file

@ -0,0 +1,40 @@
/** \file
* \brief This file defines the interface to the capacitive touch sensing used by this software.
*
*/
#ifndef HW_CAPSENSE_H
#define HW_CAPSENSE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
#define HW_CAPSENSE_TASK_STACK_SIZE_in_bytes 128
typedef enum
{
HW_CAPSENSE_BUTTON_ONE,
HW_CAPSENSE_BUTTON_TWO
} HW_CapSenseButton_T;
/* Include Files */
/* Public Variables */
//! Handle of the HW_CapSense_Task() given when the task was created.
extern TaskHandle_t HW_CapSense_Task_Handle;
/* Public Functions */
void HW_CapSense_Init(void);
void HW_CapSense_Task(void * pvParameters);
bool HW_IsCapsenseButtonPressed(HW_CapSenseButton_T button);
#ifdef __cplusplus
}
#endif
#endif // HW_CAPSENSE_H

View file

@ -0,0 +1,392 @@
// NeoPixel Driver using Direct Memory Access
//
// This implementation is based on the one by Alan Hawse of Elkhorn Creek,
// documented at https://iotexpert.com/2019/01/08/psoc-6-dma-ws2812-leds/.
// We are grateful to Mr. Hawse for sharing this.
#include "KTag.h"
#define NEOPIXEL_ZOFFSET (1)
#define NEOPIXEL_ONE3 (0b110<<24)
#define NEOPIXEL_ZERO3 (0b100<<24)
#define NEOPIXEL_SPI_BIT_PER_BIT (3)
#define NEOPIXEL_COLOR_PER_PIXEL (3)
#define NEOPIXEL_BYTES_PER_PIXEL (NEOPIXEL_SPI_BIT_PER_BIT * NEOPIXEL_COLOR_PER_PIXEL)
#define FRAME_BUFFER_SIZE (NEOPIXEL_ZOFFSET + (CONFIG_KTAG_MAX_NEOPIXELS_PER_CHANNEL * NEOPIXEL_BYTES_PER_PIXEL))
#if (CONFIG_KTAG_N_NEOPIXEL_CHANNELS == 1)
static uint8_t NeoPixel_Barrel_Channel_Frame_Buffer[FRAME_BUFFER_SIZE];
#elif (CONFIG_KTAG_N_NEOPIXEL_CHANNELS == 4)
static uint8_t NeoPixel_Barrel_Channel_Frame_Buffer[FRAME_BUFFER_SIZE];
static uint8_t NeoPixel_Receiver_Channel_Frame_Buffer[FRAME_BUFFER_SIZE];
static uint8_t NeoPixel_Display_Channel_Frame_Buffer[FRAME_BUFFER_SIZE];
static uint8_t NeoPixel_Effects_Channel_Frame_Buffer[FRAME_BUFFER_SIZE];
#else
#error "Unsupported number of NeoPixel channels defined. Supported configurations are 1 and 4."
#endif
static uint8_t* NeoPixel_Frame_Buffers[CONFIG_KTAG_N_NEOPIXEL_CHANNELS] =
{
#if (CONFIG_KTAG_N_NEOPIXEL_CHANNELS == 1)
NeoPixel_Barrel_Channel_Frame_Buffer
#elif (CONFIG_KTAG_N_NEOPIXEL_CHANNELS == 4)
NeoPixel_Barrel_Channel_Frame_Buffer,
NeoPixel_Receiver_Channel_Frame_Buffer,
NeoPixel_Display_Channel_Frame_Buffer,
NeoPixel_Effects_Channel_Frame_Buffer
#else
#error "Unsupported number of NeoPixel channels defined. Supported configurations are 1 and 4."
#endif
};
ColorOrder_T ColorOrderByChannel[CONFIG_KTAG_N_NEOPIXEL_CHANNELS];
// Since the descriptors are (or should be) set to "trigger on descriptor completion" (`.interruptType = CY_DMA_DESCR`),
// this ISR is called after each channel has been written.
static void NeoPixel_DMA_Complete(void)
{
static BaseType_t xHigherPriorityTaskWoken = pdFALSE;
Cy_DMA_Channel_ClearInterrupt(DMA_NeoPixel_HW, DMA_NeoPixel_DW_CHANNEL);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
#define NEOPIXEL_N_DESCRIPTORS CONFIG_KTAG_N_NEOPIXEL_CHANNELS
static cy_stc_dma_descriptor_t NeoPixel_Descriptors[NEOPIXEL_N_DESCRIPTORS];
static void NeoPixel_Configure_DMA(void)
{
// I [AH] copied this structure from the PSoC Creator Component configuration
// in the generated source.
const cy_stc_dma_descriptor_config_t NeoPixel_DMA_Descriptor_Config =
{
.retrigger = CY_DMA_RETRIG_IM,
.interruptType = CY_DMA_DESCR,
.triggerOutType = CY_DMA_1ELEMENT,
.channelState = CY_DMA_CHANNEL_ENABLED,
.triggerInType = CY_DMA_1ELEMENT,
.dataSize = CY_DMA_BYTE,
.srcTransferSize = CY_DMA_TRANSFER_SIZE_DATA,
.dstTransferSize = CY_DMA_TRANSFER_SIZE_WORD,
.descriptorType = CY_DMA_1D_TRANSFER,
.srcAddress = NULL,
.dstAddress = NULL,
.srcXincrement = 1L,
.dstXincrement = 0L,
.xCount = 256UL,
.srcYincrement = 0L,
.dstYincrement = 0L,
.yCount = 1UL,
.nextDescriptor = NULL
};
for (uint_fast8_t i=0; i < NEOPIXEL_N_DESCRIPTORS; i++)
{
Cy_DMA_Descriptor_Init(&NeoPixel_Descriptors[i], &NeoPixel_DMA_Descriptor_Config);
Cy_DMA_Descriptor_SetSrcAddress(&NeoPixel_Descriptors[i], (uint8_t *)&NeoPixel_Frame_Buffers[i][0]);
Cy_DMA_Descriptor_SetDstAddress(&NeoPixel_Descriptors[i], (void *)&SPI_NeoPixel_HW->TX_FIFO_WR);
Cy_DMA_Descriptor_SetXloopDataCount(&NeoPixel_Descriptors[i], FRAME_BUFFER_SIZE);
}
// Initialize and enable the interrupt from DMA_NeoPixel_HW.
Cy_SysInt_Init(&DMA_NeoPixel_Int_cfg, &NeoPixel_DMA_Complete);
NVIC_EnableIRQ(DMA_NeoPixel_Int_cfg.intrSrc);
Cy_DMA_Channel_SetInterruptMask(DMA_NeoPixel_HW, DMA_NeoPixel_DW_CHANNEL, DMA_NeoPixel_INTR_MASK);
Cy_DMA_Enable(DMA_NeoPixel_HW);
}
// Function: NeoPixel_Trigger_DMA
// This function sets up the channel... then enables it to dump the frameBuffer to pixels.
void NeoPixel_Trigger_DMA(uint_fast8_t channel)
{
cy_stc_dma_channel_config_t channel_config;
channel_config.descriptor = &NeoPixel_Descriptors[channel];
channel_config.preemptable = DMA_NeoPixel_PREEMPTABLE;
channel_config.priority = DMA_NeoPixel_PRIORITY;
channel_config.enable = false;
Cy_DMA_Channel_Init(DMA_NeoPixel_HW, DMA_NeoPixel_DW_CHANNEL, &channel_config);
Cy_DMA_Channel_Enable(DMA_NeoPixel_HW, DMA_NeoPixel_DW_CHANNEL);
}
//! Takes an 8-bit value representing a color level and turns it into a WS2812 bit code...
/*!
* ...where 1=110 and 0=011
* One input byte turns into three output bytes of a uint32_t.
*/
uint32_t NeoPixel_ConvertTo3Code(uint8_t input)
{
uint32_t rval=0;
for (uint_fast8_t i=0; i < 8; i++)
{
if (input % 2)
{
rval |= NEOPIXEL_ONE3;
}
else
{
rval |= NEOPIXEL_ZERO3;
}
rval = rval >> 3;
input = input >> 1;
}
return rval;
}
//! Takes a position and a three byte RGB value and updates the corresponding NeoPixel_Frame_Buffer with the correct nine bytes.
SystemKResult_T HW_NeoPixels_Set_RGB(NeoPixelsChannel_T channel, uint8_t position, uint8_t red, uint8_t green, uint8_t blue)
{
typedef union {
uint8_t bytes[4];
uint32_t word;
} NeoPixel_ColorByNumber;
NeoPixel_ColorByNumber color;
ColorOrder_T order = ColorOrderByChannel[channel];
if (order == COLOR_ORDER_RGB)
{
color.word = NeoPixel_ConvertTo3Code(red);
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+0+NEOPIXEL_ZOFFSET] = color.bytes[2];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+1+NEOPIXEL_ZOFFSET] = color.bytes[1];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+2+NEOPIXEL_ZOFFSET] = color.bytes[0];
color.word = NeoPixel_ConvertTo3Code(green);
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+3+NEOPIXEL_ZOFFSET] = color.bytes[2];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+4+NEOPIXEL_ZOFFSET] = color.bytes[1];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+5+NEOPIXEL_ZOFFSET] = color.bytes[0];
color.word = NeoPixel_ConvertTo3Code(blue);
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+6+NEOPIXEL_ZOFFSET] = color.bytes[2];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+7+NEOPIXEL_ZOFFSET] = color.bytes[1];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+8+NEOPIXEL_ZOFFSET] = color.bytes[0];
}
else if (order == COLOR_ORDER_GRB)
{
color.word = NeoPixel_ConvertTo3Code(green);
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+0+NEOPIXEL_ZOFFSET] = color.bytes[2];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+1+NEOPIXEL_ZOFFSET] = color.bytes[1];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+2+NEOPIXEL_ZOFFSET] = color.bytes[0];
color.word = NeoPixel_ConvertTo3Code(red);
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+3+NEOPIXEL_ZOFFSET] = color.bytes[2];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+4+NEOPIXEL_ZOFFSET] = color.bytes[1];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+5+NEOPIXEL_ZOFFSET] = color.bytes[0];
color.word = NeoPixel_ConvertTo3Code(blue);
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+6+NEOPIXEL_ZOFFSET] = color.bytes[2];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+7+NEOPIXEL_ZOFFSET] = color.bytes[1];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+8+NEOPIXEL_ZOFFSET] = color.bytes[0];
}
else
{
// Color order is not handled--log this and use RGB.
{
static bool error_logged = false;
if (error_logged == false)
{
COMM_Console_Print_String("Color order ");
COMM_Console_Print_UInt8(order);
COMM_Console_Print_String(" not yet supported!");
error_logged = true;
}
}
color.word = NeoPixel_ConvertTo3Code(red);
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+0+NEOPIXEL_ZOFFSET] = color.bytes[2];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+1+NEOPIXEL_ZOFFSET] = color.bytes[1];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+2+NEOPIXEL_ZOFFSET] = color.bytes[0];
color.word = NeoPixel_ConvertTo3Code(green);
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+3+NEOPIXEL_ZOFFSET] = color.bytes[2];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+4+NEOPIXEL_ZOFFSET] = color.bytes[1];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+5+NEOPIXEL_ZOFFSET] = color.bytes[0];
color.word = NeoPixel_ConvertTo3Code(blue);
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+6+NEOPIXEL_ZOFFSET] = color.bytes[2];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+7+NEOPIXEL_ZOFFSET] = color.bytes[1];
NeoPixel_Frame_Buffers[channel][position*NEOPIXEL_BYTES_PER_PIXEL+8+NEOPIXEL_ZOFFSET] = color.bytes[0];
}
return SYSTEMK_RESULT_SUCCESS;
}
//! Initializes the hardware.
SystemKResult_T HW_NeoPixels_Init(void)
{
Cy_SCB_SPI_Init(SPI_NeoPixel_HW, &SPI_NeoPixel_config, &SPI_NeoPixel_context);
Cy_SCB_SPI_Enable(SPI_NeoPixel_HW);
NeoPixel_Configure_DMA();
#if (CONFIG_KTAG_N_NEOPIXEL_CHANNELS == 1)
ColorOrderByChannel[NEOPIXEL_CHANNEL_BARREL] = NVM_BARREL_COLOR_ORDER;
#elif (CONFIG_KTAG_N_NEOPIXEL_CHANNELS == 4)
ColorOrderByChannel[NEOPIXEL_CHANNEL_BARREL] = NVM_BARREL_COLOR_ORDER;
ColorOrderByChannel[NEOPIXEL_CHANNEL_RECEIVER] = NVM_RECEIVER_COLOR_ORDER;
ColorOrderByChannel[NEOPIXEL_CHANNEL_DISPLAY] = NVM_DISPLAY_COLOR_ORDER;
ColorOrderByChannel[NEOPIXEL_CHANNEL_EFFECTS] = NVM_EFFECTS_COLOR_ORDER;
#else
#error "Unsupported number of NeoPixel channels defined. Supported configurations are 1 and 4."
#endif
return SYSTEMK_RESULT_SUCCESS;
}
#if (CONFIG_KTAG_N_NEOPIXEL_CHANNELS == 1)
static inline __attribute__((always_inline)) void NeoPixels_Set_Color_On_All_Channels(uint8_t position, color_t color)
{
HW_NeoPixels_Set_RGB(NEOPIXEL_CHANNEL_BARREL, position, Gamma8[Red(color)], Gamma8[Green(color)], Gamma8[Blue(color)]);
}
static inline __attribute__((always_inline)) void NeoPixel_Disable_All_Channels()
{
// Nothing to do.
}
static inline __attribute__((always_inline)) void NeoPixel_Enable_Channel(uint_fast8_t __attribute__ ((unused)) channel)
{
// Nothing to do.
}
static inline __attribute__((always_inline)) void NeoPixel_Disable_Channel(uint_fast8_t __attribute__ ((unused)) channel)
{
// Nothing to do.
}
#elif (CONFIG_KTAG_N_NEOPIXEL_CHANNELS == 4)
static inline __attribute__((always_inline)) void NeoPixel_Enable_Barrel_Channel()
{
Cy_GPIO_Write(Pin_NeoPixel_Select_0_PORT, Pin_NeoPixel_Select_0_NUM, 1);
}
static inline __attribute__((always_inline)) void NeoPixel_Disable_Barrel_Channel()
{
Cy_GPIO_Write(Pin_NeoPixel_Select_0_PORT, Pin_NeoPixel_Select_0_NUM, 0);
}
static inline __attribute__((always_inline)) void NeoPixel_Enable_Receiver_Channel()
{
Cy_GPIO_Write(Pin_NeoPixel_Select_1_PORT, Pin_NeoPixel_Select_1_NUM, 1);
}
static inline __attribute__((always_inline)) void NeoPixel_Disable_Receiver_Channel()
{
Cy_GPIO_Write(Pin_NeoPixel_Select_1_PORT, Pin_NeoPixel_Select_1_NUM, 0);
}
static inline __attribute__((always_inline)) void NeoPixel_Enable_Display_Channel()
{
Cy_GPIO_Write(Pin_NeoPixel_Select_2_PORT, Pin_NeoPixel_Select_2_NUM, 1);
}
static inline __attribute__((always_inline)) void NeoPixel_Disable_Display_Channel()
{
Cy_GPIO_Write(Pin_NeoPixel_Select_2_PORT, Pin_NeoPixel_Select_2_NUM, 0);
}
static inline __attribute__((always_inline)) void NeoPixel_Enable_Effects_Channel()
{
Cy_GPIO_Write(Pin_NeoPixel_Select_3_PORT, Pin_NeoPixel_Select_3_NUM, 1);
}
static inline __attribute__((always_inline)) void NeoPixel_Disable_Effects_Channel()
{
Cy_GPIO_Write(Pin_NeoPixel_Select_3_PORT, Pin_NeoPixel_Select_3_NUM, 0);
}
static inline __attribute__((always_inline)) void NeoPixel_Enable_All_Channels()
{
NeoPixel_Enable_Barrel_Channel();
NeoPixel_Enable_Receiver_Channel();
NeoPixel_Enable_Display_Channel();
NeoPixel_Enable_Effects_Channel();
}
static inline __attribute__((always_inline)) void NeoPixel_Disable_All_Channels()
{
NeoPixel_Disable_Barrel_Channel();
NeoPixel_Disable_Receiver_Channel();
NeoPixel_Disable_Display_Channel();
NeoPixel_Disable_Effects_Channel();
}
static inline __attribute__((always_inline)) void NeoPixel_Enable_Channel(uint_fast8_t channel)
{
switch (channel)
{
case NEOPIXEL_CHANNEL_BARREL:
NeoPixel_Enable_Barrel_Channel();
break;
case NEOPIXEL_CHANNEL_RECEIVER:
NeoPixel_Enable_Receiver_Channel();
break;
case NEOPIXEL_CHANNEL_DISPLAY:
NeoPixel_Enable_Display_Channel();
break;
case NEOPIXEL_CHANNEL_EFFECTS:
NeoPixel_Enable_Effects_Channel();
break;
default:
// Do nothing.
break;
}
}
static inline __attribute__((always_inline)) void NeoPixel_Disable_Channel(uint_fast8_t channel)
{
switch (channel)
{
case NEOPIXEL_CHANNEL_BARREL:
NeoPixel_Disable_Barrel_Channel();
break;
case NEOPIXEL_CHANNEL_RECEIVER:
NeoPixel_Disable_Receiver_Channel();
break;
case NEOPIXEL_CHANNEL_DISPLAY:
NeoPixel_Disable_Display_Channel();
break;
case NEOPIXEL_CHANNEL_EFFECTS:
NeoPixel_Disable_Effects_Channel();
break;
default:
// Do nothing.
break;
}
}
#else
#error "Unsupported number of NeoPixel channels defined. Supported configurations are 1 and 4."
#endif
SystemKResult_T HW_NeoPixels_Publish(void)
{
// Update the NeoPixels using DMA.
for (uint_fast8_t Current_NeoPixel_Channel = 0; Current_NeoPixel_Channel < CONFIG_KTAG_N_NEOPIXEL_CHANNELS; Current_NeoPixel_Channel++)
{
xSemaphoreTake(NeoPixels_Semaphore, portMAX_DELAY);
NeoPixel_Enable_Channel(Current_NeoPixel_Channel);
NeoPixel_Trigger_DMA(Current_NeoPixel_Channel);
// Allow time for the DMA transfer to go out on the wire.
vTaskDelay(portTICK_PERIOD_MS);
NeoPixel_Disable_Channel(Current_NeoPixel_Channel);
xSemaphoreGive(NeoPixels_Semaphore);
}
return SYSTEMK_RESULT_SUCCESS;
}
//! \todo Refactor this somehow...it doesn't belong here.
color_t HW_NeoPixels_Get_My_Color(void)
{
return PROTOCOLS_GetColor(GetWeaponFromID(NVM_WEAPON_ID).Protocol, NVM_TEAM_ID, NVM_PLAYER_ID);
}

View file

@ -0,0 +1,81 @@
/** \file
* \brief This is the top-level include file for the entire project.
*
* By including this file (and only this file), include dependency order is maintained.
*
*/
// KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
// KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
// KKKKKKKKKKKKKKKKKKKKKKKKKKKKky+.`/ykKKKKKKKKKKKKKKKKKKKKKKKKKKKK
// KKKKKKKKKKKKKKKKKKKKKKKKds/. -+o:` ./sdNKKKKKKKKKKKKKKKKKKKKKKK
// KKKKKKKKKKKKKKKKKKNds+-` `-+hNKKKKNho:` `-+shNKKKKKKKKKKKKKKKKKK
// KKKKKKKKKKNkhyo+:. `-/sdNKKKKKKKKKKKKKky+:` .-/oyhdNKKKKKKKKKK
// KKys++:-.````.-:+oykNKKKKKKKKKKKKKKKKKKKKKKNkhs+/-.````.-:/+syKK
// KK -/+osydkNNNKKKkkkkkkkNKKKKKKKKKKKkkkkkkkkNKKKKNNkdhyso/: KK
// KK sKKKKKKKKKKKKK```````/KKKKKKKKKd-```````:kKKKKKKKKKKKKKd `KK
// KK- oKKKKKKKKKKKKK :KKKKKKKKo` `oNKKKKKKKKKKKKKKh :KK
// KK/ +KKKKKKKKKKKKK :KKKKKKd- -dKKKKKKKKKKKKKKKKy /KK
// KK+ /KKKKKKKKKKKKK :KKKKKs` +NKKKKKKKKKKKKKKKKKs +KK
// KKo :KKKKKKKKKKKKK :KKKk: .hKKKKKKKKKKKKKKKKKKKo oKK
// KKy -KKKKKKKKKKKKK :KKy` +NKKKKKKKKKKKKKKKKKKKK/ yKK
// KKd `KKKKKKKKKKKKK :k/ .hKKKKKKKKKKKKKKKKKKKKKK: dKK
// KKN NKKKKKKKKKKKK .. /kKKKKKKKKKKKKKKKKKKKKKKK. NKK
// KKK. dKKKKKKKKKKKK .yKKKKKKKKKKKKKKKKKKKKKKKKN .KKK
// KKK+ oKKKKKKKKKKKK -kKKKKKKKKKKKKKKKKKKKKKKKKKh +KKK
// KKKd .KKKKKKKKKKKK `sNKKKKKKKKKKKKKKKKKKKKKKKK/ dKKK
// KKKK: hKKKKKKKKKKK :kKKKKKKKKKKKKKKKKKKKKKKk :KKKK
// KKKKh -KKKKKKKKKKK `` .yKKKKKKKKKKKKKKKKKKKKK+ hKKKK
// KKKKK/ yKKKKKKKKKK T :d: /kKKKKKKKKKKKKKKKKKKk`:KKKKK
// KKKKKk`.NKKKKKKKKK :KNo` .hKKKKKKKKKKKKKKKKK:`kKKKKK
// KKKKKKy /KKKKKKKKK A :KKKd- +NKKKKKKKKKKKKKKo yKKKKKK
// KKKKKKK+ oKKKKKKKK :KKKKN+` -hKKKKKKKKKKKKy`+KKKKKKK
// KKKKKKKN/ sKKKKKKK G :KKKKKKh. `oNKKKKKKKKKh`/KKKKKKKK
// KKKKKKKKN/`sKKKKKK :KKKKKKKN/ -dKKKKKKKh`/NKKKKKKKK
// KKKKKKKKKK+ +NKKKK :KKKKKKKKKy. `sNKKKKs`+KKKKKKKKKK
// KKKKKKKKKKKs`:kKKK-------+KKKKKKKKKKk/--------oKKN+`sKKKKKKKKKKK
// KKKKKKKKKKKKh..yKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKd--dKKKKKKKKKKKK
// KKKKKKKKKKKKKN+`/kKKKKKKKKKKKKKKKKKKKKKKKKKKKKNo`+NKKKKKKKKKKKKK
// KKKKKKKKKKKKKKKh-`sNKKKKKKKKKKKKKKKKKKKKKKKKNy.-hKKKKKKKKKKKKKKK
// KKKKKKKKKKKKKKKKKs..sNKKKKKKKKKKKKKKKKKKKKNy-.yKKKKKKKKKKKKKKKKK
// KKKKKKKKKKKKKKKKKKNs..okKKKKKKKKKKKKKKKKNs-.sNKKKKKKKKKKKKKKKKKK
// KKKKKKKKKKKKKKKKKKKKKy-`/hKKKKKKKKKKKKd+`-yKKKKKKKKKKKKKKKKKKKKK
// KKKKKKKKKKKKKKKKKKKKKKKd/`.odKKKKKKks-`/dKKKKKKKKKKKKKKKKKKKKKKK
// KKKKKKKKKKKKKKKKKKKKKKKKKNs: .+yy+-`:sNKKKKKKKKKKKKKKKKKKKKKKKKK
// KKKKKKKKKKKKKKKKKKKKKKKKKKKKNy/..+yNKKKKKKKKKKKKKKKKKKKKKKKKKKKK
// KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
// KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
#ifndef KTAG_H
#define KTAG_H
/* Include FreeRTOS APIs and defines */
#include "FreeRTOS.h"
#include "task.h"
#include "croutine.h"
#include "semphr.h"
#include "portmacro.h"
#include "timers.h"
/* Include PSoC system and component APIs and defines */
#include <project.h>
#include <math.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include "CONFIG.h"
#include "SystemK.h"
#include "HW.h"
#include "Audio.h"
#include "NVM.h"
#include "COMM.h"
#include "Fire_Control.h"
#include "Sample_Tasks.h"
#include "Tag_Sensors.h"
#include "Switches.h"
#include "Util.h"
#endif // KTAG_H

View file

@ -0,0 +1,105 @@
/** \dir NVM
*
* \brief Non-Volatile Memory
*
* This directory/namespace contains all the software used to manage non-volatile memory for this CPU.
*
*/
/** \file
* \brief This file defines the interface to the NVM package.
*
* This file should be included by any file outside the NVM package wishing to make use
* of any of the NVM functionality.
*/
#ifndef NVM_H
#define NVM_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
//! Enumeration of the various states of a nonvolatile memory entry.
typedef enum
{
//! This entry has not yet been initialized.
NVM_STATE_UNINITIALIZED = 0,
//! This entry has been read from nonvolatile memory, and the cyclic redundancy check failed.
NVM_STATE_CRC_FAILED,
//! No changes are pending for this entry.
NVM_STATE_IDLE,
//! A request has been made to save this entry to NVM.
NVM_STATE_SAVE_REQUESTED
} NVM_Entry_State_T;
typedef struct
{
// Size of the NVM data.
const size_t Size;
// Address of the NVM data in the EEPROM memory.
const uint16_t EE_Address;
// Address of the calculated CRC value in the EEPROM memory.
const uint16_t EE_CRC_Address;
// Address of the NVM data in RAM.
uint8_t * const Value;
// Address of the default data in ROM.
uint8_t const * const Default;
// Current state of this NVM entry
NVM_Entry_State_T State;
} NVM_EEPROMEntry_T;
/* Include Files */
#include "NVM_CRC.h"
#if (CONFIG__HAS_EXTERNAL_NVM)
#include "NVM_ExternalEEPROM.h"
#include "NVM_ExternalEEPROMEntries.h"
#endif // CONFIG__HAS_EXTERNAL_NVM
#if (CONFIG__HAS_INTERNAL_NVM)
#include "NVM_OnChipEEPROM.h"
#include "NVM_OnChipEEPROMEntries.h"
#endif // CONFIG__HAS_INTERNAL_NVM
/* Public Variables */
/* Public Functions */
inline bool IsNVMInitialized()
{
taskENTER_CRITICAL();
bool is_initialized =
#if (CONFIG__HAS_EXTERNAL_NVM)
NVM_IsExternalEEPROMInitialized &&
#endif // CONFIG__HAS_EXTERNAL_NVM
#if (CONFIG__HAS_INTERNAL_NVM)
NVM_IsOnChipEEPROMInitialized &&
#endif // CONFIG__HAS_INTERNAL_NVM
true;
taskEXIT_CRITICAL();
return is_initialized;
}
#ifdef __cplusplus
}
#endif
#endif // NVM_H

View file

@ -0,0 +1,72 @@
/**
* \file
* Functions and types for CRC checks.
*
* Generated on Sat Jun 15 14:34:15 2019
* by pycrc v0.9.2, https://pycrc.org
* using the configuration:
* - Width = 16
* - Poly = 0xed2f
* - XorIn = 0xbeef
* - ReflectIn = False
* - XorOut = 0x0000
* - ReflectOut = False
* - Algorithm = table-driven
*/
#include "NVM_CRC.h" /* include the header file generated with pycrc */
#include <stdlib.h>
#include <stdint.h>
/**
* Static table used for the table_driven implementation.
*/
static const NVM_CRC_t crc_table[256] = {
0x0000, 0xed2f, 0x3771, 0xda5e, 0x6ee2, 0x83cd, 0x5993, 0xb4bc,
0xddc4, 0x30eb, 0xeab5, 0x079a, 0xb326, 0x5e09, 0x8457, 0x6978,
0x56a7, 0xbb88, 0x61d6, 0x8cf9, 0x3845, 0xd56a, 0x0f34, 0xe21b,
0x8b63, 0x664c, 0xbc12, 0x513d, 0xe581, 0x08ae, 0xd2f0, 0x3fdf,
0xad4e, 0x4061, 0x9a3f, 0x7710, 0xc3ac, 0x2e83, 0xf4dd, 0x19f2,
0x708a, 0x9da5, 0x47fb, 0xaad4, 0x1e68, 0xf347, 0x2919, 0xc436,
0xfbe9, 0x16c6, 0xcc98, 0x21b7, 0x950b, 0x7824, 0xa27a, 0x4f55,
0x262d, 0xcb02, 0x115c, 0xfc73, 0x48cf, 0xa5e0, 0x7fbe, 0x9291,
0xb7b3, 0x5a9c, 0x80c2, 0x6ded, 0xd951, 0x347e, 0xee20, 0x030f,
0x6a77, 0x8758, 0x5d06, 0xb029, 0x0495, 0xe9ba, 0x33e4, 0xdecb,
0xe114, 0x0c3b, 0xd665, 0x3b4a, 0x8ff6, 0x62d9, 0xb887, 0x55a8,
0x3cd0, 0xd1ff, 0x0ba1, 0xe68e, 0x5232, 0xbf1d, 0x6543, 0x886c,
0x1afd, 0xf7d2, 0x2d8c, 0xc0a3, 0x741f, 0x9930, 0x436e, 0xae41,
0xc739, 0x2a16, 0xf048, 0x1d67, 0xa9db, 0x44f4, 0x9eaa, 0x7385,
0x4c5a, 0xa175, 0x7b2b, 0x9604, 0x22b8, 0xcf97, 0x15c9, 0xf8e6,
0x919e, 0x7cb1, 0xa6ef, 0x4bc0, 0xff7c, 0x1253, 0xc80d, 0x2522,
0x8249, 0x6f66, 0xb538, 0x5817, 0xecab, 0x0184, 0xdbda, 0x36f5,
0x5f8d, 0xb2a2, 0x68fc, 0x85d3, 0x316f, 0xdc40, 0x061e, 0xeb31,
0xd4ee, 0x39c1, 0xe39f, 0x0eb0, 0xba0c, 0x5723, 0x8d7d, 0x6052,
0x092a, 0xe405, 0x3e5b, 0xd374, 0x67c8, 0x8ae7, 0x50b9, 0xbd96,
0x2f07, 0xc228, 0x1876, 0xf559, 0x41e5, 0xacca, 0x7694, 0x9bbb,
0xf2c3, 0x1fec, 0xc5b2, 0x289d, 0x9c21, 0x710e, 0xab50, 0x467f,
0x79a0, 0x948f, 0x4ed1, 0xa3fe, 0x1742, 0xfa6d, 0x2033, 0xcd1c,
0xa464, 0x494b, 0x9315, 0x7e3a, 0xca86, 0x27a9, 0xfdf7, 0x10d8,
0x35fa, 0xd8d5, 0x028b, 0xefa4, 0x5b18, 0xb637, 0x6c69, 0x8146,
0xe83e, 0x0511, 0xdf4f, 0x3260, 0x86dc, 0x6bf3, 0xb1ad, 0x5c82,
0x635d, 0x8e72, 0x542c, 0xb903, 0x0dbf, 0xe090, 0x3ace, 0xd7e1,
0xbe99, 0x53b6, 0x89e8, 0x64c7, 0xd07b, 0x3d54, 0xe70a, 0x0a25,
0x98b4, 0x759b, 0xafc5, 0x42ea, 0xf656, 0x1b79, 0xc127, 0x2c08,
0x4570, 0xa85f, 0x7201, 0x9f2e, 0x2b92, 0xc6bd, 0x1ce3, 0xf1cc,
0xce13, 0x233c, 0xf962, 0x144d, 0xa0f1, 0x4dde, 0x9780, 0x7aaf,
0x13d7, 0xfef8, 0x24a6, 0xc989, 0x7d35, 0x901a, 0x4a44, 0xa76b
};
NVM_CRC_t NVM_CRC_update(NVM_CRC_t crc, const void *data, size_t data_len)
{
const unsigned char *d = (const unsigned char *)data;
unsigned int tbl_idx;
while (data_len--) {
tbl_idx = ((crc >> 8) ^ *d) & 0xff;
crc = (crc_table[tbl_idx] ^ (crc << 8)) & 0xffff;
d++;
}
return crc & 0xffff;
}

View file

@ -0,0 +1,115 @@
/**
* \file
* Functions and types for CRC checks.
*
* Generated on Sat Jun 15 14:34:05 2019
* by pycrc v0.9.2, https://pycrc.org
* using the configuration:
* - Width = 16
* - Poly = 0xed2f
* - XorIn = 0xbeef
* - ReflectIn = False
* - XorOut = 0x0000
* - ReflectOut = False
* - Algorithm = table-driven
*
* This file defines the functions NVM_CRC_init(), NVM_CRC_update() and NVM_CRC_finalize().
*
* The NVM_CRC_init() function returns the inital \c crc value and must be called
* before the first call to NVM_CRC_update().
* Similarly, the NVM_CRC_finalize() function must be called after the last call
* to NVM_CRC_update(), before the \c crc is being used.
* is being used.
*
* The NVM_CRC_update() function can be called any number of times (including zero
* times) in between the NVM_CRC_init() and NVM_CRC_finalize() calls.
*
* This pseudo-code shows an example usage of the API:
* \code{.c}
* NVM_CRC_t crc;
* unsigned char data[MAX_DATA_LEN];
* size_t data_len;
*
* crc = NVM_CRC_init();
* while ((data_len = read_data(data, MAX_DATA_LEN)) > 0) {
* crc = NVM_CRC_update(crc, data, data_len);
* }
* crc = NVM_CRC_finalize(crc);
* \endcode
*
* ## Additional Notes
*
* The CRC polynomial (0xED2F) was chosen based on the research published by Philip Koopman of Carnegie Mellon
* University [here](http://users.ece.cmu.edu/~koopman/crc/). Dr. Koopman claims this polynomial has a
* Hamming Distance of 10.
*
* The initial value, 0xBEEF, was chosen simply to avoid the most common EE values of 0xFFFF and 0x0000.
*
*/
#ifndef NVM_CRC_H
#define NVM_CRC_H
#include <stdlib.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* The definition of the used algorithm.
*
* This is not used anywhere in the generated code, but it may be used by the
* application code to call algorithm-specific code, if desired.
*/
#define CRC_ALGO_TABLE_DRIVEN 1
/**
* The type of the CRC values.
*
* CRCs are sixteen bits wide.
*/
typedef uint16_t NVM_CRC_t;
/**
* Calculate the initial crc value.
*
* \return The initial crc value.
*/
static inline NVM_CRC_t NVM_CRC_init(void)
{
return 0xbeef;
}
/**
* Update the crc value with new data.
*
* \param[in] crc The current crc value.
* \param[in] data Pointer to a buffer of \a data_len bytes.
* \param[in] data_len Number of bytes in the \a data buffer.
* \return The updated crc value.
*/
NVM_CRC_t NVM_CRC_update(NVM_CRC_t crc, const void *data, size_t data_len);
/**
* Calculate the final crc value.
*
* \param[in] crc The current crc value.
* \return The final crc value.
*/
static inline NVM_CRC_t NVM_CRC_finalize(NVM_CRC_t crc)
{
return crc;
}
#ifdef __cplusplus
} /* closing brace for extern "C" */
#endif
#endif /* NVM_CRC_H */

View file

@ -0,0 +1,302 @@
/** \file
* \brief This file contains functions that manage the external EEPROM.
*
*/
/* Include Files */
#include "KTag.h"
/* Local Definitions and Constants */
//! This is the same for both the MCP98243 and the CAT24C256.
#define EXTERNAL_EEPROM_I2C_ADDRESS 0x50
#define EXTERNAL_EEPROM_TEMP_SENSOR_I2C_ADDRESS 0x18
//! Read-only register used to identify the temperature sensor capability.
#define MCP98243_REGISTER_CAPABILITY 0x00
//! Sensor configuration register.
#define MCP98243_REGISTER_CONFIG 0x01
//! Upper temperature limit register.
#define MCP98243_REGISTER_T_UPPER 0x02
//! Lower temperature limit register.
#define MCP98243_REGISTER_T_LOWER 0x03
//! Critical temperature limit register.
#define MCP98243_REGISTER_T_CRIT 0x04
//! Ambient temperature register.
#define MCP98243_REGISTER_T_A 0x05
//! Read-only register used to identify the manufacturer of the device.
#define MCP98243_REGISTER_MANUFACTURER_ID 0x06
//! Read-only register indicating the device identification and device revision.
#define MCP98243_REGISTER_DEVICE_ID 0x07
//! Temperature sensor resolution register.
#define MCP98243_REGISTER_RESOLUTION 0x08
/* External Variables [Only if necessary!] */
/* External Function Prototypes [Only if necessary!] */
/* Public Variables */
//! Mutex controlling access to the EEPROM to ensure data/CRC integrity.
SemaphoreHandle_t xSemaphoreExternalEEPROMLock;
TaskHandle_t NVM_ExternalEEPROM_Task_Handle;
volatile bool NVM_IsExternalEEPROMInitialized = false;
/* Private Variables */
static QueueHandle_t xQueueExternalEEPROM;
//! Shared master transfer configuration variable.
static cy_stc_scb_i2c_master_xfer_config_t Master_Transfer_Config =
{
.slaveAddress = EXTERNAL_EEPROM_I2C_ADDRESS,
.buffer = NULL,
.bufferSize = 0U,
.xferPending = false
};
/* Private Function Prototypes */
/* Inline Functions */
//! Waits a given time for an I²C transfer to complete.
/*!
* \param timeout_in_ms The time (in milliseconds) to wait for the transfer to complete.
* \return #true if the transfer completed, or #false if the time ran out without
* a successful transfer.
*/
static inline bool Wait_For_Transfer_To_Complete(uint16_t timeout_in_ms)
{
bool success = false;
// Time to wait for an in-process transfer before looking again. This wait grows longer as time
// passes, until timeout_in_ms runs out.
uint16_t HOLDOFF_TIME_IN_ms = 1;
while ((success == false) && (timeout_in_ms > 0))
{
vTaskDelay(pdMS_TO_TICKS(HOLDOFF_TIME_IN_ms));
if (timeout_in_ms > HOLDOFF_TIME_IN_ms)
{
timeout_in_ms -= HOLDOFF_TIME_IN_ms;
// Wait a little longer next time.
HOLDOFF_TIME_IN_ms++;
}
else
{
timeout_in_ms = 0;
}
if ((I2C_MasterGetStatus() & CY_SCB_I2C_MASTER_BUSY) != CY_SCB_I2C_MASTER_BUSY)
{
success = true;
}
}
return success;
}
//! Reads a block of \a n bytes from EEPROM address \a source to SRAM \a destination.
static inline void EEPROM_read_block(uint8_t * destination, uint16_t source, size_t n)
{
uint8_t xfer_buffer[5];
if (xSemaphoreTake(COMM_I2C_Bus_Mutex, portMAX_DELAY) == pdTRUE)
{
// Write the initial address to the EEPROM.
xfer_buffer[0] = (source >> 8);
xfer_buffer[1] = source & 0xFF;
Master_Transfer_Config.buffer = (uint8_t *)xfer_buffer;
Master_Transfer_Config.bufferSize = 2;
cy_en_scb_i2c_status_t errStatus = I2C_MasterWrite(&Master_Transfer_Config);
if (errStatus == CY_SCB_I2C_SUCCESS)
{
(void) Wait_For_Transfer_To_Complete(100);
}
else
{
// What?
}
// Read n bytes at EEPROM[source].
Master_Transfer_Config.buffer = (uint8_t *)destination;
Master_Transfer_Config.bufferSize = n;
errStatus = I2C_MasterRead(&Master_Transfer_Config);
if (errStatus == CY_SCB_I2C_SUCCESS)
{
(void) Wait_For_Transfer_To_Complete(100);
}
else
{
// What?
}
xSemaphoreGive(COMM_I2C_Bus_Mutex);
}
}
//! Writes a block of \a n bytes from SRAM \a source to EEPROM address \a destination.
static inline void EEPROM_write_block(uint8_t * source, uint16_t destination, size_t n)
{
uint8_t xfer_buffer[4];
if (xSemaphoreTake(COMM_I2C_Bus_Mutex, portMAX_DELAY) == pdTRUE)
{
// Write the data one byte at a time.
for (uint8_t i = 0; i < n; i++)
{
uint16_t destination_address = destination + i;
xfer_buffer[0] = (destination_address >> 8);
xfer_buffer[1] = destination_address & 0xFF;
xfer_buffer[2] = *(source + i);
Master_Transfer_Config.buffer = (uint8_t *)xfer_buffer;
Master_Transfer_Config.bufferSize = 3;
cy_en_scb_i2c_status_t errStatus = I2C_MasterWrite(&Master_Transfer_Config);
if (errStatus == CY_SCB_I2C_SUCCESS)
{
(void) Wait_For_Transfer_To_Complete(100);
}
else
{
// What?
}
// The CAT24C256 has a nominal Write Cycle time (t_WR) of 5ms (no maximum specified).
// Wait 6ms between writes to have some margin (and avoid being NAKed).
vTaskDelay(pdMS_TO_TICKS(6));
}
xSemaphoreGive(COMM_I2C_Bus_Mutex);
}
}
/* Public Functions */
//! Sets up the external EEPROM, but does not read from it (yet).
void NVM_InitExternalEEPROM(void)
{
/// Create a mutex-type semaphore.
xSemaphoreExternalEEPROMLock = xSemaphoreCreateMutex();
if (xSemaphoreExternalEEPROMLock == NULL)
{
CY_ASSERT(0);
}
xQueueExternalEEPROM = xQueueCreate(5, sizeof(uint8_t));
}
//! Handles the ongoing external EEPROM tasks.
/*!
* First, it loops through all the external EEPROM entries, and reads them in to RAM.
* Then, it priodically loops through all the external EEPROM entries, and saves the ones that have been flagged.
*/
void NVM_ExternalEEPROMTask(void * pvParameters)
{
portBASE_TYPE xStatus;
static TickType_t xTicksToWait = pdMS_TO_TICKS(NVM_EXTERNAL_EEPROM_TASK_RATE_IN_ms);
for (uint8_t i = 0; i < NVM_N_EXTERNAL_EEPROM_ENTRIES; i++)
{
NVM_CRC_t calculated_crc;
NVM_CRC_t stored_crc = 0;
EEPROM_read_block(NVM_ExternalEEPROMEntries[i]->Value, NVM_ExternalEEPROMEntries[i]->EE_Address, NVM_ExternalEEPROMEntries[i]->Size);
EEPROM_read_block((uint8_t *)&stored_crc, NVM_ExternalEEPROMEntries[i]->EE_CRC_Address, sizeof(NVM_CRC_t));
calculated_crc = NVM_CRC_init();
calculated_crc = NVM_CRC_update(calculated_crc, NVM_ExternalEEPROMEntries[i]->Value, NVM_ExternalEEPROMEntries[i]->Size);
calculated_crc = NVM_CRC_finalize(calculated_crc);
if (calculated_crc == stored_crc)
{
NVM_ExternalEEPROMEntries[i]->State = NVM_STATE_IDLE;
}
else
{
NVM_ExternalEEPROMEntries[i]->State = NVM_STATE_CRC_FAILED;
COMM_Console_Print_String("[NVMEx ");
COMM_Console_Print_UInt16((uint16_t) i);
COMM_Console_Print_String("] Calculated/Stored CRCs: ");
COMM_Console_Print_UInt16((uint16_t) calculated_crc);
COMM_Console_Print_String("/");
COMM_Console_Print_UInt16((uint16_t) stored_crc);
COMM_Console_Print_String("\n");
COMM_Console_Print_String("[NVMEx ");
COMM_Console_Print_UInt16((uint16_t) i);
COMM_Console_Print_String("] Applying defaults.\n");
memcpy(NVM_ExternalEEPROMEntries[i]->Value, NVM_ExternalEEPROMEntries[i]->Default, NVM_ExternalEEPROMEntries[i]->Size);
// Auto-fix the CRC.
NVM_SaveExternalEEPROMEntry(NVM_ExternalEEPROMEntries[i]);
}
}
taskENTER_CRITICAL();
NVM_IsExternalEEPROMInitialized = true;
taskEXIT_CRITICAL();
while(true)
{
uint8_t dummy;
// Wait for a call to NVM_SaveExternalEEPROMEntry().
xStatus = xQueueReceive(xQueueExternalEEPROM, &dummy, xTicksToWait);
if (xStatus == pdPASS)
{
for (uint8_t i = 0; i < NVM_N_EXTERNAL_EEPROM_ENTRIES; i++)
{
NVM_CRC_t crc;
if (NVM_ExternalEEPROMEntries[i]->State == NVM_STATE_SAVE_REQUESTED)
{
if (xSemaphoreTake(xSemaphoreExternalEEPROMLock, portMAX_DELAY) == pdTRUE)
{
EEPROM_write_block(NVM_ExternalEEPROMEntries[i]->Value, NVM_ExternalEEPROMEntries[i]->EE_Address, NVM_ExternalEEPROMEntries[i]->Size);
// Calculate the CRC.
crc = NVM_CRC_init();
crc = NVM_CRC_update(crc, NVM_ExternalEEPROMEntries[i]->Value, NVM_ExternalEEPROMEntries[i]->Size);
crc = NVM_CRC_finalize(crc);
EEPROM_write_block((uint8_t *)&crc, NVM_ExternalEEPROMEntries[i]->EE_CRC_Address, sizeof(uint16_t));
NVM_ExternalEEPROMEntries[i]->State = NVM_STATE_IDLE;
xSemaphoreGive(xSemaphoreExternalEEPROMLock);
}
}
}
}
}
}
//! Flags the given external EEPROM entry to be saved next time the NVM_ExternalEEPROMTask() is run.
void NVM_SaveExternalEEPROMEntry(NVM_EEPROMEntry_T * const this)
{
if (xSemaphoreTake(xSemaphoreExternalEEPROMLock, portMAX_DELAY) == pdTRUE)
{
this->State = NVM_STATE_SAVE_REQUESTED;
xSemaphoreGive(xSemaphoreExternalEEPROMLock);
uint8_t dummy = 0;
xQueueSend(xQueueExternalEEPROM, &dummy, 0);
}
}
/* Private Functions */

View file

@ -0,0 +1,44 @@
/** \file
* \brief This file contains the public interface to the external EEPROM.
*
* On the 2020TPC, the external EEPROM is the Onsemi [CAT24C256](https://www.onsemi.com/pdf/datasheet/cat24c256-d.pdf).
*
*/
#ifndef NVM_EXTERNALEEPROM_H
#define NVM_EXTERNALEEPROM_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
#define NVM_EXTERNAL_EEPROM_TASK_STACK_SIZE_in_bytes 256
//! The time between calls to NVM_ExternalEEPROMTask().
#define NVM_EXTERNAL_EEPROM_TASK_RATE_IN_ms 2000
/* Include Files */
/* Public Variables */
extern SemaphoreHandle_t xSemaphoreExternalEEPROMLock;
//! Handle of the NVM_ExternalEEPROMTask() given when the task was created.
extern TaskHandle_t NVM_ExternalEEPROM_Task_Handle;
extern volatile bool NVM_IsExternalEEPROMInitialized;
/* Public Functions */
void NVM_InitExternalEEPROM(void);
void NVM_ExternalEEPROMTask(void * pvParameters);
void NVM_SaveExternalEEPROMEntry(NVM_EEPROMEntry_T * const this);
/* Inline Functions */
#ifdef __cplusplus
}
#endif
#endif // NVM_EXTERNALEEPROM_H

View file

@ -0,0 +1,153 @@
/*
* __ ________ _____ ______ __
* / //_/_ __/___ _____ _ / ___/____ __ _______________ / ____/___ ____/ /__
* / ,< / / / __ `/ __ `/ \__ \/ __ \/ / / / ___/ ___/ _ \ / / / __ \/ __ / _ \
* / /| | / / / /_/ / /_/ / ___/ / /_/ / /_/ / / / /__/ __/ / /___/ /_/ / /_/ / __/
* /_/ |_|/_/ \__,_/\__, / /____/\____/\__,_/_/ \___/\___/ \____/\____/\__,_/\___/
* /____/
*
* 🃞 THIS FILE IS PART OF THE KTAG SOURCE CODE. Visit https://ktag.clubk.club/ for more. 🃞
*
*/
/** \file
* \brief [Autogenerated] This file defines the External EEPROM entries.
*
* \note AUTOGENERATED: This file was generated automatically on Friday, April 28, 2023 at 11:31:31 AM.
* DO NOT MODIFY THIS FILE MANUALLY!
*/
/* Include Files */
#include "KTag.h"
/* EEPROM Entries */
/** \defgroup NVM_EXTERNAL_EEPROM NVM External EEPROM
*
* The External EEPROM is divided into logical "entries", represented by instances of the #NVM_EEPROMEntry_T type.
* At startup, these entries are loaded into their respective RAM copies by NVM_InitExternalEEPROM(). The application
* then updates the RAM copies directly, and requests that the NVM_ExternalEEPROMTask() save these back to the EEPROM
* when necessary.
* @{ */
static NVM_External_Test_T RAM_External_Test;
static const NVM_External_Test_T DEFAULT_External_Test =
{
//! Test Code 3
.External_Test_3 = UINT16_MAX,
//! Test Code 4
.External_Test_4 = UINT32_MAX,
};
NVM_EEPROMEntry_T NVM_External_Test =
{
//! Size == sizeof(NVM_External_Test_T)
.Size = 6,
.EE_Address = 0,
.EE_CRC_Address = 6,
.Value = (uint8_t *)&RAM_External_Test,
.Default = (uint8_t *)&DEFAULT_External_Test,
.State = NVM_STATE_UNINITIALIZED
};
static NVM_Info_T RAM_Info;
static const NVM_Info_T DEFAULT_Info =
{
//! Date this unit was first programmed.
.Date_Code_as_YYYYMMDD = 20200101,
};
NVM_EEPROMEntry_T NVM_Info =
{
//! Size == sizeof(NVM_Info_T)
.Size = 4,
.EE_Address = 8,
.EE_CRC_Address = 12,
.Value = (uint8_t *)&RAM_Info,
.Default = (uint8_t *)&DEFAULT_Info,
.State = NVM_STATE_UNINITIALIZED
};
static NVM_Hardware_Settings_T RAM_Hardware_Settings;
static const NVM_Hardware_Settings_T DEFAULT_Hardware_Settings =
{
//! Color order for the barrel Neopixels.
.Barrel_Color_Order = 2,
//! Color order for the receiver NeoPixels.
.Receiver_Color_Order = 0,
//! Color order for the display NeoPixels.
.Display_Color_Order = 2,
//! Color order for the effects NeoPixels.
.Effects_Color_Order = 2,
//! true if this unit is configured for a right-handed person; false if for a left-handed person.
.Is_Right_Handed = true,
//! Audio volume.
.Volume = 20,
};
NVM_EEPROMEntry_T NVM_Hardware_Settings =
{
//! Size == sizeof(NVM_Hardware_Settings_T)
.Size = 6,
.EE_Address = 14,
.EE_CRC_Address = 20,
.Value = (uint8_t *)&RAM_Hardware_Settings,
.Default = (uint8_t *)&DEFAULT_Hardware_Settings,
.State = NVM_STATE_UNINITIALIZED
};
static NVM_Game_Settings_T RAM_Game_Settings;
static const NVM_Game_Settings_T DEFAULT_Game_Settings =
{
//! Selected weapon.
.Weapon_ID = LASER_X_ID,
//! Player identification (is this used?)
.Player_ID = 0,
//! Selected team.
.Team_ID = 1,
};
NVM_EEPROMEntry_T NVM_Game_Settings =
{
//! Size == sizeof(NVM_Game_Settings_T)
.Size = 3,
.EE_Address = 22,
.EE_CRC_Address = 25,
.Value = (uint8_t *)&RAM_Game_Settings,
.Default = (uint8_t *)&DEFAULT_Game_Settings,
.State = NVM_STATE_UNINITIALIZED
};
static NVM_Hourmeter_T RAM_Hourmeter;
static const NVM_Hourmeter_T DEFAULT_Hourmeter =
{
//! Total number of startups for this unit.
.Hourmeter_Startups = 0,
};
NVM_EEPROMEntry_T NVM_Hourmeter =
{
//! Size == sizeof(NVM_Hourmeter_T)
.Size = 2,
.EE_Address = 27,
.EE_CRC_Address = 29,
.Value = (uint8_t *)&RAM_Hourmeter,
.Default = (uint8_t *)&DEFAULT_Hourmeter,
.State = NVM_STATE_UNINITIALIZED
};
/** @} */
NVM_EEPROMEntry_T * const NVM_ExternalEEPROMEntries[] =
{
&NVM_External_Test,
&NVM_Info,
&NVM_Hardware_Settings,
&NVM_Game_Settings,
&NVM_Hourmeter,
};
//! Size of the #NVM_ExternalEEPROMEntries array (i.e. the number of External EEPROM entries).
const uint8_t NVM_N_EXTERNAL_EEPROM_ENTRIES = (uint8_t) (sizeof(NVM_ExternalEEPROMEntries) / sizeof(NVM_EEPROMEntry_T *));

View file

@ -0,0 +1,135 @@
/*
* __ ________ _____ ______ __
* / //_/_ __/___ _____ _ / ___/____ __ _______________ / ____/___ ____/ /__
* / ,< / / / __ `/ __ `/ \__ \/ __ \/ / / / ___/ ___/ _ \ / / / __ \/ __ / _ \
* / /| | / / / /_/ / /_/ / ___/ / /_/ / /_/ / / / /__/ __/ / /___/ /_/ / /_/ / __/
* /_/ |_|/_/ \__,_/\__, / /____/\____/\__,_/_/ \___/\___/ \____/\____/\__,_/\___/
* /____/
*
* 🃞 THIS FILE IS PART OF THE KTAG SOURCE CODE. Visit https://ktag.clubk.club/ for more. 🃞
*
*/
/** \file
* \brief [Autogenerated] This file declares the External EEPROM entries.
*
* \note AUTOGENERATED: This file was generated automatically on Friday, April 28, 2023 at 11:31:31 AM.
* DO NOT MODIFY THIS FILE MANUALLY!
*/
#ifndef NVM_EXTERNALEEPROMENTRIES_H
#define NVM_EXTERNALEEPROMENTRIES_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
typedef struct __attribute__((packed))
{
//! Test Code 3
uint16_t External_Test_3;
//! Test Code 4
uint32_t External_Test_4;
} NVM_External_Test_T;
typedef struct __attribute__((packed))
{
//! Date this unit was first programmed.
uint32_t Date_Code_as_YYYYMMDD;
} NVM_Info_T;
typedef struct __attribute__((packed))
{
//! Color order for the barrel Neopixels.
uint8_t Barrel_Color_Order;
//! Color order for the receiver NeoPixels.
uint8_t Receiver_Color_Order;
//! Color order for the display NeoPixels.
uint8_t Display_Color_Order;
//! Color order for the effects NeoPixels.
uint8_t Effects_Color_Order;
//! true if this unit is configured for a right-handed person; false if for a left-handed person.
bool Is_Right_Handed;
//! Audio volume.
uint8_t Volume;
} NVM_Hardware_Settings_T;
typedef struct __attribute__((packed))
{
//! Selected weapon.
uint8_t Weapon_ID;
//! Player identification (is this used?)
uint8_t Player_ID;
//! Selected team.
uint8_t Team_ID;
} NVM_Game_Settings_T;
typedef struct __attribute__((packed))
{
//! Total number of startups for this unit.
uint16_t Hourmeter_Startups;
} NVM_Hourmeter_T;
/* Include Files */
/* Public Variables */
extern NVM_EEPROMEntry_T NVM_External_Test;
extern NVM_EEPROMEntry_T NVM_Info;
extern NVM_EEPROMEntry_T NVM_Hardware_Settings;
extern NVM_EEPROMEntry_T NVM_Game_Settings;
extern NVM_EEPROMEntry_T NVM_Hourmeter;
extern NVM_EEPROMEntry_T * const NVM_ExternalEEPROMEntries[];
extern const uint8_t NVM_N_EXTERNAL_EEPROM_ENTRIES;
// Shorthand macros, to save you time.
#define NVM_EXTERNAL_TEST_3 (((NVM_External_Test_T*)NVM_External_Test.Value)->External_Test_3)
#define NVM_EXTERNAL_TEST_3_ENTRY_PTR (&NVM_External_Test)
#define NVM_EXTERNAL_TEST_4 (((NVM_External_Test_T*)NVM_External_Test.Value)->External_Test_4)
#define NVM_EXTERNAL_TEST_4_ENTRY_PTR (&NVM_External_Test)
#define NVM_DATE_CODE_AS_YYYYMMDD (((NVM_Info_T*)NVM_Info.Value)->Date_Code_as_YYYYMMDD)
#define NVM_DATE_CODE_AS_YYYYMMDD_ENTRY_PTR (&NVM_Info)
#define NVM_BARREL_COLOR_ORDER (((NVM_Hardware_Settings_T*)NVM_Hardware_Settings.Value)->Barrel_Color_Order)
#define NVM_BARREL_COLOR_ORDER_ENTRY_PTR (&NVM_Hardware_Settings)
#define NVM_RECEIVER_COLOR_ORDER (((NVM_Hardware_Settings_T*)NVM_Hardware_Settings.Value)->Receiver_Color_Order)
#define NVM_RECEIVER_COLOR_ORDER_ENTRY_PTR (&NVM_Hardware_Settings)
#define NVM_DISPLAY_COLOR_ORDER (((NVM_Hardware_Settings_T*)NVM_Hardware_Settings.Value)->Display_Color_Order)
#define NVM_DISPLAY_COLOR_ORDER_ENTRY_PTR (&NVM_Hardware_Settings)
#define NVM_EFFECTS_COLOR_ORDER (((NVM_Hardware_Settings_T*)NVM_Hardware_Settings.Value)->Effects_Color_Order)
#define NVM_EFFECTS_COLOR_ORDER_ENTRY_PTR (&NVM_Hardware_Settings)
#define NVM_IS_RIGHT_HANDED (((NVM_Hardware_Settings_T*)NVM_Hardware_Settings.Value)->Is_Right_Handed)
#define NVM_IS_RIGHT_HANDED_ENTRY_PTR (&NVM_Hardware_Settings)
#define NVM_VOLUME (((NVM_Hardware_Settings_T*)NVM_Hardware_Settings.Value)->Volume)
#define NVM_VOLUME_ENTRY_PTR (&NVM_Hardware_Settings)
#define NVM_WEAPON_ID (((NVM_Game_Settings_T*)NVM_Game_Settings.Value)->Weapon_ID)
#define NVM_WEAPON_ID_ENTRY_PTR (&NVM_Game_Settings)
#define NVM_PLAYER_ID (((NVM_Game_Settings_T*)NVM_Game_Settings.Value)->Player_ID)
#define NVM_PLAYER_ID_ENTRY_PTR (&NVM_Game_Settings)
#define NVM_TEAM_ID (((NVM_Game_Settings_T*)NVM_Game_Settings.Value)->Team_ID)
#define NVM_TEAM_ID_ENTRY_PTR (&NVM_Game_Settings)
#define NVM_HOURMETER_STARTUPS (((NVM_Hourmeter_T*)NVM_Hourmeter.Value)->Hourmeter_Startups)
#define NVM_HOURMETER_STARTUPS_ENTRY_PTR (&NVM_Hourmeter)
#ifdef __cplusplus
}
#endif
#endif // NVM_EXTERNALEEPROMENTRIES_H

View file

@ -0,0 +1,260 @@
/** \file
* \brief This file contains functions that manage the on-chip EEPROM.
*
*/
/* Include Files */
#include "KTag.h"
/* Local Definitions and Constants */
/* External Variables [Only if necessary!] */
/* External Function Prototypes [Only if necessary!] */
/* Public Variables */
//! Mutex controlling access to the EEPROM to ensure data/CRC integrity.
SemaphoreHandle_t xSemaphoreOnChipEEPROMLock;
TaskHandle_t NVM_OnChipEEPROM_Task_Handle;
volatile bool NVM_IsOnChipEEPROMInitialized = false;
/* Private Variables */
static QueueHandle_t xQueueOnChipEEPROM;
#if CY_PSOC4
const uint8_t Emulated_EEPROM_Storage[On_Chip_Emulated_EEPROM_PHYSICAL_SIZE]
__ALIGNED(CY_FLASH_SIZEOF_ROW) = {0u};
#endif // CY_PSOC4
/* Private Function Prototypes */
/* Inline Functions */
#if CY_PSOC4
//! Reads a block of \a n bytes from EEPROM address \a source to SRAM \a destination.
static inline void EEPROM_read_block(uint8_t * destination, uint16_t source, size_t n)
{
On_Chip_Emulated_EEPROM_Read(source, destination, n);
}
//! Writes a block of \a n bytes from SRAM \a source to EEPROM address \a destination.
static inline void EEPROM_write_block(uint8_t * source, uint16_t destination, size_t n)
{
On_Chip_Emulated_EEPROM_Write(destination, source, n);
}
#endif // CY_PSOC4
#if CY_PSOC5
//! Reads a block of \a n bytes from EEPROM address \a source to SRAM \a destination.
static inline void EEPROM_read_block(uint8_t * destination, uint16_t source, size_t n)
{
for (uint_fast16_t i = 0; i < n; i++)
{
uint8_t temp = On_Chip_EEPROM_ReadByte(source + i);
*(destination + i) = temp;
}
}
//! Writes a block of \a n bytes from SRAM \a source to EEPROM address \a destination.
static inline void EEPROM_write_block(uint8_t * source, uint16_t destination, size_t n)
{
for (uint_fast16_t i = 0; i < n; i++)
{
On_Chip_EEPROM_WriteByte(*(source + i), destination + i);
}
}
#endif // CY_PSOC5
#if CY_PSOC6
//! Reads a block of \a n bytes from EEPROM address \a source to SRAM \a destination.
static inline void EEPROM_read_block(uint8_t * destination, uint16_t source, size_t n)
{
cy_en_em_eeprom_status_t result = On_Chip_EEPROM_Read(source, destination, n);
if (result != CY_EM_EEPROM_SUCCESS)
{
CY_ASSERT(0);
}
}
//! Writes a block of \a n bytes from SRAM \a source to EEPROM address \a destination.
static inline void EEPROM_write_block(uint8_t * source, uint16_t destination, size_t n)
{
cy_en_em_eeprom_status_t result = On_Chip_EEPROM_Write(destination, source, n);
if (result != CY_EM_EEPROM_SUCCESS)
{
CY_ASSERT(0);
}
}
#endif // CY_PSOC6
/* Public Functions */
//! Sets up the on-chip EEPROM, but does not read from it (yet).
void NVM_InitOnChipEEPROM(void)
{
/// Create a mutex-type semaphore.
xSemaphoreOnChipEEPROMLock = xSemaphoreCreateMutex();
if (xSemaphoreOnChipEEPROMLock == NULL)
{
CY_ASSERT(0);
}
xQueueOnChipEEPROM = xQueueCreate(5, sizeof(uint8_t));
#if CY_PSOC4
On_Chip_Emulated_EEPROM_Init((uint32_t)Emulated_EEPROM_Storage);
#endif // CY_PSOC4
#if CY_PSOC5
On_Chip_EEPROM_Start();
#endif // CY_PSOC5
#if CY_PSOC6
// From the docs: "For PSoC 6, if Emulated EEPROM is selected for EEPROM storage, the start address will be
// overwritten to some address from Emulated EEPROM flash area."
On_Chip_EEPROM_Init(0);
#endif // CY_PSOC6
}
//! Handles the ongoing on-chip EEPROM tasks.
/*!
* First, it loops through all the on-chip EEPROM entries, and reads them in to RAM.
* Then, it priodically loops through all the on-chip EEPROM entries, and saves the ones that have been flagged.
*/
void NVM_OnChipEEPROMTask(void * pvParameters)
{
portBASE_TYPE xStatus;
static TickType_t xTicksToWait = pdMS_TO_TICKS(NVM_ON_CHIP_EEPROM_TASK_RATE_IN_ms);
for (uint8_t i = 0; i < NVM_N_ONCHIP_EEPROM_ENTRIES; i++)
{
NVM_CRC_t calculated_crc;
NVM_CRC_t stored_crc = 0;
EEPROM_read_block(NVM_OnChipEEPROMEntries[i]->Value, NVM_OnChipEEPROMEntries[i]->EE_Address, NVM_OnChipEEPROMEntries[i]->Size);
EEPROM_read_block((uint8_t *)&stored_crc, NVM_OnChipEEPROMEntries[i]->EE_CRC_Address, sizeof(NVM_CRC_t));
calculated_crc = NVM_CRC_init();
calculated_crc = NVM_CRC_update(calculated_crc, NVM_OnChipEEPROMEntries[i]->Value, NVM_OnChipEEPROMEntries[i]->Size);
calculated_crc = NVM_CRC_finalize(calculated_crc);
if (calculated_crc == stored_crc)
{
NVM_OnChipEEPROMEntries[i]->State = NVM_STATE_IDLE;
}
else
{
NVM_OnChipEEPROMEntries[i]->State = NVM_STATE_CRC_FAILED;
COMM_Console_Print_String("[NVMOn ");
COMM_Console_Print_UInt16((uint16_t) i);
COMM_Console_Print_String("] Calculated/Stored CRCs: ");
COMM_Console_Print_UInt16((uint16_t) calculated_crc);
COMM_Console_Print_String("/");
COMM_Console_Print_UInt16((uint16_t) stored_crc);
COMM_Console_Print_String("\n");
COMM_Console_Print_String("[NVMOn ");
COMM_Console_Print_UInt16((uint16_t) i);
COMM_Console_Print_String("] Applying defaults.\n");
memcpy(NVM_OnChipEEPROMEntries[i]->Value, NVM_OnChipEEPROMEntries[i]->Default, NVM_OnChipEEPROMEntries[i]->Size);
// Auto-fix the CRC.
NVM_SaveOnChipEEPROMEntry(NVM_OnChipEEPROMEntries[i]);
}
}
taskENTER_CRITICAL();
NVM_IsOnChipEEPROMInitialized = true;
taskEXIT_CRITICAL();
while(true)
{
uint8_t dummy;
// Wait for a call to NVM_SaveOnChipEEPROMEntry().
xStatus = xQueueReceive(xQueueOnChipEEPROM, &dummy, xTicksToWait);
if (xStatus == pdPASS)
{
for (uint8_t i = 0; i < NVM_N_ONCHIP_EEPROM_ENTRIES; i++)
{
NVM_CRC_t crc;
#if (defined CY_PSOC4) || (defined CY_PSOC6)
if (NVM_OnChipEEPROMEntries[i]->State == NVM_STATE_SAVE_REQUESTED)
{
if (xSemaphoreTake(xSemaphoreOnChipEEPROMLock, ( TickType_t ) 1000) == pdTRUE)
{
EEPROM_write_block(NVM_OnChipEEPROMEntries[i]->Value, NVM_OnChipEEPROMEntries[i]->EE_Address, NVM_OnChipEEPROMEntries[i]->Size);
// Calculate the CRC.
crc = NVM_CRC_init();
crc = NVM_CRC_update(crc, NVM_OnChipEEPROMEntries[i]->Value, NVM_OnChipEEPROMEntries[i]->Size);
crc = NVM_CRC_finalize(crc);
EEPROM_write_block((uint8_t *)&crc, NVM_OnChipEEPROMEntries[i]->EE_CRC_Address, sizeof(uint16_t));
NVM_OnChipEEPROMEntries[i]->State = NVM_STATE_IDLE;
xSemaphoreGive(xSemaphoreOnChipEEPROMLock);
}
}
#endif // (defined CY_PSOC4) || (defined CY_PSOC6)
#if CY_PSOC5
// From the component datasheet:
// "[On_Chip_EEPROM_UpdateTemperature()] updates the store temperature value. This should
// be called anytime the EEPROM is active and temperature may have changed by more than
// 10°C."
if (On_Chip_EEPROM_UpdateTemperature() == CYRET_SUCCESS)
{
if (NVM_OnChipEEPROMEntries[i]->State == NVM_STATE_SAVE_REQUESTED)
{
if (On_Chip_EEPROM_Query() == CYRET_SUCCESS)
{
if (xSemaphoreTake(xSemaphoreOnChipEEPROMLock, ( TickType_t ) 1000) == pdTRUE)
{
EEPROM_write_block(NVM_OnChipEEPROMEntries[i]->Value, NVM_OnChipEEPROMEntries[i]->EE_Address, NVM_OnChipEEPROMEntries[i]->Size);
// Calculate the CRC.
crc = NVM_CRC_init();
crc = NVM_CRC_update(crc, NVM_OnChipEEPROMEntries[i]->Value, NVM_OnChipEEPROMEntries[i]->Size);
crc = NVM_CRC_finalize(crc);
EEPROM_write_block((uint8_t *)&crc, NVM_OnChipEEPROMEntries[i]->EE_CRC_Address, sizeof(uint16_t));
NVM_OnChipEEPROMEntries[i]->State = NVM_STATE_IDLE;
xSemaphoreGive(xSemaphoreOnChipEEPROMLock);
}
}
}
}
else
{
vSerialPutString("ERROR: Couldn't update EEPROM temperature!", 80);
}
#endif // CY_PSOC5
}
}
}
}
//! Flags the given on-chip EEPROM entry to be saved next time the NVM_OnChipEEPROMTask() is run.
void NVM_SaveOnChipEEPROMEntry(NVM_EEPROMEntry_T * const this)
{
if (xSemaphoreTake(xSemaphoreOnChipEEPROMLock, ( TickType_t ) 1000) == pdTRUE)
{
this->State = NVM_STATE_SAVE_REQUESTED;
xSemaphoreGive(xSemaphoreOnChipEEPROMLock);
uint8_t dummy = 0;
xQueueSend(xQueueOnChipEEPROM, &dummy, 0);
}
}
/* Private Functions */

View file

@ -0,0 +1,42 @@
/** \file
* \brief This file contains the public interface to the on-chip EEPROM driver.
*
*/
#ifndef NVM_ONCHIPEEPROM_H
#define NVM_ONCHIPEEPROM_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
#define NVM_ON_CHIP_EEPROM_TASK_STACK_SIZE_in_bytes 256
//! The time between calls to NVM_OnChipEEPROMTask().
#define NVM_ON_CHIP_EEPROM_TASK_RATE_IN_ms 2000
/* Include Files */
/* Public Variables */
extern SemaphoreHandle_t xSemaphoreOnChipEEPROMLock;
//! Handle of the NVM_OnChipEEPROMTask() given when the task was created.
extern TaskHandle_t NVM_OnChipEEPROM_Task_Handle;
extern volatile bool NVM_IsOnChipEEPROMInitialized;
/* Public Functions */
void NVM_InitOnChipEEPROM(void);
void NVM_OnChipEEPROMTask(void * pvParameters);
void NVM_SaveOnChipEEPROMEntry(NVM_EEPROMEntry_T * const this);
/* Inline Functions */
#ifdef __cplusplus
}
#endif
#endif // NVM_ONCHIPEEPROM_H

View file

@ -0,0 +1,63 @@
/*
* __ ________ _____ ______ __
* / //_/_ __/___ _____ _ / ___/____ __ _______________ / ____/___ ____/ /__
* / ,< / / / __ `/ __ `/ \__ \/ __ \/ / / / ___/ ___/ _ \ / / / __ \/ __ / _ \
* / /| | / / / /_/ / /_/ / ___/ / /_/ / /_/ / / / /__/ __/ / /___/ /_/ / /_/ / __/
* /_/ |_|/_/ \__,_/\__, / /____/\____/\__,_/_/ \___/\___/ \____/\____/\__,_/\___/
* /____/
*
* 🃞 THIS FILE IS PART OF THE KTAG SOURCE CODE. Visit https://ktag.clubk.club/ for more. 🃞
*
*/
/** \file
* \brief [Autogenerated] This file defines the OnChip EEPROM entries.
*
* \note AUTOGENERATED: This file was generated automatically on Friday, April 28, 2023 at 11:31:31 AM.
* DO NOT MODIFY THIS FILE MANUALLY!
*/
/* Include Files */
#include "KTag.h"
/* EEPROM Entries */
/** \defgroup NVM_ONCHIP_EEPROM NVM OnChip EEPROM
*
* The OnChip EEPROM is divided into logical "entries", represented by instances of the #NVM_EEPROMEntry_T type.
* At startup, these entries are loaded into their respective RAM copies by NVM_InitOnChipEEPROM(). The application
* then updates the RAM copies directly, and requests that the NVM_OnChipEEPROMTask() save these back to the EEPROM
* when necessary.
* @{ */
static NVM_OnChip_Test_T RAM_OnChip_Test;
static const NVM_OnChip_Test_T DEFAULT_OnChip_Test =
{
//! Test Code 1
.OnChip_Test_1 = UINT16_MAX,
//! Test Code 2
.OnChip_Test_2 = UINT32_MAX,
};
NVM_EEPROMEntry_T NVM_OnChip_Test =
{
//! Size == sizeof(NVM_OnChip_Test_T)
.Size = 6,
.EE_Address = 0,
.EE_CRC_Address = 6,
.Value = (uint8_t *)&RAM_OnChip_Test,
.Default = (uint8_t *)&DEFAULT_OnChip_Test,
.State = NVM_STATE_UNINITIALIZED
};
/** @} */
NVM_EEPROMEntry_T * const NVM_OnChipEEPROMEntries[] =
{
&NVM_OnChip_Test,
};
//! Size of the #NVM_OnChipEEPROMEntries array (i.e. the number of OnChip EEPROM entries).
const uint8_t NVM_N_ONCHIP_EEPROM_ENTRIES = (uint8_t) (sizeof(NVM_OnChipEEPROMEntries) / sizeof(NVM_EEPROMEntry_T *));

View file

@ -0,0 +1,60 @@
/*
* __ ________ _____ ______ __
* / //_/_ __/___ _____ _ / ___/____ __ _______________ / ____/___ ____/ /__
* / ,< / / / __ `/ __ `/ \__ \/ __ \/ / / / ___/ ___/ _ \ / / / __ \/ __ / _ \
* / /| | / / / /_/ / /_/ / ___/ / /_/ / /_/ / / / /__/ __/ / /___/ /_/ / /_/ / __/
* /_/ |_|/_/ \__,_/\__, / /____/\____/\__,_/_/ \___/\___/ \____/\____/\__,_/\___/
* /____/
*
* 🃞 THIS FILE IS PART OF THE KTAG SOURCE CODE. Visit https://ktag.clubk.club/ for more. 🃞
*
*/
/** \file
* \brief [Autogenerated] This file declares the OnChip EEPROM entries.
*
* \note AUTOGENERATED: This file was generated automatically on Friday, April 28, 2023 at 11:31:31 AM.
* DO NOT MODIFY THIS FILE MANUALLY!
*/
#ifndef NVM_ONCHIPEEPROMENTRIES_H
#define NVM_ONCHIPEEPROMENTRIES_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
typedef struct __attribute__((packed))
{
//! Test Code 1
uint16_t OnChip_Test_1;
//! Test Code 2
uint32_t OnChip_Test_2;
} NVM_OnChip_Test_T;
/* Include Files */
/* Public Variables */
extern NVM_EEPROMEntry_T NVM_OnChip_Test;
extern NVM_EEPROMEntry_T * const NVM_OnChipEEPROMEntries[];
extern const uint8_t NVM_N_ONCHIP_EEPROM_ENTRIES;
// Shorthand macros, to save you time.
#define NVM_ONCHIP_TEST_1 (((NVM_OnChip_Test_T*)NVM_OnChip_Test.Value)->OnChip_Test_1)
#define NVM_ONCHIP_TEST_1_ENTRY_PTR (&NVM_OnChip_Test)
#define NVM_ONCHIP_TEST_2 (((NVM_OnChip_Test_T*)NVM_OnChip_Test.Value)->OnChip_Test_2)
#define NVM_ONCHIP_TEST_2_ENTRY_PTR (&NVM_OnChip_Test)
#ifdef __cplusplus
}
#endif
#endif // NVM_ONCHIPEEPROMENTRIES_H

View file

@ -0,0 +1,125 @@
/** \file
* \brief This file contains functions that implement the settings interface for SystemK.
*
*/
/* Include Files */
#include "KTag.h"
SystemKResult_T SETTINGS_get_uint8_t(SystemKSettingID_T id, uint8_t * value)
{
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
switch (id)
{
case SYSTEMK_SETTING_IS_RIGHT_HANDED:
*value = NVM_IS_RIGHT_HANDED;
break;
case SYSTEMK_SETTING_AUDIO_VOLUME:
*value = NVM_VOLUME;
break;
case SYSTEMK_SETTING_TEAMID:
*value = NVM_TEAM_ID;
break;
case SYSTEMK_SETTING_PLAYERID:
*value = NVM_PLAYER_ID;
break;
case SYSTEMK_SETTING_WEAPONID:
*value = NVM_WEAPON_ID;
break;
default:
result = SYSTEMK_RESULT_WRONG_DATATYPE;
break;
}
return result;
}
SystemKResult_T SETTINGS_set_uint8_t(SystemKSettingID_T id, uint8_t value)
{
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
switch (id)
{
case SYSTEMK_SETTING_IS_RIGHT_HANDED:
NVM_IS_RIGHT_HANDED = value;
break;
case SYSTEMK_SETTING_AUDIO_VOLUME:
NVM_VOLUME = value;
break;
case SYSTEMK_SETTING_TEAMID:
NVM_TEAM_ID = value;
break;
case SYSTEMK_SETTING_PLAYERID:
NVM_PLAYER_ID = value;
break;
case SYSTEMK_SETTING_WEAPONID:
NVM_WEAPON_ID = value;
break;
default:
result = SYSTEMK_RESULT_WRONG_DATATYPE;
break;
}
return result;
}
SystemKResult_T SETTINGS_get_uint32_t(SystemKSettingID_T id, uint32_t * value)
{
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
switch (id)
{
case SYSTEMK_SETTING_T_START_GAME_in_ms:
*value = CONFIG_KTAG_T_DEFAULT_START_GAME_in_ms;
break;
default:
result = SYSTEMK_RESULT_WRONG_DATATYPE;
break;
}
return result;
}
SystemKResult_T SETTINGS_set_uint32_t(SystemKSettingID_T id, uint32_t value)
{
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
switch (id)
{
case SYSTEMK_SETTING_T_START_GAME_in_ms:
result = SYSTEMK_RESULT_NOT_IMPLEMENTED;
break;
default:
result = SYSTEMK_RESULT_WRONG_DATATYPE;
break;
}
return result;
}
SystemKResult_T SETTINGS_Save(void)
{
#if (CONFIG__HAS_EXTERNAL_NVM)
NVM_SaveExternalEEPROMEntry(&NVM_Hardware_Settings);
NVM_SaveExternalEEPROMEntry(&NVM_Game_Settings);
#else // CONFIG__HAS_EXTERNAL_NVM
NVM_SaveOnChipEEPROMEntry(&NVM_Hardware_Settings);
NVM_SaveOnChipEEPROMEntry(&NVM_Game_Settings);
#endif // CONFIG__HAS_EXTERNAL_NVM
return SYSTEMK_RESULT_SUCCESS;
}

View file

@ -0,0 +1,93 @@
/* Include Files */
#include "KTag.h"
TaskHandle_t Sample_Task_Handle;
// LED Functionality
static void LED_CoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex );
#define LED_COROUTINE_PRIORITY 0
static const TickType_t Delay_50ms = 50 / portTICK_PERIOD_MS;
static const TickType_t Delay_100ms = 100 / portTICK_PERIOD_MS;
static const TickType_t Delay_600ms = 600 / portTICK_PERIOD_MS;
// Serial Debug Functionality
static void Serial_Debug_CoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex );
#define SERIAL_DEBUG_COROUTINE_PRIORITY 0
static const TickType_t Delay_1s = 1000 / portTICK_PERIOD_MS;
void Sample_Task_Init(void)
{
}
//! Sample task: blinks the LED and sends text out on the UART.
/*!
* \param pvParameters (not used)
* \return None (infinite loop)
*/
void Sample_Task(void * pvParameters)
{
xCoRoutineCreate(LED_CoRoutine, LED_COROUTINE_PRIORITY, 0 );
xCoRoutineCreate(Serial_Debug_CoRoutine, SERIAL_DEBUG_COROUTINE_PRIORITY, 0 );
while (true)
{
vCoRoutineSchedule();
// Delay a bit here so as to not starve the idle task.
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
//! Blinks the LED.
static void LED_CoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{
crSTART( xHandle );
static bool is_startup = false;
while (true)
{
if (is_startup == false)
{
Cy_GPIO_Write(Red_LED_PORT, Red_LED_NUM, 1);
crDELAY(xHandle, Delay_100ms);
Cy_GPIO_Write(Red_LED_PORT, Red_LED_NUM, 0);
crDELAY(xHandle, Delay_50ms);
Cy_GPIO_Write(Red_LED_PORT, Red_LED_NUM, 1);
crDELAY(xHandle, Delay_100ms);
Cy_GPIO_Write(Red_LED_PORT, Red_LED_NUM, 0);
crDELAY(xHandle, Delay_50ms);
Cy_GPIO_Write(Red_LED_PORT, Red_LED_NUM, 1);
crDELAY(xHandle, Delay_100ms);
Cy_GPIO_Write(Red_LED_PORT, Red_LED_NUM, 0);
is_startup = true;
}
crDELAY(xHandle, Delay_600ms);
}
crEND();
}
static void Serial_Debug_CoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{
crSTART( xHandle );
//static uint32_t i = 0;
while (true)
{
//Debug_printf("%lu\n", i++);
//vSerialPutString(" * ", 50);
crDELAY(xHandle, Delay_1s);
}
crEND();
}
/* [] END OF FILE */

View file

@ -0,0 +1,9 @@
#ifndef SAMPLE_TASKS_H
#define SAMPLE_TASKS_H
extern TaskHandle_t Sample_Task_Handle;
void Sample_Task_Init(void);
void Sample_Task(void * pvParameters);
#endif // SAMPLE_TASKS_H

View file

@ -0,0 +1,196 @@
/* Include Files */
#include "KTag.h"
TaskHandle_t Switches_Task_Handle;
#define SWITCHES_TASK_PERIOD_IN_TICKS (100 / portTICK_PERIOD_MS)
//! Continuously pressing a switch for this length of time will be interpreted as a long press.
/*!
* #Duration_Of_Long_Press_in_Ticks must be an integer multiple of #SWITCHES_TASK_PERIOD_IN_TICKS!
*/
static const TickType_t Duration_Of_Long_Press_in_Ticks = (10 * SWITCHES_TASK_PERIOD_IN_TICKS);
#if (defined LIL_BRUV) || (defined LITTLE_BOY_BLUE)
static TickType_t Up_Switch_Time_Pressed_in_Ticks = 0;
static TickType_t Up_Switch_Time_Released_in_Ticks = 0;
static TickType_t Down_Switch_Time_Pressed_in_Ticks = 0;
static TickType_t Down_Switch_Time_Released_in_Ticks = 0;
static TickType_t Forward_Switch_Time_Pressed_in_Ticks = 0;
static TickType_t Forward_Switch_Time_Released_in_Ticks = 0;
static TickType_t Backward_Switch_Time_Pressed_in_Ticks = 0;
static TickType_t Backward_Switch_Time_Released_in_Ticks = 0;
#elif (defined TWENTY20TPC)
static TickType_t Accessory_Switch_Time_Pressed_in_Ticks = 0;
static TickType_t Accessory_Switch_Total_Time_Pressed_in_Ticks = 0;
static TickType_t Accessory_Switch_Time_Released_in_Ticks = 0;
static TickType_t Accessory_Switch_Time_Since_Last_Release_in_Ticks = 0;
#endif // Model
void Switches_Init(void)
{
}
//! Reads the hardware switches and creates press and release events.
/*!
* This is a periodic task--see https://www.freertos.org/vtaskdelayuntil.html.
*/
void Switches_Task(void * pvParameters)
{
TickType_t xLastWakeTime;
// Initialize the xLastWakeTime variable with the current time.
xLastWakeTime = xTaskGetTickCount();
while (true)
{
#if (defined LIL_BRUV) || (defined LITTLE_BOY_BLUE)
if (Cy_GPIO_Read(Pin_Up_PORT, Pin_Up_NUM) == 0)
{
if (Up_Switch_Time_Pressed_in_Ticks == 0)
{
Up_Switch_Time_Released_in_Ticks = 0;
KEvent_T switch_event = {.ID = KEVENT_UP_SWITCH_PRESSED, .Data = &Up_Switch_Time_Released_in_Ticks};
Post_KEvent(&switch_event);
}
else if (Up_Switch_Time_Pressed_in_Ticks == Duration_Of_Long_Press_in_Ticks)
{
KEvent_T switch_event = {.ID = KEVENT_UP_SWITCH_LONG_PRESSED, .Data = &Up_Switch_Time_Pressed_in_Ticks};
Post_KEvent(&switch_event);
}
Up_Switch_Time_Pressed_in_Ticks += SWITCHES_TASK_PERIOD_IN_TICKS;
}
else
{
if (Up_Switch_Time_Released_in_Ticks == 0)
{
Up_Switch_Time_Pressed_in_Ticks = 0;
KEvent_T switch_event = {.ID = KEVENT_UP_SWITCH_RELEASED, .Data = &Up_Switch_Time_Pressed_in_Ticks};
Post_KEvent(&switch_event);
}
Up_Switch_Time_Released_in_Ticks += SWITCHES_TASK_PERIOD_IN_TICKS;
}
if (Cy_GPIO_Read(Pin_Down_PORT, Pin_Down_NUM) == 0)
{
if (Down_Switch_Time_Pressed_in_Ticks == 0)
{
Down_Switch_Time_Released_in_Ticks = 0;
KEvent_T switch_event = {.ID = KEVENT_DOWN_SWITCH_PRESSED, .Data = &Down_Switch_Time_Released_in_Ticks};
Post_KEvent(&switch_event);
}
else if (Down_Switch_Time_Pressed_in_Ticks == Duration_Of_Long_Press_in_Ticks)
{
KEvent_T switch_event = {.ID = KEVENT_DOWN_SWITCH_LONG_PRESSED, .Data = &Down_Switch_Time_Pressed_in_Ticks};
Post_KEvent(&switch_event);
}
Down_Switch_Time_Pressed_in_Ticks += SWITCHES_TASK_PERIOD_IN_TICKS;
}
else
{
if (Down_Switch_Time_Released_in_Ticks == 0)
{
Down_Switch_Time_Pressed_in_Ticks = 0;
KEvent_T switch_event = {.ID = KEVENT_DOWN_SWITCH_RELEASED, .Data = &Down_Switch_Time_Pressed_in_Ticks};
Post_KEvent(&switch_event);
}
Down_Switch_Time_Released_in_Ticks += SWITCHES_TASK_PERIOD_IN_TICKS;
}
if (Cy_GPIO_Read(Pin_Forward_PORT, Pin_Forward_NUM) == 0)
{
if (Forward_Switch_Time_Pressed_in_Ticks == 0)
{
Forward_Switch_Time_Released_in_Ticks = 0;
KEvent_T switch_event = {.ID = KEVENT_FORWARD_SWITCH_PRESSED, .Data = &Forward_Switch_Time_Released_in_Ticks};
Post_KEvent(&switch_event);
}
else if (Forward_Switch_Time_Pressed_in_Ticks == Duration_Of_Long_Press_in_Ticks)
{
KEvent_T switch_event = {.ID = KEVENT_FORWARD_SWITCH_LONG_PRESSED, .Data = &Forward_Switch_Time_Pressed_in_Ticks};
Post_KEvent(&switch_event);
}
Forward_Switch_Time_Pressed_in_Ticks += SWITCHES_TASK_PERIOD_IN_TICKS;
}
else
{
if (Forward_Switch_Time_Released_in_Ticks == 0)
{
Forward_Switch_Time_Pressed_in_Ticks = 0;
KEvent_T switch_event = {.ID = KEVENT_FORWARD_SWITCH_RELEASED, .Data = &Forward_Switch_Time_Pressed_in_Ticks};
Post_KEvent(&switch_event);
}
Forward_Switch_Time_Released_in_Ticks += SWITCHES_TASK_PERIOD_IN_TICKS;
}
if (Cy_GPIO_Read(Pin_Backward_PORT, Pin_Backward_NUM) == 0)
{
if (Backward_Switch_Time_Pressed_in_Ticks == 0)
{
Backward_Switch_Time_Released_in_Ticks = 0;
KEvent_T switch_event = {.ID = KEVENT_BACKWARD_SWITCH_PRESSED, .Data = &Backward_Switch_Time_Released_in_Ticks};
Post_KEvent(&switch_event);
}
else if (Backward_Switch_Time_Pressed_in_Ticks == Duration_Of_Long_Press_in_Ticks)
{
KEvent_T switch_event = {.ID = KEVENT_BACKWARD_SWITCH_LONG_PRESSED, .Data = &Backward_Switch_Time_Pressed_in_Ticks};
Post_KEvent(&switch_event);
}
Backward_Switch_Time_Pressed_in_Ticks += SWITCHES_TASK_PERIOD_IN_TICKS;
}
else
{
if (Backward_Switch_Time_Released_in_Ticks == 0)
{
Backward_Switch_Time_Pressed_in_Ticks = 0;
KEvent_T switch_event = {.ID = KEVENT_BACKWARD_SWITCH_RELEASED, .Data = &Backward_Switch_Time_Pressed_in_Ticks};
Post_KEvent(&switch_event);
}
Backward_Switch_Time_Released_in_Ticks += SWITCHES_TASK_PERIOD_IN_TICKS;
}
#elif (defined TWENTY20TPC)
// Use the Remote Trigger pin as the Accessory input, since we never got around to using remote triggers.
if (Cy_GPIO_Read(Pin_Remote_Trigger_PORT, Pin_Remote_Trigger_NUM) == 0)
{
if (Accessory_Switch_Time_Pressed_in_Ticks == 0)
{
Accessory_Switch_Time_Since_Last_Release_in_Ticks = Accessory_Switch_Time_Released_in_Ticks;
KEvent_T switch_event = {.ID = KEVENT_ACCESSORY_SWITCH_PRESSED, .Data = (void *) pdTICKS_TO_MS(Accessory_Switch_Time_Since_Last_Release_in_Ticks)};
Post_KEvent(&switch_event);
Accessory_Switch_Time_Released_in_Ticks = 0;
}
if ((UINT32_MAX - Accessory_Switch_Time_Pressed_in_Ticks) > SWITCHES_TASK_PERIOD_IN_TICKS)
{
Accessory_Switch_Time_Pressed_in_Ticks += SWITCHES_TASK_PERIOD_IN_TICKS;
}
}
else
{
if (Accessory_Switch_Time_Released_in_Ticks == 0)
{
Accessory_Switch_Total_Time_Pressed_in_Ticks = Accessory_Switch_Time_Pressed_in_Ticks;
KEvent_T switch_event = {.ID = KEVENT_ACCESSORY_SWITCH_RELEASED, .Data = (void *) pdTICKS_TO_MS(Accessory_Switch_Total_Time_Pressed_in_Ticks)};
Post_KEvent(&switch_event);
Accessory_Switch_Time_Pressed_in_Ticks = 0;
}
if ((UINT32_MAX - Accessory_Switch_Time_Released_in_Ticks) > SWITCHES_TASK_PERIOD_IN_TICKS)
{
Accessory_Switch_Time_Released_in_Ticks += SWITCHES_TASK_PERIOD_IN_TICKS;
}
}
#endif // Model
// Wait for the next cycle.
vTaskDelayUntil(&xLastWakeTime, SWITCHES_TASK_PERIOD_IN_TICKS);
}
}

View file

@ -0,0 +1,9 @@
#ifndef SWITCHES_H
#define SWITCHES_H
extern TaskHandle_t Switches_Task_Handle;
void Switches_Init(void);
void Switches_Task(void * pvParameters);
#endif // SWITCHES_H

@ -0,0 +1 @@
Subproject commit 4fe072f2d3280b19aa53e197bd22ec44b174ff88

View file

@ -0,0 +1,582 @@
/* Include Files */
#include "KTag.h"
TaskHandle_t Tag_Sensors_Task_Handle;
//#define DEBUG_TAG_SENSORS
#define MAX_RX_PULSES (2 * MAX_PULSES)
typedef enum
{
FALLING_EDGE,
RISING_EDGE
} EdgeDirection_T;
static volatile uint32_t LocalIncomingPulseDurations[MAX_RX_PULSES];
static volatile uint32_t RemoteIncomingPulseDurations[MAX_RX_PULSES];
static volatile uint16_t LocalPulseIndex = 0;
static volatile uint16_t RemotePulseIndex = 0;
static volatile uint16_t NumberOfLocalIncomingPulses = 0;
static volatile uint16_t NumberOfRemoteIncomingPulses = 0;
static volatile TagSensorLocation_T LocalActiveSensor = TAG_SENSOR_NONE;
static uint32_t LocalProcessingPulseDurations[MAX_RX_PULSES];
static uint32_t RemoteProcessingPulseDurations[MAX_RX_PULSES];
static uint16_t NumberOfLocalProcessingPulses = 0;
static uint16_t NumberOfRemoteProcessingPulses = 0;
static TimedPulseTrain_T LocalProcessingPulses;
static TimedPulseTrain_T RemoteProcessingPulses;
static TagSensorLocation_T LocalProcessingSensor = TAG_SENSOR_NONE;
static volatile EdgeDirection_T LocalExpectedEdgeDirection = FALLING_EDGE;
static volatile EdgeDirection_T RemoteExpectedEdgeDirection = FALLING_EDGE;
void On_Forward_Tag_Sensor_Rising_Edge();
void On_Forward_Tag_Sensor_Falling_Edge();
void On_Left_Tag_Sensor_Rising_Edge();
void On_Left_Tag_Sensor_Falling_Edge();
void On_Right_Tag_Sensor_Rising_Edge();
void On_Right_Tag_Sensor_Falling_Edge();
void On_Remote_Tag_Sensor_Rising_Edge();
void On_Remote_Tag_Sensor_Falling_Edge();
void On_Local_Tag_Sensor_Bit_Stream_Timer();
void On_Remote_Tag_Sensor_Bit_Stream_Timer();
QueueHandle_t xQueueTagSensors;
#ifdef DEBUG_TAG_SENSORS
static char8 buffer[30];
#endif // DEBUG_TAG_SENSORS
inline static void AppendLocalPulse(uint32_t duration)
{
LocalIncomingPulseDurations[LocalPulseIndex] = duration;
if (LocalPulseIndex < (MAX_RX_PULSES - 1))
{
LocalPulseIndex++;
}
}
inline static void AppendRemotePulse(uint32_t duration)
{
RemoteIncomingPulseDurations[RemotePulseIndex] = duration;
if (RemotePulseIndex < (MAX_RX_PULSES - 1))
{
RemotePulseIndex++;
}
}
inline static void EnableAllLocalEdgeISRs(void)
{
NVIC_EnableIRQ(Forward_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
NVIC_EnableIRQ(Forward_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
NVIC_EnableIRQ(Left_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
NVIC_EnableIRQ(Left_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
NVIC_EnableIRQ(Right_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
NVIC_EnableIRQ(Right_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
}
inline static void EnableAllRemoteEdgeISRs(void)
{
NVIC_EnableIRQ(Remote_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
NVIC_EnableIRQ(Remote_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
}
inline static void DisableAllLocalRisingEdgeISRs(void)
{
NVIC_DisableIRQ(Forward_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
NVIC_DisableIRQ(Left_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
NVIC_DisableIRQ(Right_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
}
inline static void DisableAllRemoteRisingEdgeISRs(void)
{
NVIC_DisableIRQ(Remote_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
}
inline static void DisableAllLocalFallingEdgeISRs(void)
{
NVIC_DisableIRQ(Forward_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
NVIC_DisableIRQ(Left_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
NVIC_DisableIRQ(Right_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
}
inline static void DisableAllRemoteFallingEdgeISRs(void)
{
NVIC_DisableIRQ(Remote_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
}
inline static void DisableAllLocalEdgeISRs(void)
{
DisableAllLocalRisingEdgeISRs();
DisableAllLocalFallingEdgeISRs();
}
inline static void DisableAllRemoteEdgeISRs(void)
{
DisableAllRemoteRisingEdgeISRs();
DisableAllRemoteFallingEdgeISRs();
}
inline static void ClearAllPendingLocalEdgeISRs(void)
{
NVIC_ClearPendingIRQ(Forward_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
NVIC_ClearPendingIRQ(Forward_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
NVIC_ClearPendingIRQ(Left_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
NVIC_ClearPendingIRQ(Left_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
NVIC_ClearPendingIRQ(Right_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
NVIC_ClearPendingIRQ(Right_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
}
inline static void ClearAllPendingRemoteEdgeISRs(void)
{
NVIC_ClearPendingIRQ(Remote_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
NVIC_ClearPendingIRQ(Remote_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
}
void Tag_Sensors_Init(void)
{
// Register the Local ISRs.
Cy_SysInt_Init(&Forward_Tag_Sensor_Rising_Edge_ISR_cfg, On_Forward_Tag_Sensor_Rising_Edge);
Cy_SysInt_Init(&Forward_Tag_Sensor_Falling_Edge_ISR_cfg, On_Forward_Tag_Sensor_Falling_Edge);
Cy_SysInt_Init(&Left_Tag_Sensor_Rising_Edge_ISR_cfg, On_Left_Tag_Sensor_Rising_Edge);
Cy_SysInt_Init(&Left_Tag_Sensor_Falling_Edge_ISR_cfg, On_Left_Tag_Sensor_Falling_Edge);
Cy_SysInt_Init(&Right_Tag_Sensor_Rising_Edge_ISR_cfg, On_Right_Tag_Sensor_Rising_Edge);
Cy_SysInt_Init(&Right_Tag_Sensor_Falling_Edge_ISR_cfg, On_Right_Tag_Sensor_Falling_Edge);
Cy_SysInt_Init(&Local_Tag_Sensor_Bit_Stream_Timer_Interrupt_cfg, On_Local_Tag_Sensor_Bit_Stream_Timer);
// Register the Remote ISRs.
Cy_SysInt_Init(&Remote_Tag_Sensor_Rising_Edge_ISR_cfg, On_Remote_Tag_Sensor_Rising_Edge);
Cy_SysInt_Init(&Remote_Tag_Sensor_Falling_Edge_ISR_cfg, On_Remote_Tag_Sensor_Falling_Edge);
Cy_SysInt_Init(&Remote_Tag_Sensor_Bit_Stream_Timer_Interrupt_cfg, On_Remote_Tag_Sensor_Bit_Stream_Timer);
// Enable the forward, left, right, and remote sensors.
Tag_Sensor_Register_Write(0xFF - 0x0F);
xQueueTagSensors = xQueueCreate(5, sizeof(TagSensorsAction_T));
// Enable the timers.
NVIC_EnableIRQ(Local_Tag_Sensor_Bit_Stream_Timer_Interrupt_cfg.intrSrc);
NVIC_EnableIRQ(Remote_Tag_Sensor_Bit_Stream_Timer_Interrupt_cfg.intrSrc);
// Enable the sensors.
EnableAllLocalEdgeISRs();
EnableAllRemoteEdgeISRs();
}
void Tag_Sensors_Task(void * pvParameters)
{
portBASE_TYPE xStatus;
while (true)
{
TagSensorsAction_T action;
xStatus = xQueueReceive(xQueueTagSensors, &action, 0);
if (xStatus == pdPASS)
{
switch (action)
{
case TAG_SENSOR_PROCESS_LOCAL_BUFFER:
{
for (uint8_t i = 0; i < NumberOfLocalIncomingPulses; i++)
{
LocalProcessingPulseDurations[i] = LocalIncomingPulseDurations[i];
}
NumberOfLocalProcessingPulses = NumberOfLocalIncomingPulses;
NumberOfLocalIncomingPulses = 0;
LocalProcessingSensor = LocalActiveSensor;
LocalActiveSensor = TAG_SENSOR_NONE;
EnableAllLocalEdgeISRs();
#ifdef DEBUG_TAG_SENSORS
COMM_Console_Print_String("\n");
switch (LocalProcessingSensor)
{
case TAG_SENSOR_FORWARD:
COMM_Console_Print_String("Tag Rx'd FORWARD\n");
vTaskDelay(pdMS_TO_TICKS(10));
break;
case TAG_SENSOR_LEFT:
COMM_Console_Print_String("Tag Rx'd LEFT\n");
vTaskDelay(pdMS_TO_TICKS(10));
break;
case TAG_SENSOR_RIGHT:
COMM_Console_Print_String("Tag Rx'd RIGHT\n");
vTaskDelay(pdMS_TO_TICKS(10));
break;
default:
case TAG_SENSOR_REMOTE:
case TAG_SENSOR_NONE:
break;
}
for (uint_fast16_t i = 0; i < NumberOfLocalProcessingPulses; i++)
{
// Even pulses are marks; odd pulses are spaces.
if ((i % 2) == 0)
{
COMM_Console_Print_String("{.symbol = MARK, .time = ");
sprintf(buffer, "%lu}, // %d\n", LocalProcessingPulseDurations[i], i);
COMM_Console_Print_String(buffer);
vTaskDelay(pdMS_TO_TICKS(10));
}
// A falling edge is the end of space.
else
{
COMM_Console_Print_String("{.symbol = SPACE, .time = ");
sprintf(buffer, "%lu}, // %d\n", LocalProcessingPulseDurations[i], i);
COMM_Console_Print_String(buffer);
vTaskDelay(pdMS_TO_TICKS(10));
}
}
#endif // DEBUG_TAG_SENSORS
LocalProcessingPulses.count = NumberOfLocalProcessingPulses;
for (uint_fast16_t i = 0; (i < NumberOfLocalProcessingPulses) && (i < MAX_RX_PULSES); i++)
{
if ((i % 2) == 0)
{
LocalProcessingPulses.bitstream[i].symbol = MARK;
}
else
{
LocalProcessingPulses.bitstream[i].symbol = SPACE;
}
LocalProcessingPulses.bitstream[i].duration = LocalProcessingPulseDurations[i];
}
LocalProcessingPulses.bitstream[NumberOfLocalProcessingPulses].duration = LAST_PULSE;
LocalProcessingPulses.receiver = LocalProcessingSensor;
DecodedPacket_T * result = PROTOCOLS_MaybeDecodePacket(&LocalProcessingPulses);
if (result != NULL)
{
if (result->Generic.type == DECODED_PACKET_TYPE_TAG_RECEIVED)
{
KEvent_T tag_received_event = {.ID = KEVENT_TAG_RECEIVED, .Data = result};
Post_KEvent(&tag_received_event);
}
else if (result->Generic.type == DECODED_PACKET_TYPE_COMMAND_RECEIVED)
{
KEvent_T command_received_event = {.ID = KEVENT_COMMAND_RECEIVED, .Data = result};
Post_KEvent(&command_received_event);
}
}
else
{
KEvent_T near_miss_event = {.ID = KEVENT_NEAR_MISS, .Data = NULL};
Post_KEvent(&near_miss_event);
}
}
break;
case TAG_SENSOR_PROCESS_REMOTE_BUFFER:
{
for (uint8_t i = 0; i < NumberOfRemoteIncomingPulses; i++)
{
RemoteProcessingPulseDurations[i] = RemoteIncomingPulseDurations[i];
}
NumberOfRemoteProcessingPulses = NumberOfRemoteIncomingPulses;
NumberOfRemoteIncomingPulses = 0;
EnableAllRemoteEdgeISRs();
#ifdef DEBUG_TAG_SENSORS
COMM_Console_Print_String("\n");
COMM_Console_Print_String("Tag Rx'd REMOTE\n");
vTaskDelay(pdMS_TO_TICKS(10));
for (uint_fast16_t i = 0; i < NumberOfRemoteProcessingPulses; i++)
{
// Even pulses are marks; odd pulses are spaces.
if ((i % 2) == 0)
{
COMM_Console_Print_String("{.symbol = MARK, .time = ");
sprintf(buffer, "%lu}, // %d\n", RemoteProcessingPulseDurations[i], i);
COMM_Console_Print_String(buffer);
vTaskDelay(pdMS_TO_TICKS(10));
}
// A falling edge is the end of space.
else
{
COMM_Console_Print_String("{.symbol = SPACE, .time = ");
sprintf(buffer, "%lu}, // %d\n", RemoteProcessingPulseDurations[i], i);
COMM_Console_Print_String(buffer);
vTaskDelay(pdMS_TO_TICKS(10));
}
}
#endif // DEBUG_TAG_SENSORS
RemoteProcessingPulses.count = NumberOfRemoteProcessingPulses;
for (uint_fast16_t i = 0; (i < NumberOfRemoteProcessingPulses) && (i < MAX_RX_PULSES); i++)
{
if ((i % 2) == 0)
{
RemoteProcessingPulses.bitstream[i].symbol = MARK;
}
else
{
RemoteProcessingPulses.bitstream[i].symbol = SPACE;
}
RemoteProcessingPulses.bitstream[i].duration = RemoteProcessingPulseDurations[i];
}
RemoteProcessingPulses.bitstream[NumberOfRemoteProcessingPulses].duration = LAST_PULSE;
RemoteProcessingPulses.receiver = TAG_SENSOR_REMOTE;
DecodedPacket_T * result = PROTOCOLS_MaybeDecodePacket(&RemoteProcessingPulses);
if (result != NULL)
{
if (result->Generic.type == DECODED_PACKET_TYPE_TAG_RECEIVED)
{
KEvent_T tag_received_event = {.ID = KEVENT_TAG_RECEIVED, .Data = result};
Post_KEvent(&tag_received_event);
}
else if (result->Generic.type == DECODED_PACKET_TYPE_COMMAND_RECEIVED)
{
KEvent_T command_received_event = {.ID = KEVENT_COMMAND_RECEIVED, .Data = result};
Post_KEvent(&command_received_event);
}
}
else
{
KEvent_T near_miss_event = {.ID = KEVENT_NEAR_MISS, .Data = NULL};
Post_KEvent(&near_miss_event);
}
}
break;
default:
break;
}
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
// A rising edge means the IR carrier frequency is no longer detected.
void On_Forward_Tag_Sensor_Rising_Edge()
{
uint32_t counter = Local_Tag_Sensor_Bit_Stream_Timer_GetCounter();
if (LocalActiveSensor == TAG_SENSOR_FORWARD)
{
if (LocalExpectedEdgeDirection == RISING_EDGE)
{
Local_Tag_Sensor_Bit_Stream_Timer_SetCounter(0);
NVIC_ClearPendingIRQ(Forward_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
AppendLocalPulse(counter);
LocalExpectedEdgeDirection = FALLING_EDGE;
}
}
}
// A falling edge means the IR carrier frequency has been detected.
void On_Forward_Tag_Sensor_Falling_Edge()
{
uint32_t counter = Local_Tag_Sensor_Bit_Stream_Timer_GetCounter();
if ((LocalActiveSensor == TAG_SENSOR_FORWARD) || (LocalActiveSensor == TAG_SENSOR_NONE))
{
if (LocalExpectedEdgeDirection == FALLING_EDGE)
{
Local_Tag_Sensor_Bit_Stream_Timer_SetCounter(0);
NVIC_ClearPendingIRQ(Forward_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
if (LocalPulseIndex == 0)
{
Local_Tag_Sensor_Bit_Stream_Timer_Start();
LocalActiveSensor = TAG_SENSOR_FORWARD;
}
else
{
AppendLocalPulse(counter);
}
LocalExpectedEdgeDirection = RISING_EDGE;
}
}
}
// A rising edge means the IR carrier frequency is no longer detected.
void On_Left_Tag_Sensor_Rising_Edge()
{
uint32_t counter = Local_Tag_Sensor_Bit_Stream_Timer_GetCounter();
if (LocalActiveSensor == TAG_SENSOR_LEFT)
{
if (LocalExpectedEdgeDirection == RISING_EDGE)
{
Local_Tag_Sensor_Bit_Stream_Timer_SetCounter(0);
NVIC_ClearPendingIRQ(Left_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
AppendLocalPulse(counter);
LocalExpectedEdgeDirection = FALLING_EDGE;
}
}
}
// A falling edge means the IR carrier frequency has been detected.
void On_Left_Tag_Sensor_Falling_Edge()
{
uint32_t counter = Local_Tag_Sensor_Bit_Stream_Timer_GetCounter();
if ((LocalActiveSensor == TAG_SENSOR_LEFT) || (LocalActiveSensor == TAG_SENSOR_NONE))
{
if (LocalExpectedEdgeDirection == FALLING_EDGE)
{
Local_Tag_Sensor_Bit_Stream_Timer_SetCounter(0);
NVIC_ClearPendingIRQ(Left_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
if (LocalPulseIndex == 0)
{
Local_Tag_Sensor_Bit_Stream_Timer_Start();
LocalActiveSensor = TAG_SENSOR_LEFT;
}
else
{
AppendLocalPulse(counter);
}
LocalExpectedEdgeDirection = RISING_EDGE;
}
}
}
// A rising edge means the IR carrier frequency is no longer detected.
void On_Right_Tag_Sensor_Rising_Edge()
{
uint32_t counter = Local_Tag_Sensor_Bit_Stream_Timer_GetCounter();
if (LocalActiveSensor == TAG_SENSOR_RIGHT)
{
if (LocalExpectedEdgeDirection == RISING_EDGE)
{
Local_Tag_Sensor_Bit_Stream_Timer_SetCounter(0);
NVIC_ClearPendingIRQ(Right_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
AppendLocalPulse(counter);
LocalExpectedEdgeDirection = FALLING_EDGE;
}
}
}
// A falling edge means the IR carrier frequency has been detected.
void On_Right_Tag_Sensor_Falling_Edge()
{
uint32_t counter = Local_Tag_Sensor_Bit_Stream_Timer_GetCounter();
if ((LocalActiveSensor == TAG_SENSOR_RIGHT) || (LocalActiveSensor == TAG_SENSOR_NONE))
{
if (LocalExpectedEdgeDirection == FALLING_EDGE)
{
Local_Tag_Sensor_Bit_Stream_Timer_SetCounter(0);
NVIC_ClearPendingIRQ(Left_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
if (LocalPulseIndex == 0)
{
Local_Tag_Sensor_Bit_Stream_Timer_Start();
LocalActiveSensor = TAG_SENSOR_RIGHT;
}
else
{
AppendLocalPulse(counter);
}
LocalExpectedEdgeDirection = RISING_EDGE;
}
}
}
// A rising edge means the IR carrier frequency is no longer detected.
void On_Remote_Tag_Sensor_Rising_Edge()
{
uint32_t counter = Remote_Tag_Sensor_Bit_Stream_Timer_GetCounter();
if (RemoteExpectedEdgeDirection == RISING_EDGE)
{
Remote_Tag_Sensor_Bit_Stream_Timer_SetCounter(0);
NVIC_ClearPendingIRQ(Remote_Tag_Sensor_Rising_Edge_ISR_cfg.intrSrc);
AppendRemotePulse(counter);
RemoteExpectedEdgeDirection = FALLING_EDGE;
}
}
// A falling edge means the IR carrier frequency has been detected.
void On_Remote_Tag_Sensor_Falling_Edge()
{
uint32_t counter = Remote_Tag_Sensor_Bit_Stream_Timer_GetCounter();
if (RemoteExpectedEdgeDirection == FALLING_EDGE)
{
Remote_Tag_Sensor_Bit_Stream_Timer_SetCounter(0);
NVIC_ClearPendingIRQ(Remote_Tag_Sensor_Falling_Edge_ISR_cfg.intrSrc);
if (RemotePulseIndex == 0)
{
Remote_Tag_Sensor_Bit_Stream_Timer_Start();
}
else
{
AppendRemotePulse(counter);
}
RemoteExpectedEdgeDirection = RISING_EDGE;
}
}
void On_Local_Tag_Sensor_Bit_Stream_Timer()
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
// Read and clear the interrupt status.
uint32_t status = Local_Tag_Sensor_Bit_Stream_Timer_GetInterruptStatus();
Local_Tag_Sensor_Bit_Stream_Timer_ClearInterrupt(CY_TCPWM_INT_ON_TC);
if (status & CY_TCPWM_INT_ON_TC)
{
// The timer expired.
Local_Tag_Sensor_Bit_Stream_Timer_TriggerStop();
Local_Tag_Sensor_Bit_Stream_Timer_SetCounter(0);
NumberOfLocalIncomingPulses = LocalPulseIndex;
LocalPulseIndex = 0;
DisableAllLocalEdgeISRs();
LocalExpectedEdgeDirection = FALLING_EDGE;
const TagSensorsAction_T action = TAG_SENSOR_PROCESS_LOCAL_BUFFER;
xQueueSendFromISR(xQueueTagSensors, &action, &xHigherPriorityTaskWoken);
}
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void On_Remote_Tag_Sensor_Bit_Stream_Timer()
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
// Read and clear the interrupt status.
uint32_t status = Remote_Tag_Sensor_Bit_Stream_Timer_GetInterruptStatus();
Remote_Tag_Sensor_Bit_Stream_Timer_ClearInterrupt(CY_TCPWM_INT_ON_TC);
if (status & CY_TCPWM_INT_ON_TC)
{
// The timer expired.
Remote_Tag_Sensor_Bit_Stream_Timer_TriggerStop();
Remote_Tag_Sensor_Bit_Stream_Timer_SetCounter(0);
NumberOfRemoteIncomingPulses = RemotePulseIndex;
RemotePulseIndex = 0;
DisableAllRemoteEdgeISRs();
RemoteExpectedEdgeDirection = FALLING_EDGE;
const TagSensorsAction_T action = TAG_SENSOR_PROCESS_REMOTE_BUFFER;
xQueueSendFromISR(xQueueTagSensors, &action, &xHigherPriorityTaskWoken);
}
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

View file

@ -0,0 +1,16 @@
#ifndef TAG_SENSORS_H
#define TAG_SENSORS_H
extern TaskHandle_t Tag_Sensors_Task_Handle;
void Tag_Sensors_Init(void);
void Tag_Sensors_Task(void * pvParameters);
typedef enum
{
TAG_SENSOR_PROCESS_LOCAL_BUFFER,
TAG_SENSOR_PROCESS_REMOTE_BUFFER
} TagSensorsAction_T;
#endif // TAG_SENSORS_H

Binary file not shown.

View file

@ -0,0 +1,41 @@
/** \dir UTIL
*
* \brief Utility Software
*
* This directory/namespace contains miscellaneous utility functions.
*
*/
/** \file
* \brief This file defines the interface to the UTIL package used by this software.
*
* This file should be included by any file outside the UTIL package wishing to make use
* of any of the UTIL functionality.
*
* \note As always, <project.h> and <CONFIG.h> should be included <I>before</I> this file.
*/
#ifndef UTIL_H
#define UTIL_H
#ifdef __cplusplus
extern "C" {
#endif
/* Preprocessor and Type Definitions */
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
/* Include Files */
#include "UTIL_CircularBuffer.h"
/* Public Variables */
/* Public Functions */
#ifdef __cplusplus
}
#endif
#endif // UTIL_H

View file

@ -0,0 +1,160 @@
/** \file
* \brief This file implements a circular buffer.
*
*/
/* Include Files */
#include <stdbool.h>
#include <stdint.h>
#include <project.h>
#include "FreeRTOS.h"
#include "task.h"
#include "UTIL_CircularBuffer.h"
/* Local Definitions */
/* Public Functions */
/* Public Data */
/* ******************* Module Level Information ********************* */
/* Private Function Prototypes */
/* Private Data */
/* Module Level Code */
//! Increments a value using modular arithmetic.
/*!
* \param value the value to be incremented
* \param modulus the modulus to use
* \return (value + 1) modulo <i>modulus</i>
*/
inline uint16_t ModuloIncrement(const uint16_t value, const uint16_t modulus)
{
uint16_t nextValue = value + 1;
if (nextValue >= modulus)
{
nextValue = 0;
}
return (nextValue);
}
//! Initializes the circular buffer, and clears the flags.
/*!
* \param this pointer to the circular buffer in question
* \param buffer pointer to the memory allocated to store this circular buffer
* \param size size (in bytes) of this circular buffer
*/
void UTIL_InitCircularBuffer(UTIL_CircularBuffer_T * const this, uint8_t * buffer, uint16_t size)
{
this->buffer = buffer;
this->size = size;
this->head = 0;
this->tail = 0;
this->count = 0;
// Note that there is no need to zero out the actual buffer,
// since it will be overwritten when values are added.
}
//! Adds a value to the end of the circular buffer.
/*!
* If the buffer is full, the value is dropped and the overflow flag is set.
*
* \param this pointer to the circular buffer in question
* \param value the value to be added to the buffer
*/
UTIL_CircularBufferResult_T UTIL_PushToCircularBuffer(UTIL_CircularBuffer_T * const this, uint8_t value)
{
UTIL_CircularBufferResult_T result = UTIL_CIRCULARBUFFERRESULT_UNKNOWN;
//UBaseType_t uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
portDISABLE_INTERRUPTS();
if (this->count < this->size)
{
this->buffer[this->head] = value;
this->head = ModuloIncrement(this->head, this->size);
this->count++;
result = UTIL_CIRCULARBUFFERRESULT_SUCCESS;
}
else
{
result = UTIL_CIRCULARBUFFERRESULT_ERROR_OVERFLOW;
}
portENABLE_INTERRUPTS();
//taskEXIT_CRITICAL_FROM_ISR(uxSavedInterruptStatus);
return result;
}
//! Retrieves a value from the beginning of the circular buffer (FIFO).
/*!
* If the buffer is empty, zero is returned and the underflow flag is set.
*
* \param this pointer to the circular buffer in question
* \return the oldest value in the buffer
*/
UTIL_CircularBufferResult_T UTIL_PopFromCircularBuffer(UTIL_CircularBuffer_T * const this, uint8_t * const value)
{
UTIL_CircularBufferResult_T result = UTIL_CIRCULARBUFFERRESULT_UNKNOWN;
//UBaseType_t uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
portDISABLE_INTERRUPTS();
if (this->count > 0)
{
*value = this->buffer[this->tail];
this->tail = ModuloIncrement(this->tail, this->size);
this->count--;
result = UTIL_CIRCULARBUFFERRESULT_SUCCESS;
}
else
{
*value = 0;
result = UTIL_CIRCULARBUFFERRESULT_ERROR_UNDERFLOW;
}
portENABLE_INTERRUPTS();
//taskEXIT_CRITICAL_FROM_ISR(uxSavedInterruptStatus);
return result;
}
//! Determines whether or not the circular buffer is empty.
/*!
* \param this pointer to the circular buffer in question
* \return true if the buffer is empty; false otherwise
*/
bool UTIL_IsCircularBufferEmpty(UTIL_CircularBuffer_T * const this)
{
bool result = false;
if (this->count == 0)
{
result = true;
}
return result;
}
//! Determines whether or not the circular buffer is full.
/*!
* \param this pointer to the circular buffer in question
* \return true if the buffer is full; false otherwise
*/
bool UTIL_IsCircularBufferFull(UTIL_CircularBuffer_T * const this)
{
bool result = false;
if (this->count >= this->size)
{
result = true;
}
return result;
}

View file

@ -0,0 +1,41 @@
/** \file
* \brief This file contains definitions for a circular buffer.
*
*/
#ifndef UTIL_CIRCULARBUFFER_H
#define UTIL_CIRCULARBUFFER_H
/* Definitions */
typedef enum
{
//! The result could not be determined.
UTIL_CIRCULARBUFFERRESULT_UNKNOWN = 0,
//! The requested action completed successfully.
UTIL_CIRCULARBUFFERRESULT_SUCCESS,
//! There is no more room in the buffer.
UTIL_CIRCULARBUFFERRESULT_ERROR_OVERFLOW,
//! There is no data left in the buffer.
UTIL_CIRCULARBUFFERRESULT_ERROR_UNDERFLOW
} UTIL_CircularBufferResult_T;
//! Circular buffer data structure.
typedef struct
{
uint8_t * buffer;
uint16_t size;
volatile uint16_t head;
volatile uint16_t tail;
volatile uint16_t count;
} UTIL_CircularBuffer_T;
/* Function Declarations */
void UTIL_InitCircularBuffer(UTIL_CircularBuffer_T * const this, uint8_t * buffer, uint16_t size);
UTIL_CircularBufferResult_T UTIL_PushToCircularBuffer(UTIL_CircularBuffer_T * const this, uint8_t value);
UTIL_CircularBufferResult_T UTIL_PopFromCircularBuffer(UTIL_CircularBuffer_T * const this, uint8_t * const value);
bool UTIL_IsCircularBufferEmpty(UTIL_CircularBuffer_T * const this);
bool UTIL_IsCircularBufferFull(UTIL_CircularBuffer_T * const this);
#endif // UTIL_CIRCULARBUFFER_H

View file

@ -0,0 +1,218 @@
/***************************************************************************//**
* \file cy8c6xx7_cm0plus.icf
* \version 2.20
*
* 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.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/*###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__ = 0x08024000;
/* Flash */
define symbol __ICFEDIT_region_IROM1_start__ = 0x10000000;
define symbol __ICFEDIT_region_IROM1_end__ = 0x10080000;
/* 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__ = 0x0400;
} 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,402 @@
/***************************************************************************//**
* \file cy8c6xx7_cm0plus.ld
* \version 2.20
*
* 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.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
ENTRY(Reset_Handler)
/* Force symbol to be entered in the output file as an undefined symbol. Doing
* this may, for example, trigger linking of additional modules from standard
* libraries. You may list several symbols for each EXTERN, and you may use
* EXTERN multiple times. This command has the same effect as the -u command-line
* option.
*/
EXTERN(Reset_Handler)
/* 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 = 0x24000
flash (rx) : ORIGIN = 0x10000000, LENGTH = 0x80000
/* 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 = 0x4000 /* 16 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*))
} > flash
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > flash
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > flash
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_psoc6_01_cm0plus.S */
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
/* Copy interrupt vectors from flash to RAM */
LONG (__Vectors) /* From */
LONG (__ram_vectors_start__) /* To */
LONG (__Vectors_End - __Vectors) /* Size */
/* Copy data section to RAM */
LONG (__etext) /* From */
LONG (__data_start__) /* To */
LONG (__data_end__ - __data_start__) /* Size */
__copy_table_end__ = .;
} > flash
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_psoc6_01_cm0plus.S */
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
__zero_table_end__ = .;
} > flash
__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,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.20
;*
;* 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.
;* You may use this file only in accordance with the license, terms, conditions,
;* disclaimers, and limitations in the end user license agreement accompanying
;* the software package with which this file was provided.
;******************************************************************************/
; 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
#define RAM_START 0x08000000
#define RAM_SIZE 0x00024000
; Flash
#define FLASH_START 0x10000000
#define FLASH_SIZE 0x00080000
; 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_FLASH 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)
}
ER_RAM_DATA +0
{
* (.cy_ramfunc)
.ANY (+RW, +ZI)
}
; Place variables in the section that should not be initialized during the
; device startup.
ER_RAM_NOINIT_DATA +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,219 @@
/***************************************************************************//**
* \file cy8c6xx7_cm4_dual.icf
* \version 2.20
*
* 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.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
/*###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__ = 0x08024000;
define symbol __ICFEDIT_region_IRAM1_end__ = 0x08047800;
/* Flash */
define symbol __ICFEDIT_region_IROM1_start__ = 0x10080000;
define symbol __ICFEDIT_region_IROM1_end__ = 0x10100000;
/* 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__ = 0x0400;
} 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,408 @@
/***************************************************************************//**
* \file cy8c6xx7_cm4_dual.ld
* \version 2.20
*
* 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.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
ENTRY(Reset_Handler)
/* Force symbol to be entered in the output file as an undefined symbol. Doing
* this may, for example, trigger linking of additional modules from standard
* libraries. You may list several symbols for each EXTERN, and you may use
* EXTERN multiple times. This command has the same effect as the -u command-line
* option.
*/
EXTERN(Reset_Handler)
/* 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 = 0x08024000, LENGTH = 0x23800
flash (rx) : ORIGIN = 0x10080000, LENGTH = 0x80000
/* 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 = 0x14004000, LENGTH = 0x4000 /* 16 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*))
} > flash
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > flash
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > flash
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_psoc6_01_cm4.S */
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
/* Copy interrupt vectors from flash to RAM */
LONG (__Vectors) /* From */
LONG (__ram_vectors_start__) /* To */
LONG (__Vectors_End - __Vectors) /* Size */
/* Copy data section to RAM */
LONG (__etext) /* From */
LONG (__data_start__) /* To */
LONG (__data_end__ - __data_start__) /* Size */
__copy_table_end__ = .;
} > flash
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_psoc6_01_cm4.S */
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
__zero_table_end__ = .;
} > flash
__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 application.
* 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,213 @@
#! 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.20
;*
;* 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.
;* You may use this file only in accordance with the license, terms, conditions,
;* disclaimers, and limitations in the end user license agreement accompanying
;* the software package with which this file was provided.
;******************************************************************************/
; 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
#define RAM_START 0x08024000
#define RAM_SIZE 0x00023800
; Flash
#define FLASH_START 0x10080000
#define FLASH_SIZE 0x00080000
; 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_FLASH 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)
}
ER_RAM_DATA +0
{
* (.cy_ramfunc)
.ANY (+RW, +ZI)
}
; Place variables in the section that should not be initialized during the
; device startup.
ER_RAM_NOINIT_DATA +0 UNINIT
{
* (.noinit)
}
; Used for the digital signature of the secure application and the
; Bootloader SDK application. 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,66 @@
/***************************************************************************//**
* \file cy_ble_config.h
* \version 2.80
*
* \brief
* The user BLE configuration file. Allows redefining the configuration #define(s)
* generated by the BLE customizer.
*
********************************************************************************
* \copyright
* Copyright 2017-2023, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#ifndef CY_BLE_CONF_H
#define CY_BLE_CONF_H
#include "ble/cy_ble_defines.h"
/**
* The BLE_config.h file is generated by the BLE customizer and includes all common
* configuration defines (CY_BLE_CONFIG_***).
*/
#include "BLE_config.h"
#include <cy_device_headers.h>
#ifndef CY_IP_MXBLESS
#error "The BLE middleware is not supported on this device"
#endif
/**
* The BLE Interrupt Notification Feature - Exposes BLE interrupt notifications
* to an application that indicates a different link layer and radio state
* transition to the user from the BLESS interrupt context.
* This callback is triggered at the beginning of a received BLESS interrupt
* (based on the registered interrupt mask). After this feature is enabled,
* the following APIs are available:
* Cy_BLE_RegisterInterruptCallback() and Cy_BLE_UnRegisterInterruptCallback().
*
* The valid value: 1u - enable / 0u - disable.
*
* BLE Dual mode requires an additional define IPC channel and IPC Interrupt
* structure to send notification from the controller core to host core.
* Use the following defines:
* #define CY_BLE_INTR_NOTIFY_IPC_CHAN (9..15)
* #define CY_BLE_INTR_NOTIFY_IPC_INTR (9..15)
* #define CY_BLE_INTR_NOTIFY_IPC_INTR_PRIOR (0..7)
*/
#define CY_BLE_INTR_NOTIFY_FEATURE_ENABLE (0u)
/**
* To redefine the config #define(s) generated by the BLE customizer,
* use the construction #undef... #define.
*
* #undef CY_BLE_CONFIG_ENABLE_LL_PRIVACY
* #define CY_BLE_CONFIG_ENABLE_LL_PRIVACY (1u)
*
*/
#endif /* !defined(CY_BLE_CONF_H)*/
/* [] END OF FILE */

View file

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

View file

@ -0,0 +1,404 @@
/**************************************************************************//**
* @file startup_psoc6_01_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
*
* Note. The global resources are not yet initialized (for example global variables, peripherals, clocks)
* because this function is executed as the first instruction in the ResetHandler.
* The PDL is also not initialized to use the proper register offsets.
* The user of this function is responsible for initializing the PDL and resources before using them.
*/
.weak Cy_OnResetUser
.func Cy_OnResetUser, Cy_OnResetUser
.type Cy_OnResetUser, %function
Cy_OnResetUser:
bx lr
.size Cy_OnResetUser, . - Cy_OnResetUser
.endfunc
/* Reset handler */
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
bl Cy_OnResetUser
cpsid i
/* Firstly it copies data from read only memory to RAM. There are two schemes
* to copy. One can copy more than one sections. Another can only copy
* one section. The former scheme needs more instructions and read-only
* data to implement than the latter.
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
#ifdef __STARTUP_COPY_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of triplets, each of which specify:
* offset 0: LMA of start of a section to copy from
* offset 4: VMA of start of a section to copy to
* offset 8: size of the section to copy. Must be multiply of 4
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r4, =__copy_table_start__
ldr r5, =__copy_table_end__
.L_loop0:
cmp r4, r5
bge .L_loop0_done
ldr r1, [r4]
ldr r2, [r4, #4]
ldr r3, [r4, #8]
.L_loop0_0:
subs r3, #4
blt .L_loop0_0_done
ldr r0, [r1, r3]
str r0, [r2, r3]
b .L_loop0_0
.L_loop0_0_done:
adds r4, #12
b .L_loop0
.L_loop0_done:
#else
/* Single section scheme.
*
* The ranges of copy from/to are specified by following symbols
* __etext: LMA of start of the section to copy from. Usually end of text
* __data_start__: VMA of start of the section to copy to
* __data_end__: VMA of end of the section to copy to
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
subs r3, r2
ble .L_loop1_done
.L_loop1:
subs r3, #4
ldr r0, [r1,r3]
str r0, [r2,r3]
bgt .L_loop1
.L_loop1_done:
#endif /*__STARTUP_COPY_MULTIPLE */
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
* There are two schemes too. One can clear multiple BSS sections. Another
* can only clear one section. The former is more size expensive than the
* latter.
*
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
* Otherwise define macro __STARTUP_CLEAR_BSS to choose the later.
*/
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of tuples specifying:
* offset 0: Start of a BSS section
* offset 4: Size of this BSS section. Must be multiply of 4
*/
ldr r3, =__zero_table_start__
ldr r4, =__zero_table_end__
.L_loop2:
cmp r3, r4
bge .L_loop2_done
ldr r1, [r3]
ldr r2, [r3, #4]
movs r0, 0
.L_loop2_0:
subs r2, #4
blt .L_loop2_0_done
str r0, [r1, r2]
b .L_loop2_0
.L_loop2_0_done:
adds r3, #8
b .L_loop2
.L_loop2_done:
#elif defined (__STARTUP_CLEAR_BSS)
/* Single BSS section scheme.
*
* The BSS section is specified by following symbols
* __bss_start__: start of the BSS section.
* __bss_end__: end of the BSS section.
*
* Both addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__bss_start__
ldr r2, =__bss_end__
movs r0, 0
subs r2, r1
ble .L_loop3_done
.L_loop3:
subs r2, #4
str r0, [r1, r2]
bgt .L_loop3
.L_loop3_done:
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
/* Update Vector Table Offset Register. */
ldr r0, =__ramVectors
ldr r1, =CY_CPU_VTOR_ADDR
str r0, [r1]
dsb 0xF
#ifndef __NO_SYSTEM_INIT
bl SystemInit
#endif
bl main
/* 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,635 @@
/**************************************************************************//**
* @file startup_psoc6_01_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
*
* Note. The global resources are not yet initialized (for example global variables, peripherals, clocks)
* because this function is executed as the first instruction in the ResetHandler.
* The PDL is also not initialized to use the proper register offsets.
* The user of this function is responsible for initializing the PDL and resources before using them.
*/
.weak Cy_OnResetUser
.func Cy_OnResetUser, Cy_OnResetUser
.type Cy_OnResetUser, %function
Cy_OnResetUser:
bx lr
.size Cy_OnResetUser, . - Cy_OnResetUser
.endfunc
/* Reset handler */
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
bl Cy_OnResetUser
cpsid i
/* Firstly it copies data from read only memory to RAM. There are two schemes
* to copy. One can copy more than one sections. Another can only copy
* one section. The former scheme needs more instructions and read-only
* data to implement than the latter.
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
#ifdef __STARTUP_COPY_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of triplets, each of which specify:
* offset 0: LMA of start of a section to copy from
* offset 4: VMA of start of a section to copy to
* offset 8: size of the section to copy. Must be multiply of 4
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r4, =__copy_table_start__
ldr r5, =__copy_table_end__
.L_loop0:
cmp r4, r5
bge .L_loop0_done
ldr r1, [r4]
ldr r2, [r4, #4]
ldr r3, [r4, #8]
.L_loop0_0:
subs r3, #4
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 define 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
#ifndef __NO_SYSTEM_INIT
bl SystemInit
#endif
bl main
/* 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,423 @@
;/**************************************************************************//**
; * @file startup_psoc6_01_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
EXTERN SystemInit
EXTERN __iar_data_init3
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Weak function for startup customization
;;
;; Note. The global resources are not yet initialized (for example global variables, peripherals, clocks)
;; because this function is executed as the first instruction in the ResetHandler.
;; The PDL is also not initialized to use the proper register offsets.
;; The user of this function is responsible for initializing the PDL and resources before using them.
;;
PUBWEAK Cy_OnResetUser
SECTION .text:CODE:REORDER:NOROOT(2)
Cy_OnResetUser
BX LR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Define strong version to return zero for
;; __iar_program_start to skip data sections
;; initialization.
;;
PUBLIC __low_level_init
SECTION .text:CODE:REORDER:NOROOT(2)
__low_level_init
MOVS R0, #0
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
; Disable global interrupts
CPSID I
; 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
; Initialize data sections
LDR R0, =__iar_data_init3
BLX R0
LDR R0, =SystemInit
BLX R0
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

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,30 @@
#include "project.h"
#include "COMM_IPC_Messages.h"
int main(void)
{
__enable_irq();
#if(CY_BLE_STACK_MODE_IPC)
/* Start BLE Controller for dual core mode */
Cy_BLE_Start(NULL);
#endif /* (CY_BLE_STACK_MODE_IPC)*/
COMM_InitIPCMessages();
/* Enable CM4. CY_CORTEX_M4_APPL_ADDR must be updated if CM4 memory layout is changed. */
Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR);
while(true)
{
#if(CY_BLE_STACK_MODE_IPC)
/* Process BLE events continuously for controller in dual core mode */
Cy_BLE_ProcessEvents();
#endif /* CY_BLE_STACK_MODE_IPC */
/* To achieve low power in the device */
Cy_SysPm_DeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT);
}
}

View file

@ -0,0 +1,107 @@
/** \file
* \brief This file provides the entry point for the application running on the Cortex-M4 core.
*
* ## CapSense
* To tune the CapSense buttons, do the following:
* 1. Define `TUNE_CAPSENSE` below.
* 2. Rebuild the project, and load it on to your board.
* 3. Right-click on the `CapSense` component on the "CapSense" schematic page in `TopDesign.cysch`, and choose "Launch Tuner".
* 4. Follow the instructions in [AN85951 - PSoC® 4 and PSoC® 6 MCU CapSense® Design Guide](https://www.cypress.com/documentation/application-notes/an85951-psoc-4-and-psoc-6-mcu-capsense-design-guide) to complete the tuning.
*
*/
/* Include Files */
#include "KTag.h"
// See the instructions at the top of this file for how to tune CapSense--this is only part of what you need.
//#define TUNE_CAPSENSE
#ifndef TUNE_CAPSENSE
int main()
{
CONFIG_InitTasks();
/* Enable global interrupts. */
__enable_irq();
COMM_InitIPCMessages();
CONFIG_RunTasks();
}
#endif // TUNE_CAPSENSE
void vApplicationIdleHook(void)
{
CyDelay(500);
}
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
/* Halt the CPU */
CY_ASSERT(0);
}
void vApplicationMallocFailedHook( void )
{
/* Halt the CPU */
CY_ASSERT(0);
}
#ifdef TUNE_CAPSENSE
int main()
{
uint8 header[] = {0x0Du, 0x0Au};
uint8 tail[] = {0x00u, 0xFFu, 0xFFu};
__enable_irq(); /* Enable global interrupts. */
UART_Console_Start(); /* Start UART SCB Component */
CapSense_Start(); /* Initialize Component */
CapSense_ScanAllWidgets(); /* Scan all widgets */
for(;;)
{
/* Do this only when a scan is done */
if(CapSense_NOT_BUSY == CapSense_IsBusy())
{
CapSense_ProcessAllWidgets(); /* Process all widgets */
/* Send packet header */
UART_Console_PutArrayBlocking((uint8 *)(&header), sizeof(header));
/* Send packet with CapSense data */
UART_Console_PutArrayBlocking((uint8 *)(&CapSense_dsRam), sizeof(CapSense_dsRam));
/* Send packet tail */
UART_Console_PutArrayBlocking((uint8 *)(&tail), sizeof(tail));
CapSense_ScanAllWidgets(); /* Start next scan */
}
}
}
#endif // TUNE_CAPSENSE
void vApplicationGetIdleTaskMemory(StaticTask_t** ppxIdleTaskTCBBuffer, StackType_t** ppxIdleTaskStackBuffer, uint32_t* pulIdleTaskStackSize)
{
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE];
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
void vApplicationGetTimerTaskMemory(StaticTask_t** ppxTimerTaskTCBBuffer, StackType_t** ppxTimerTaskStackBuffer, uint32_t* pulTimerTaskStackSize)
{
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH];
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}

View file

@ -0,0 +1,321 @@
;/**************************************************************************//**
; * @file startup_psoc6_01_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 >>> ------------------
;*/
; <h> Stack Configuration
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
IF :DEF:__STACK_SIZE
Stack_Size EQU __STACK_SIZE
ELSE
Stack_Size EQU 0x00001000
ENDIF
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
IF :DEF:__HEAP_SIZE
Heap_Size EQU __HEAP_SIZE
ELSE
Heap_Size EQU 0x00000400
ENDIF
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
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
; Weak function for startup customization
;
; Note. The global resources are not yet initialized (for example global variables, peripherals, clocks)
; because this function is executed as the first instruction in the ResetHandler.
; The PDL is also not initialized to use the proper register offsets.
; The user of this function is responsible for initializing the PDL and resources before using them.
;
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
; Disable global interrupts
CPSID I
; 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
; User Initial Stack & Heap
IF :DEF:__MICROLIB
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap PROC
LDR R0, =Heap_Mem
LDR R1, =(Stack_Mem + Stack_Size)
LDR R2, =(Heap_Mem + Heap_Size)
LDR R3, =Stack_Mem
BX LR
ENDP
ALIGN
ENDIF
END
; [] END OF FILE

View file

@ -0,0 +1,696 @@
;/**************************************************************************//**
; * @file startup_psoc6_01_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 >>> ------------------
;*/
; <h> Stack Configuration
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
IF :DEF:__STACK_SIZE
Stack_Size EQU __STACK_SIZE
ELSE
Stack_Size EQU 0x00001000
ENDIF
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
IF :DEF:__HEAP_SIZE
Heap_Size EQU __HEAP_SIZE
ELSE
Heap_Size EQU 0x00000400
ENDIF
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
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
; Weak function for startup customization
;
; Note. The global resources are not yet initialized (for example global variables, peripherals, clocks)
; because this function is executed as the first instruction in the ResetHandler.
; The PDL is also not initialized to use the proper register offsets.
; The user of this function is responsible for initializing the PDL and resources before using them.
;
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
; Disable global interrupts
CPSID I
; 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
; User Initial Stack & Heap
IF :DEF:__MICROLIB
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap PROC
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ENDP
ALIGN
ENDIF
END
; [] END OF FILE

View file

@ -0,0 +1,65 @@
/***************************************************************************//**
* \file stdio_user.c
* \version 1.20
*
* \brief
* This file provides low level function implementation to retarget
* I/O functions of the standard C run-time library.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "stdio_user.h"
#if defined (IO_STDOUT_ENABLE) && defined (IO_STDOUT_UART)
/*******************************************************************************
* Function Name: STDIO_PutChar
********************************************************************************
*
* This function outputs a character through user defined target.
* Note: this is a template function which may be overwritten by the USER in order
* to change the target used in redirecting STDOUT stream.
*
* \param ch
* The character to send.
*
*******************************************************************************/
void STDIO_PutChar(uint32_t ch)
{
/* Place the call to your function here. */
while(0U == Cy_SCB_UART_Put(IO_STDOUT_UART, ch))
{
/* Wait until FIFO is full */
}
}
#endif /* IO_STDOUT_ENABLE && IO_STDOUT_UART */
#if defined (IO_STDIN_ENABLE) && defined (IO_STDIN_UART)
/*******************************************************************************
* Function Name: STDIO_GetChar
********************************************************************************
*
* This function retrieves STDIN from a user specified input source.
* Note: this is a template function which may be overwritten by the USER in order
* to change the target used in redirecting STDIN stream.
*
* \return
* The received character.
*
*******************************************************************************/
uint32_t STDIO_GetChar(void)
{
/* Place the call to your function here. */
while(0UL == Cy_SCB_UART_GetNumInRxFifo(IO_STDIN_UART))
{
}
return (Cy_SCB_UART_Get(IO_STDIN_UART));
}
#endif /* IO_STDIN_ENABLE && IO_STDIN_UART */
/* [] END OF FILE */

View file

@ -0,0 +1,200 @@
/***************************************************************************//**
* \file stdio_user.h
* \version 1.20
*
* \brief
* This file provides configuration macros and function prototypes to retarget
* I/O functions of the standard C run-time library.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#ifndef STDIO_USER_H
#define STDIO_USER_H
/**
* \addtogroup group_retarget_io
* \{
* Retarget the I/O functions of the standard C run-time library to the user-defined target.
*
* Application code frequently uses standard I/O library functions, such as
* scanf()/printf() to perform input/output operations. This utility allows you to retarget
* standard C run-time library I/O functions to the user-defined target.
*
* <h1>Design</h1>
* The file retarget.c defines functions that replace weakly linked I/O functions
* in the standard library (i.e. _write() and _read()). The functions in
* retarget.c in turn call the STDIO_PutChar() and STDIO_GetChar()
* implemented in stdio_user.c.
*
* <h1>Use</h1>
* The files for this utility are in this folder:
* \<PDL Install Directory\>/utilities/retarget_io
*
* The first thing you need to do is add the source files to your project.
*
* For a 3rd Party IDE, add the retarget_io folder to your list of include
* paths and add the files retarget.c and stdio_user.c to your project.
*
* For PSoC Creator, create a PSoC Creator project. Then click
* <b>Project</b> > <b>Build Setting</b> > <b>Peripheral Driver Library</b>. To
* add Retarget I/O source files to your project, enable it as shown on the
* screenshot below. After selecting Retarget I/O in the PDL software package
* list, click OK and build the project. The Retarget I/O source files are
* added to your project and are available for modification.
* ![Figure 1. Build Settings dialog in PSoC Creator](retarget_io_build_settings.png)
*
* For ModusToolbox, create or open existing ModusToolbox project. Open
* Middleware Selector (<b>Project</b> > <b>ModusToolbox Middleware Selector</b>),
* select Retarget I/O item, and click OK (see the screenshot below).
* The Retarget I/O source files are added to your project and are available for
* modification.
* ![Figure 2. Middleware Selector dialog in ModusToolbox](retarget_io_middleware_selector.png)
*
* There are multiple serial communication blocks (SCB) available. By default
* the Retarget I/O files use SCB0. The stdio_user.h file defines these macros:
* \code #define IO_STDOUT_UART SCB0
* #define IO_STDIN_UART SCB0 \endcode
*
* Modify these macros to use the SCB in your design. Standard library I/O
* calls are then retargeted to that SCB.
*
* If you use PSoC Creator, the code generator creates a symbol UART_HW
* to represent the SCB block used in your design. In this case you can
* include "project.h" to access that symbol, and modify the macros like this:
* \code #define IO_STDOUT_UART UART_HW
* #define IO_STDIN_UART UART_HW \endcode
*
* The functions implemented in retarget.c are weakly linked. If you wish
* to modify those functions, you can write your own implementation, and
* not use stdio_user.c at all.
*
* \note The standard library is not standard in how it treats an I/O stream.
* Some implement a data buffer by default. The buffer is not flushed until
* it is full. In that case it may appear that your I/O is not working. You
* should be aware of how the library buffers data, and you should identify
* a buffering strategy and buffer size for a specified stream. If you
* supply a buffer, it must exist until the stream is closed. The following
* line of code disables the buffer for the standard library that
* accompanies the GCC compiler:
* \code setvbuf( stdin, NULL, _IONBF, 0 ); \endcode
*
*
* <h1>MISRA-C Compliance</h1>
* The Retarget IO utility 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>5.6</td>
* <td>A</td>
* <td>No identifier in one name space should have the same spelling
* as an identifier in another name space, with the exception of
* structure member and union member names.</td>
* <td>Violated since the utility redefines the function declared in standard
* library.</td>
* </tr>
* <tr>
* <td>6.3</td>
* <td>A</td>
* <td><i>typedefs</i> that indicate size and signedness should be used in
* place of the basic numerical type.</td>
* <td>Basic numerical types are used to match the definition of the
* function with the prototype defined in the standard library.</td>
* </tr>
* <tr>
* <td>8.8</td>
* <td>R</td>
* <td>An external object or function shall be declared in one and only one file.</td>
* <td>The <i>_write</i> is declared in the standard i/o library with
* <i>weak</i> attribute and is redefined in the utility.</td>
* </tr>
* <tr>
* <td>14.2</td>
* <td>R</td>
* <td>All non-null statements shall either:<br>(a) have at least one
* side-effect however executed, or <br>(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>20.9</td>
* <td>R</td>
* <td>The input/output library <i><stdio.h></i> shall not be used in
* production code.</td>
* <td><i>stdio.h</i> file is included to connect the standard function
* definition with their declaration in the standard library.</td>
* </tr>
* </table>
*
* <h1>Changelog</h1>
*
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>1.20</td>
* <td>Changed include path for cy_scb_uart.h to reflect the PDL source code structure</td>
* <td></td>
* </tr>
* <tr>
* <td>1.10</td>
* <td>Added STDIN support</td>
* <td></td>
* </tr>
* <tr>
* <td>1.0</td>
* <td>Initial version</td>
* <td></td>
* </tr>
* </table>
* \}
*/
#include <project.h>
#include "cy_device_headers.h"
/* Must remain uncommented to use this utility */
#define IO_STDOUT_ENABLE
#define IO_STDIN_ENABLE
#define IO_STDOUT_UART UART_Console_HW
#define IO_STDIN_UART UART_Console_HW
#if defined(IO_STDOUT_ENABLE) || defined(IO_STDIN_ENABLE)
#if defined(IO_STDOUT_UART) || defined(IO_STDIN_UART)
#include "cy_scb_uart.h"
#endif /* IO_STDOUT_UART || IO_STDIN_UART */
#endif /* IO_STDOUT_ENABLE || IO_STDIN_ENABLE */
/* Controls whether CR is added for LF */
#ifndef STDOUT_CR_LF
#define STDOUT_CR_LF 0
#endif /* STDOUT_CR_LF */
#if defined(__cplusplus)
extern "C" {
#endif
#if defined (IO_STDOUT_ENABLE) && defined (IO_STDOUT_UART)
void STDIO_PutChar(uint32_t ch);
#endif /* IO_STDOUT_ENABLE && IO_STDOUT_UART */
#if defined (IO_STDIN_ENABLE) && defined (IO_STDIN_UART)
uint32_t STDIO_GetChar(void);
#endif /* IO_STDIN_ENABLE && IO_STDIN_UART */
#if defined(__cplusplus)
}
#endif
#endif /* STDIO_USER_H */
/* [] END OF FILE */

View file

@ -0,0 +1,648 @@
/***************************************************************************//**
* \file system_psoc6.h
* \version 2.20
*
* \brief Device system header file.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#ifndef _SYSTEM_PSOC6_H_
#define _SYSTEM_PSOC6_H_
/**
* \addtogroup group_system_config
* \{
* 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
* - \ref group_system_config_default_handlers
* - \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
* (e.g. startup_psoc6_01_cm0plus.S and startup_psoc6_01_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
* (e.g. startup_psoc6_01_cm0plus.s and startup_psoc6_01_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_default_handlers Default Interrupt Handlers Definition
* The default interrupt handler functions are defined as weak functions to a dummy
* handler in the startup file. The naming convention for the interrupt handler names
* is <interrupt_name>_IRQHandler. A default interrupt handler can be overwritten in
* user code by defining the handler function using the same name. For example:
* \code
* void scb_0_interrupt_IRQHandler(void)
*{
* ...
*}
* \endcode
*
* \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 (e.g. startup_psoc6_01_cm0plus.S and startup_psoc6_01_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 (e.g. startup_psoc6_01_cm0plus.s and startup_psoc6_01_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 (e.g. startup_psoc6_01_cm0plus.s and startup_psoc6_01_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>2.20</td>
* <td>Moved the Cy_IPC_SystemSemaInit(), Cy_IPC_SystemPipeInit() functions implementation from IPC to Startup.</td>
* <td>Changed the IPC driver configuration method from compile time to run time.</td>
* </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>
* <td></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 ( CY_FLASH_BASE + CY_FLASH_SIZE / 2U) /* <<< Half of flash is reserved for the Cortex-M0+ application */
/***************************************************************************//**
* \brief IPC Semaphores allocation ([value]UL).
* <i>(USER SETTING)</i>
*******************************************************************************/
#define CY_IPC_SEMA_COUNT (128UL) /* <<< This will allow 128 (4*32) semaphores */
/***************************************************************************//**
* \brief IPC Pipe definitions ([value]UL).
* <i>(USER SETTING)</i>
*******************************************************************************/
#define CY_IPC_MAX_ENDPOINTS (8UL) /* <<< 8 endpoints */
/*******************************************************************************
*
* 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
* \{
*/
#if defined(__ARMCC_VERSION)
extern void SystemInit(void) __attribute__((constructor));
#else
extern void SystemInit(void);
#endif /* (__ARMCC_VERSION) */
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);
void Cy_SysIpcPipeIsrCm0(void);
void Cy_SysIpcPipeIsrCm4(void);
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) */
/*******************************************************************************
* IPC Configuration
* =========================
*******************************************************************************/
/* IPC CY_PIPE default configuration */
#define CY_SYS_CYPIPE_CLIENT_CNT (8UL)
#define CY_SYS_INTR_CYPIPE_MUX_EP0 (1UL) /* IPC CYPRESS PIPE */
#define CY_SYS_INTR_CYPIPE_PRIOR_EP0 (1UL) /* Notifier Priority */
#define CY_SYS_INTR_CYPIPE_PRIOR_EP1 (1UL) /* Notifier Priority */
#define CY_SYS_CYPIPE_CHAN_MASK_EP0 (0x0001UL << CY_IPC_CHAN_CYPIPE_EP0)
#define CY_SYS_CYPIPE_CHAN_MASK_EP1 (0x0001UL << CY_IPC_CHAN_CYPIPE_EP1)
/******************************************************************************/
/*
* 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_SYS_CYPIPE_INTR_MASK ( CY_SYS_CYPIPE_CHAN_MASK_EP0 | CY_SYS_CYPIPE_CHAN_MASK_EP1 )
#define CY_SYS_CYPIPE_CONFIG_EP0 ( (CY_SYS_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_SYS_CYPIPE_CONFIG_EP1 ( (CY_SYS_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)
/******************************************************************************/
/** \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 */
/** \cond INTERNAL */
/*******************************************************************************
* Backward compatibility macro. The following code is DEPRECATED and must
* not be used in new projects
*******************************************************************************/
/* BWC defines for functions related to enter/exit critical section */
#define Cy_SaveIRQ Cy_SysLib_EnterCriticalSection
#define Cy_RestoreIRQ Cy_SysLib_ExitCriticalSection
#define CY_SYS_INTR_CYPIPE_EP0 (CY_IPC_INTR_CYPIPE_EP0)
#define CY_SYS_INTR_CYPIPE_EP1 (CY_IPC_INTR_CYPIPE_EP1)
/** \endcond */
#ifdef __cplusplus
}
#endif
#endif /* _SYSTEM_PSOC6_H_ */
/* [] END OF FILE */

View file

@ -0,0 +1,699 @@
/***************************************************************************//**
* \file system_psoc6_cm0plus.c
* \version 2.20
*
* The device system-source file.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include <stdbool.h>
#include "system_psoc6.h"
#include "cy_device.h"
#include "cy_device_headers.h"
#include "cy_syslib.h"
#include "cy_wdt.h"
#if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
#include "cy_ipc_sema.h"
#include "cy_ipc_pipe.h"
#include "cy_ipc_drv.h"
#if defined(CY_DEVICE_PSOC6ABLE2)
#include "cy_flash.h"
#endif /* defined(CY_DEVICE_PSOC6ABLE2) */
#endif /* !defined(CY_IPC_DEFAULT_CFG_DISABLE) */
/*******************************************************************************
* SystemCoreClockUpdate()
*******************************************************************************/
/** Default HFClk frequency in Hz */
#define CY_CLK_HFCLK0_FREQ_HZ_DEFAULT (150000000UL)
/** Default PeriClk frequency in Hz */
#define CY_CLK_PERICLK_FREQ_HZ_DEFAULT (75000000UL)
/** Default SlowClk system core frequency in Hz */
#define CY_CLK_SYSTEM_FREQ_HZ_DEFAULT (75000000UL)
/** IMO frequency in Hz */
#define CY_CLK_IMO_FREQ_HZ (8000000UL)
/** HVILO frequency in Hz */
#define CY_CLK_HVILO_FREQ_HZ (32000UL)
/** PILO frequency in Hz */
#define CY_CLK_PILO_FREQ_HZ (32768UL)
/** WCO frequency in Hz */
#define CY_CLK_WCO_FREQ_HZ (32768UL)
/** ALTLF frequency in Hz */
#define CY_CLK_ALTLF_FREQ_HZ (32768UL)
/**
* 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)) || defined (CY_DOXYGEN)
uint32_t cy_BleEcoClockFreqHz = CY_CLK_ALTHF_FREQ_HZ;
#endif /* (defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL)) || defined (CY_DOXYGEN) */
/*******************************************************************************
* SystemInit()
*******************************************************************************/
/* 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)
#define CY_SYS_CM4_VECTOR_TABLE_VALID_ADDR (0x000003FFUL)
/*******************************************************************************
* Function Name: SystemInit
****************************************************************************//**
*
* Initializes the system:
* - Restores FLL registers to the default state.
* - Unlocks and disables WDT.
* - Calls Cy_PDL_Init() function to define the driver library.
* - Calls the Cy_SystemInit() function, if compiled from PSoC Creator.
* - Calls \ref SystemCoreClockUpdate().
*
*******************************************************************************/
void SystemInit(void)
{
Cy_PDL_Init(CY_DEVICE_CFG);
/* 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 */
Cy_WDT_Unlock();
Cy_WDT_Disable();
Cy_SystemInit();
SystemCoreClockUpdate();
#if defined(CY_DEVICE_PSOC6ABLE2) && !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_DEVICE_PSOC6ABLE2) && !defined(CY_PSOC6ABLE2_REV_0A_SUPPORT_DISABLE) */
#if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
/* Allocate and initialize semaphores for the system operations. */
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);
/********************************************************************************
*
* Initializes the system pipes. The system pipes are used by BLE and Flash.
*
* 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_Sema_Init()
* -# Cy_IPC_Pipe_Config()
* -# Cy_IPC_Pipe_Init()
* -# Cy_Flash_Init()
*
*******************************************************************************/
/* Create an array of endpoint structures */
static cy_stc_ipc_pipe_ep_t systemIpcPipeEpArray[CY_IPC_MAX_ENDPOINTS];
Cy_IPC_Pipe_Config(systemIpcPipeEpArray);
static cy_ipc_pipe_callback_ptr_t systemIpcPipeSysCbArray[CY_SYS_CYPIPE_CLIENT_CNT];
static const cy_stc_ipc_pipe_config_t systemIpcPipeConfigCm0 =
{
/* .ep0ConfigData */
{
/* .ipcNotifierNumber */ CY_IPC_INTR_CYPIPE_EP0,
/* .ipcNotifierPriority */ CY_SYS_INTR_CYPIPE_PRIOR_EP0,
/* .ipcNotifierMuxNumber */ CY_SYS_INTR_CYPIPE_MUX_EP0,
/* .epAddress */ CY_IPC_EP_CYPIPE_CM0_ADDR,
/* .epConfig */ CY_SYS_CYPIPE_CONFIG_EP0
},
/* .ep1ConfigData */
{
/* .ipcNotifierNumber */ CY_IPC_INTR_CYPIPE_EP1,
/* .ipcNotifierPriority */ CY_SYS_INTR_CYPIPE_PRIOR_EP1,
/* .ipcNotifierMuxNumber */ 0u,
/* .epAddress */ CY_IPC_EP_CYPIPE_CM4_ADDR,
/* .epConfig */ CY_SYS_CYPIPE_CONFIG_EP1
},
/* .endpointClientsCount */ CY_SYS_CYPIPE_CLIENT_CNT,
/* .endpointsCallbacksArray */ systemIpcPipeSysCbArray,
/* .userPipeIsrHandler */ &Cy_SysIpcPipeIsrCm0
};
if (cy_device->flashPipeRequired != 0u)
{
Cy_IPC_Pipe_Init(&systemIpcPipeConfigCm0);
}
#if defined(CY_DEVICE_PSOC6ABLE2)
Cy_Flash_Init();
#endif /* defined(CY_DEVICE_PSOC6ABLE2) */
#endif /* !defined(CY_IPC_DEFAULT_CFG_DISABLE) */
}
/*******************************************************************************
* 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;
CY_ASSERT_L2((vectorTableOffset & CY_SYS_CM4_VECTOR_TABLE_VALID_ADDR) == 0UL);
interruptState = Cy_SysLib_EnterCriticalSection();
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_SysLib_ExitCriticalSection(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_SysLib_EnterCriticalSection();
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_SysLib_ExitCriticalSection(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_SysLib_EnterCriticalSection();
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_SysLib_ExitCriticalSection(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_SysLib_EnterCriticalSection();
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_SysLib_ExitCriticalSection(interruptState);
}
#endif /* #if (CY_SYSTEM_CPU_CM0P == 1UL) || defined(CY_DOXYGEN) */
#if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
/*******************************************************************************
* Function Name: Cy_SysIpcPipeIsrCm0
****************************************************************************//**
*
* This is the interrupt service routine for the system pipe.
*
*******************************************************************************/
void Cy_SysIpcPipeIsrCm0(void)
{
Cy_IPC_Pipe_ExecuteCallback(CY_IPC_EP_CYPIPE_CM0_ADDR);
}
#endif
/*******************************************************************************
* 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,542 @@
/***************************************************************************//**
* \file system_psoc6_cm4.c
* \version 2.20
*
* The device system-source file.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include <stdbool.h>
#include "system_psoc6.h"
#include "cy_device.h"
#include "cy_device_headers.h"
#include "cy_syslib.h"
#include "cy_wdt.h"
#if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
#include "cy_ipc_sema.h"
#include "cy_ipc_pipe.h"
#include "cy_ipc_drv.h"
#if defined(CY_DEVICE_PSOC6ABLE2)
#include "cy_flash.h"
#endif /* defined(CY_DEVICE_PSOC6ABLE2) */
#endif /* !defined(CY_IPC_DEFAULT_CFG_DISABLE) */
/*******************************************************************************
* SystemCoreClockUpdate()
*******************************************************************************/
/** Default HFClk frequency in Hz */
#define CY_CLK_HFCLK0_FREQ_HZ_DEFAULT (150000000UL)
/** Default PeriClk frequency in Hz */
#define CY_CLK_PERICLK_FREQ_HZ_DEFAULT (75000000UL)
/** Default SlowClk system core frequency in Hz */
#define CY_CLK_SYSTEM_FREQ_HZ_DEFAULT (75000000UL)
/** IMO frequency in Hz */
#define CY_CLK_IMO_FREQ_HZ (8000000UL)
/** HVILO frequency in Hz */
#define CY_CLK_HVILO_FREQ_HZ (32000UL)
/** PILO frequency in Hz */
#define CY_CLK_PILO_FREQ_HZ (32768UL)
/** WCO frequency in Hz */
#define CY_CLK_WCO_FREQ_HZ (32768UL)
/** ALTLF frequency in Hz */
#define CY_CLK_ALTLF_FREQ_HZ (32768UL)
/**
* 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)) || defined (CY_DOXYGEN)
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()
*******************************************************************************/
/* 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) */
/*******************************************************************************
* Function Name: SystemInit
****************************************************************************//**
* \cond
* Initializes the system:
* - Restores FLL registers to the default state for single core devices.
* - Unlocks and disables WDT.
* - Calls Cy_PDL_Init() function to define the driver library.
* - Calls the Cy_SystemInit() function, if compiled from PSoC Creator.
* - Calls \ref SystemCoreClockUpdate().
* \endcond
*******************************************************************************/
void SystemInit(void)
{
Cy_PDL_Init(CY_DEVICE_CFG);
#ifdef __CM0P_PRESENT
#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;
/* Unlock and disable WDT */
Cy_WDT_Unlock();
Cy_WDT_Disable();
#endif /* (__CM0P_PRESENT == 0) */
#endif /* __CM0P_PRESENT */
Cy_SystemInit();
SystemCoreClockUpdate();
#if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
#ifdef __CM0P_PRESENT
#if (__CM0P_PRESENT == 0)
/* Allocate and initialize semaphores for the system operations. */
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);
#else
(void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, 0ul, NULL);
#endif /* (__CM0P_PRESENT) */
#else
(void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, 0ul, NULL);
#endif /* __CM0P_PRESENT */
/********************************************************************************
*
* Initializes the system pipes. The system pipes are used by BLE and Flash.
*
* 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_Sema_Init()
* -# Cy_IPC_Pipe_Config()
* -# Cy_IPC_Pipe_Init()
* -# Cy_Flash_Init()
*
*******************************************************************************/
/* Create an array of endpoint structures */
static cy_stc_ipc_pipe_ep_t systemIpcPipeEpArray[CY_IPC_MAX_ENDPOINTS];
Cy_IPC_Pipe_Config(systemIpcPipeEpArray);
static cy_ipc_pipe_callback_ptr_t systemIpcPipeSysCbArray[CY_SYS_CYPIPE_CLIENT_CNT];
static const cy_stc_ipc_pipe_config_t systemIpcPipeConfigCm4 =
{
/* .ep0ConfigData */
{
/* .ipcNotifierNumber */ CY_IPC_INTR_CYPIPE_EP0,
/* .ipcNotifierPriority */ CY_SYS_INTR_CYPIPE_PRIOR_EP0,
/* .ipcNotifierMuxNumber */ CY_SYS_INTR_CYPIPE_MUX_EP0,
/* .epAddress */ CY_IPC_EP_CYPIPE_CM0_ADDR,
/* .epConfig */ CY_SYS_CYPIPE_CONFIG_EP0
},
/* .ep1ConfigData */
{
/* .ipcNotifierNumber */ CY_IPC_INTR_CYPIPE_EP1,
/* .ipcNotifierPriority */ CY_SYS_INTR_CYPIPE_PRIOR_EP1,
/* .ipcNotifierMuxNumber */ 0u,
/* .epAddress */ CY_IPC_EP_CYPIPE_CM4_ADDR,
/* .epConfig */ CY_SYS_CYPIPE_CONFIG_EP1
},
/* .endpointClientsCount */ CY_SYS_CYPIPE_CLIENT_CNT,
/* .endpointsCallbacksArray */ systemIpcPipeSysCbArray,
/* .userPipeIsrHandler */ &Cy_SysIpcPipeIsrCm4
};
if (cy_device->flashPipeRequired != 0u)
{
Cy_IPC_Pipe_Init(&systemIpcPipeConfigCm4);
}
#if defined(CY_DEVICE_PSOC6ABLE2)
Cy_Flash_Init();
#endif /* defined(CY_DEVICE_PSOC6ABLE2) */
#endif /* !defined(CY_IPC_DEFAULT_CFG_DISABLE) */
}
/*******************************************************************************
* 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_SysLib_EnterCriticalSection();
SCB->CPACR |= SCB_CPACR_CP10_CP11_ENABLE;
__DSB();
__ISB();
Cy_SysLib_ExitCriticalSection(interruptState);
#endif /* (__FPU_USED) && (__FPU_USED == 1U) */
}
#if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
/*******************************************************************************
* Function Name: Cy_SysIpcPipeIsrCm4
****************************************************************************//**
*
* This is the interrupt service routine for the system pipe.
*
*******************************************************************************/
void Cy_SysIpcPipeIsrCm4(void)
{
Cy_IPC_Pipe_ExecuteCallback(CY_IPC_EP_CYPIPE_CM4_ADDR);
}
#endif
/*******************************************************************************
* 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 */