Initial public release.
This commit is contained in:
parent
7b169e8116
commit
dac4af8d25
255 changed files with 68595 additions and 2 deletions
1242
2020TPCApp1.cydsn/2020TPCApp1.cydwr
Normal file
1242
2020TPCApp1.cydsn/2020TPCApp1.cydwr
Normal file
File diff suppressed because it is too large
Load diff
6435
2020TPCApp1.cydsn/2020TPCApp1.cyprj
Normal file
6435
2020TPCApp1.cydsn/2020TPCApp1.cyprj
Normal file
File diff suppressed because it is too large
Load diff
BIN
2020TPCApp1.cydsn/2020TPCApp1_datasheet.pdf
Normal file
BIN
2020TPCApp1.cydsn/2020TPCApp1_datasheet.pdf
Normal file
Binary file not shown.
288
2020TPCApp1.cydsn/Audio.c
Normal file
288
2020TPCApp1.cydsn/Audio.c
Normal 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;
|
||||
}
|
7
2020TPCApp1.cydsn/Audio.h
Normal file
7
2020TPCApp1.cydsn/Audio.h
Normal 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();
|
1013
2020TPCApp1.cydsn/COMM/BLE/COMM_BLE.c
Normal file
1013
2020TPCApp1.cydsn/COMM/BLE/COMM_BLE.c
Normal file
File diff suppressed because it is too large
Load diff
79
2020TPCApp1.cydsn/COMM/BLE/COMM_BLE.h
Normal file
79
2020TPCApp1.cydsn/COMM/BLE/COMM_BLE.h
Normal 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
|
252
2020TPCApp1.cydsn/COMM/BLE/COMM_BLE_Bond.c
Normal file
252
2020TPCApp1.cydsn/COMM/BLE/COMM_BLE_Bond.c
Normal 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 */
|
32
2020TPCApp1.cydsn/COMM/BLE/COMM_BLE_Bond.h
Normal file
32
2020TPCApp1.cydsn/COMM/BLE/COMM_BLE_Bond.h
Normal 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
|
177
2020TPCApp1.cydsn/COMM/BLE/COMM_BLE_UART.c
Normal file
177
2020TPCApp1.cydsn/COMM/BLE/COMM_BLE_UART.c
Normal 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 */
|
30
2020TPCApp1.cydsn/COMM/BLE/COMM_BLE_UART.h
Normal file
30
2020TPCApp1.cydsn/COMM/BLE/COMM_BLE_UART.h
Normal 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
|
50
2020TPCApp1.cydsn/COMM/COMM.h
Normal file
50
2020TPCApp1.cydsn/COMM/COMM.h
Normal 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
|
639
2020TPCApp1.cydsn/COMM/COMM_Console.c
Normal file
639
2020TPCApp1.cydsn/COMM/COMM_Console.c
Normal 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)
|
144
2020TPCApp1.cydsn/COMM/COMM_Console.h
Normal file
144
2020TPCApp1.cydsn/COMM/COMM_Console.h
Normal 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
|
254
2020TPCApp1.cydsn/COMM/COMM_Console_Util.c
Normal file
254
2020TPCApp1.cydsn/COMM/COMM_Console_Util.c
Normal 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)
|
50
2020TPCApp1.cydsn/COMM/COMM_Console_Util.h
Normal file
50
2020TPCApp1.cydsn/COMM/COMM_Console_Util.h
Normal 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
|
33
2020TPCApp1.cydsn/COMM/COMM_I2C_Bus.c
Normal file
33
2020TPCApp1.cydsn/COMM/COMM_I2C_Bus.c
Normal 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 */
|
29
2020TPCApp1.cydsn/COMM/COMM_I2C_Bus.h
Normal file
29
2020TPCApp1.cydsn/COMM/COMM_I2C_Bus.h
Normal 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
|
285
2020TPCApp1.cydsn/COMM/COMM_IPC_Messages.c
Normal file
285
2020TPCApp1.cydsn/COMM/COMM_IPC_Messages.c
Normal 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);
|
||||
}
|
||||
|
49
2020TPCApp1.cydsn/COMM/COMM_IPC_Messages.h
Normal file
49
2020TPCApp1.cydsn/COMM/COMM_IPC_Messages.h
Normal 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
|
48
2020TPCApp1.cydsn/COMM/COMM_Util.c
Normal file
48
2020TPCApp1.cydsn/COMM/COMM_Util.c
Normal 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 */
|
27
2020TPCApp1.cydsn/COMM/COMM_Util.h
Normal file
27
2020TPCApp1.cydsn/COMM/COMM_Util.h
Normal 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
|
|
@ -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)
|
|
@ -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
|
|
@ -0,0 +1,73 @@
|
|||
/** \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},
|
||||
{"reprogram", " Loads the KTag bootloader for OTA reprogramming.", COMM_RTOS_HandleConsoleReprogram},
|
||||
};
|
||||
|
||||
//! 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)
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
|
@ -0,0 +1,120 @@
|
|||
/** \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;
|
||||
}
|
||||
|
||||
COMM_Console_Command_Result_T COMM_RTOS_HandleConsoleReprogram(char8 * data, uint32_t size)
|
||||
{
|
||||
COMM_Console_Print_String("Entering bootloader for BLE reprogramming.\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
|
||||
Cy_DFU_ExecuteApp(0u);
|
||||
|
||||
// Not that it matters...
|
||||
return COMM_CONSOLE_CMD_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
|
|
@ -0,0 +1,33 @@
|
|||
/** \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);
|
||||
COMM_Console_Command_Result_T COMM_RTOS_HandleConsoleReprogram(char8 * data, uint32_t size);
|
||||
|
||||
#endif // (CONFIG__FEATURE_COMM_CONSOLE == CONFIG__FEATURE_ENABLED)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // COMM_RTOS_CONSOLECOMMANDS_H
|
|
@ -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]), ×) == 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)
|
|
@ -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
|
83
2020TPCApp1.cydsn/CONFIG/CONFIG.h
Normal file
83
2020TPCApp1.cydsn/CONFIG/CONFIG.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
/** \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)
|
||||
|
||||
//! 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
|
113
2020TPCApp1.cydsn/CONFIG/CONFIG_RTOS.c
Normal file
113
2020TPCApp1.cydsn/CONFIG/CONFIG_RTOS.c
Normal 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 */
|
29
2020TPCApp1.cydsn/CONFIG/CONFIG_RTOS.h
Normal file
29
2020TPCApp1.cydsn/CONFIG/CONFIG_RTOS.h
Normal 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
|
223
2020TPCApp1.cydsn/Fire_Control.c
Normal file
223
2020TPCApp1.cydsn/Fire_Control.c
Normal 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();
|
||||
}
|
||||
}
|
13
2020TPCApp1.cydsn/Fire_Control.h
Normal file
13
2020TPCApp1.cydsn/Fire_Control.h
Normal 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
|
228
2020TPCApp1.cydsn/FreeRTOSConfig.h
Normal file
228
2020TPCApp1.cydsn/FreeRTOSConfig.h
Normal 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 system’s 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 */
|
50
2020TPCApp1.cydsn/HW/HW.h
Normal file
50
2020TPCApp1.cydsn/HW/HW.h
Normal 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
|
125
2020TPCApp1.cydsn/HW/HW_CapSense.c
Normal file
125
2020TPCApp1.cydsn/HW/HW_CapSense.c
Normal 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 */
|
||||
|
40
2020TPCApp1.cydsn/HW/HW_CapSense.h
Normal file
40
2020TPCApp1.cydsn/HW/HW_CapSense.h
Normal 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
|
||||
|
392
2020TPCApp1.cydsn/HW/HW_NeoPixels.c
Normal file
392
2020TPCApp1.cydsn/HW/HW_NeoPixels.c
Normal 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);
|
||||
}
|
81
2020TPCApp1.cydsn/KTag.h
Normal file
81
2020TPCApp1.cydsn/KTag.h
Normal 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
|
79
2020TPCApp1.cydsn/Menu/GameSettings/GameMenuItem.c
Normal file
79
2020TPCApp1.cydsn/Menu/GameSettings/GameMenuItem.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* Include Files */
|
||||
#include "KTag.h"
|
||||
|
||||
static uint8_t SubmenuIndex = 0;
|
||||
static MenuItem_T const * const Submenus[] =
|
||||
{
|
||||
&TeamIDMenuItem,
|
||||
&PlayerIDMenuItem
|
||||
};
|
||||
static const uint8_t N_SUBMENUS = (sizeof(Submenus) / sizeof(MenuItem_T *));
|
||||
|
||||
static void OnFocus(bool IncludeDetails);
|
||||
static MenuItem_T const * OnSelect();
|
||||
static void OnIncrement();
|
||||
static void OnDecrement();
|
||||
|
||||
const MenuItem_T GameMenuItem =
|
||||
{
|
||||
.OnFocus = OnFocus,
|
||||
.OnSelect = OnSelect,
|
||||
.OnIncrement = OnIncrement,
|
||||
.OnDecrement = OnDecrement
|
||||
|
||||
};
|
||||
|
||||
static void OnFocus(bool IncludeDetails)
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_GAME_SETTINGS_PROMPT, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
|
||||
if (IncludeDetails == true)
|
||||
{
|
||||
if (Submenus[SubmenuIndex]->OnFocus != NULL)
|
||||
{
|
||||
Submenus[SubmenuIndex]->OnFocus(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static MenuItem_T const * OnSelect()
|
||||
{
|
||||
return Submenus[SubmenuIndex];
|
||||
}
|
||||
|
||||
static void OnIncrement()
|
||||
{
|
||||
if (SubmenuIndex < (N_SUBMENUS -1))
|
||||
{
|
||||
SubmenuIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wrap around.
|
||||
SubmenuIndex = 0;
|
||||
}
|
||||
|
||||
if (Submenus[SubmenuIndex]->OnFocus != NULL)
|
||||
{
|
||||
Submenus[SubmenuIndex]->OnFocus(false);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnDecrement()
|
||||
{
|
||||
if (SubmenuIndex > 0)
|
||||
{
|
||||
SubmenuIndex--;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wrap around.
|
||||
SubmenuIndex = (N_SUBMENUS -1);
|
||||
}
|
||||
|
||||
if (Submenus[SubmenuIndex]->OnFocus != NULL)
|
||||
{
|
||||
Submenus[SubmenuIndex]->OnFocus(false);
|
||||
}
|
||||
}
|
6
2020TPCApp1.cydsn/Menu/GameSettings/GameMenuItem.h
Normal file
6
2020TPCApp1.cydsn/Menu/GameSettings/GameMenuItem.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef GAMEMENUITEM_H
|
||||
#define GAMEMENUITEM_H
|
||||
|
||||
const MenuItem_T GameMenuItem;
|
||||
|
||||
#endif // GAMEMENUITEM_H
|
66
2020TPCApp1.cydsn/Menu/GameSettings/PlayerIDMenuItem.c
Normal file
66
2020TPCApp1.cydsn/Menu/GameSettings/PlayerIDMenuItem.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* Include Files */
|
||||
#include "KTag.h"
|
||||
|
||||
#define MIN_PLAYER_ID 0b0000000
|
||||
#define MAX_PLAYER_ID 0b1111111
|
||||
|
||||
static void OnFocus(bool IncludeDetails);
|
||||
static MenuItem_T const * OnSelect();
|
||||
static void OnIncrement();
|
||||
static void OnDecrement();
|
||||
|
||||
const MenuItem_T PlayerIDMenuItem =
|
||||
{
|
||||
.OnFocus = OnFocus,
|
||||
.OnSelect = OnSelect,
|
||||
.OnIncrement = OnIncrement,
|
||||
.OnDecrement = OnDecrement
|
||||
|
||||
};
|
||||
|
||||
static void OnFocus(bool IncludeDetails)
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_PLAYER_ID_PROMPT, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
|
||||
if (IncludeDetails == true)
|
||||
{
|
||||
AudioAction_T volume_action = {.ID = AUDIO_PRONOUNCE_NUMBER_0_TO_100, .Play_To_Completion = true, .Data = (void *)&NVM_PLAYER_ID};
|
||||
xQueueSend(xQueueAudio, &volume_action, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static MenuItem_T const * OnSelect()
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_SELECTION_INDICATOR, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void OnIncrement()
|
||||
{
|
||||
if (NVM_PLAYER_ID < MAX_PLAYER_ID)
|
||||
{
|
||||
NVM_PLAYER_ID++;
|
||||
}
|
||||
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_PLAYER_ID_PROMPT, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
|
||||
AudioAction_T volume_action = {.ID = AUDIO_PRONOUNCE_NUMBER_0_TO_100, .Play_To_Completion = true, .Data = (void *)&NVM_PLAYER_ID};
|
||||
xQueueSend(xQueueAudio, &volume_action, 0);
|
||||
}
|
||||
|
||||
static void OnDecrement()
|
||||
{
|
||||
if (NVM_PLAYER_ID > MIN_PLAYER_ID)
|
||||
{
|
||||
NVM_PLAYER_ID--;
|
||||
}
|
||||
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_PLAYER_ID_PROMPT, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
|
||||
AudioAction_T volume_action = {.ID = AUDIO_PRONOUNCE_NUMBER_0_TO_100, .Play_To_Completion = true, .Data = (void *)&NVM_PLAYER_ID};
|
||||
xQueueSend(xQueueAudio, &volume_action, 0);
|
||||
}
|
6
2020TPCApp1.cydsn/Menu/GameSettings/PlayerIDMenuItem.h
Normal file
6
2020TPCApp1.cydsn/Menu/GameSettings/PlayerIDMenuItem.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef PLAYERIDMENUITEM_H
|
||||
#define PLAYERIDMENUITEM_H
|
||||
|
||||
const MenuItem_T PlayerIDMenuItem;
|
||||
|
||||
#endif // PLAYERIDMENUITEM_H
|
66
2020TPCApp1.cydsn/Menu/GameSettings/TeamIDMenuItem.c
Normal file
66
2020TPCApp1.cydsn/Menu/GameSettings/TeamIDMenuItem.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* Include Files */
|
||||
#include "KTag.h"
|
||||
|
||||
#define MIN_TEAM_ID 0
|
||||
#define MAX_TEAM_ID 3
|
||||
|
||||
static void OnFocus(bool IncludeDetails);
|
||||
static MenuItem_T const * OnSelect();
|
||||
static void OnIncrement();
|
||||
static void OnDecrement();
|
||||
|
||||
const MenuItem_T TeamIDMenuItem =
|
||||
{
|
||||
.OnFocus = OnFocus,
|
||||
.OnSelect = OnSelect,
|
||||
.OnIncrement = OnIncrement,
|
||||
.OnDecrement = OnDecrement
|
||||
|
||||
};
|
||||
|
||||
static void OnFocus(bool IncludeDetails)
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_TEAM_ID_PROMPT, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
|
||||
if (IncludeDetails == true)
|
||||
{
|
||||
AudioAction_T volume_action = {.ID = AUDIO_PRONOUNCE_NUMBER_0_TO_100, .Play_To_Completion = true, .Data = (void *)&NVM_TEAM_ID};
|
||||
xQueueSend(xQueueAudio, &volume_action, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static MenuItem_T const * OnSelect()
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_SELECTION_INDICATOR, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void OnIncrement()
|
||||
{
|
||||
if (NVM_TEAM_ID < MAX_TEAM_ID)
|
||||
{
|
||||
NVM_TEAM_ID++;
|
||||
}
|
||||
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_TEAM_ID_PROMPT, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
|
||||
AudioAction_T volume_action = {.ID = AUDIO_PRONOUNCE_NUMBER_0_TO_100, .Play_To_Completion = true, .Data = (void *)&NVM_TEAM_ID};
|
||||
xQueueSend(xQueueAudio, &volume_action, 0);
|
||||
}
|
||||
|
||||
static void OnDecrement()
|
||||
{
|
||||
if (NVM_TEAM_ID > MIN_TEAM_ID)
|
||||
{
|
||||
NVM_TEAM_ID--;
|
||||
}
|
||||
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_TEAM_ID_PROMPT, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
|
||||
AudioAction_T volume_action = {.ID = AUDIO_PRONOUNCE_NUMBER_0_TO_100, .Play_To_Completion = true, .Data = (void *)&NVM_TEAM_ID};
|
||||
xQueueSend(xQueueAudio, &volume_action, 0);
|
||||
}
|
6
2020TPCApp1.cydsn/Menu/GameSettings/TeamIDMenuItem.h
Normal file
6
2020TPCApp1.cydsn/Menu/GameSettings/TeamIDMenuItem.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef TEAMIDMENUITEM_H
|
||||
#define TEAMIDMENUITEM_H
|
||||
|
||||
const MenuItem_T TeamIDMenuItem;
|
||||
|
||||
#endif // TEAMIDMENUITEM_H
|
64
2020TPCApp1.cydsn/Menu/HardwareSettings/HandedMenuItem.c
Normal file
64
2020TPCApp1.cydsn/Menu/HardwareSettings/HandedMenuItem.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* Include Files */
|
||||
#include "KTag.h"
|
||||
|
||||
static void OnFocus(bool IncludeDetails);
|
||||
static MenuItem_T const * OnSelect();
|
||||
static void OnIncrement();
|
||||
static void OnDecrement();
|
||||
static void ToggleHanded();
|
||||
|
||||
const MenuItem_T HandedMenuItem =
|
||||
{
|
||||
.OnFocus = OnFocus,
|
||||
.OnSelect = OnSelect,
|
||||
.OnIncrement = OnIncrement,
|
||||
.OnDecrement = OnDecrement
|
||||
|
||||
};
|
||||
|
||||
static void OnFocus(bool IncludeDetails)
|
||||
{
|
||||
if (NVM_IS_RIGHT_HANDED == true)
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_RIGHT_HANDED, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_LEFT_HANDED, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static MenuItem_T const * OnSelect()
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_SELECTION_INDICATOR, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void OnIncrement()
|
||||
{
|
||||
ToggleHanded();
|
||||
}
|
||||
|
||||
static void OnDecrement()
|
||||
{
|
||||
ToggleHanded();
|
||||
}
|
||||
|
||||
static void ToggleHanded()
|
||||
{
|
||||
if (NVM_IS_RIGHT_HANDED == true)
|
||||
{
|
||||
NVM_IS_RIGHT_HANDED = false;
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_LEFT_HANDED, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
NVM_IS_RIGHT_HANDED = true;
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_RIGHT_HANDED, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
}
|
||||
}
|
6
2020TPCApp1.cydsn/Menu/HardwareSettings/HandedMenuItem.h
Normal file
6
2020TPCApp1.cydsn/Menu/HardwareSettings/HandedMenuItem.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef HANDEDMENUITEM_H
|
||||
#define HANDEDMENUITEM_H
|
||||
|
||||
const MenuItem_T HandedMenuItem;
|
||||
|
||||
#endif // VOLUMEMENUITEM_H
|
79
2020TPCApp1.cydsn/Menu/HardwareSettings/HardwareMenuItem.c
Normal file
79
2020TPCApp1.cydsn/Menu/HardwareSettings/HardwareMenuItem.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* Include Files */
|
||||
#include "KTag.h"
|
||||
|
||||
static uint8_t SubmenuIndex = 0;
|
||||
static MenuItem_T const * const Submenus[] =
|
||||
{
|
||||
&VolumeMenuItem,
|
||||
&HandedMenuItem
|
||||
};
|
||||
static const uint8_t N_SUBMENUS = (sizeof(Submenus) / sizeof(MenuItem_T *));
|
||||
|
||||
static void OnFocus(bool IncludeDetails);
|
||||
static MenuItem_T const * OnSelect();
|
||||
static void OnIncrement();
|
||||
static void OnDecrement();
|
||||
|
||||
const MenuItem_T HardwareMenuItem =
|
||||
{
|
||||
.OnFocus = OnFocus,
|
||||
.OnSelect = OnSelect,
|
||||
.OnIncrement = OnIncrement,
|
||||
.OnDecrement = OnDecrement
|
||||
|
||||
};
|
||||
|
||||
static void OnFocus(bool IncludeDetails)
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_HARDWARE_SETTINGS_PROMPT, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
|
||||
if (IncludeDetails == true)
|
||||
{
|
||||
if (Submenus[SubmenuIndex]->OnFocus != NULL)
|
||||
{
|
||||
Submenus[SubmenuIndex]->OnFocus(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static MenuItem_T const * OnSelect()
|
||||
{
|
||||
return Submenus[SubmenuIndex];
|
||||
}
|
||||
|
||||
static void OnIncrement()
|
||||
{
|
||||
if (SubmenuIndex < (N_SUBMENUS -1))
|
||||
{
|
||||
SubmenuIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wrap around.
|
||||
SubmenuIndex = 0;
|
||||
}
|
||||
|
||||
if (Submenus[SubmenuIndex]->OnFocus != NULL)
|
||||
{
|
||||
Submenus[SubmenuIndex]->OnFocus(false);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnDecrement()
|
||||
{
|
||||
if (SubmenuIndex > 0)
|
||||
{
|
||||
SubmenuIndex--;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wrap around.
|
||||
SubmenuIndex = (N_SUBMENUS -1);
|
||||
}
|
||||
|
||||
if (Submenus[SubmenuIndex]->OnFocus != NULL)
|
||||
{
|
||||
Submenus[SubmenuIndex]->OnFocus(false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef HARDWAREMENUITEM_H
|
||||
#define HARDWAREMENUITEM_H
|
||||
|
||||
const MenuItem_T HardwareMenuItem;
|
||||
|
||||
#endif // HARDWAREMENUITEM_H
|
72
2020TPCApp1.cydsn/Menu/HardwareSettings/VolumeMenuItem.c
Normal file
72
2020TPCApp1.cydsn/Menu/HardwareSettings/VolumeMenuItem.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
/* Include Files */
|
||||
#include "KTag.h"
|
||||
|
||||
#define MAX_VOLUME 30
|
||||
#define MIN_VOLUME 5
|
||||
|
||||
static void OnFocus(bool IncludeDetails);
|
||||
static MenuItem_T const * OnSelect();
|
||||
static void OnIncrement();
|
||||
static void OnDecrement();
|
||||
|
||||
const MenuItem_T VolumeMenuItem =
|
||||
{
|
||||
.OnFocus = OnFocus,
|
||||
.OnSelect = OnSelect,
|
||||
.OnIncrement = OnIncrement,
|
||||
.OnDecrement = OnDecrement
|
||||
|
||||
};
|
||||
|
||||
static void OnFocus(bool IncludeDetails)
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_VOLUME_PROMPT, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
|
||||
if (IncludeDetails == true)
|
||||
{
|
||||
AudioAction_T volume_action = {.ID = AUDIO_PRONOUNCE_NUMBER_0_TO_100, .Play_To_Completion = true, .Data = (void *)&NVM_VOLUME};
|
||||
xQueueSend(xQueueAudio, &volume_action, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static MenuItem_T const * OnSelect()
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_SELECTION_INDICATOR, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void OnIncrement()
|
||||
{
|
||||
if (NVM_VOLUME < MAX_VOLUME)
|
||||
{
|
||||
NVM_VOLUME++;
|
||||
}
|
||||
|
||||
AudioAction_T set_volume_action = {.ID = AUDIO_SET_VOLUME, .Data = (void *)&NVM_VOLUME};
|
||||
xQueueSend(xQueueAudio, &set_volume_action, 0);
|
||||
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_VOLUME_PROMPT, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
|
||||
AudioAction_T volume_action = {.ID = AUDIO_PRONOUNCE_NUMBER_0_TO_100, .Play_To_Completion = true, .Data = (void *)&NVM_VOLUME};
|
||||
xQueueSend(xQueueAudio, &volume_action, 0);
|
||||
}
|
||||
|
||||
static void OnDecrement()
|
||||
{
|
||||
if (NVM_VOLUME > MIN_VOLUME)
|
||||
{
|
||||
NVM_VOLUME--;
|
||||
}
|
||||
|
||||
AudioAction_T set_volume_action = {.ID = AUDIO_SET_VOLUME, .Data = (void *)&NVM_VOLUME};
|
||||
xQueueSend(xQueueAudio, &set_volume_action, 0);
|
||||
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_VOLUME_PROMPT, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
|
||||
AudioAction_T volume_action = {.ID = AUDIO_PRONOUNCE_NUMBER_0_TO_100, .Play_To_Completion = true, .Data = (void *)&NVM_VOLUME};
|
||||
xQueueSend(xQueueAudio, &volume_action, 0);
|
||||
}
|
6
2020TPCApp1.cydsn/Menu/HardwareSettings/VolumeMenuItem.h
Normal file
6
2020TPCApp1.cydsn/Menu/HardwareSettings/VolumeMenuItem.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef VOLUMEMENUITEM_H
|
||||
#define VOLUMEMENUITEM_H
|
||||
|
||||
const MenuItem_T VolumeMenuItem;
|
||||
|
||||
#endif // VOLUMEMENUITEM_H
|
86
2020TPCApp1.cydsn/Menu/Menu.c
Normal file
86
2020TPCApp1.cydsn/Menu/Menu.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
/* Include Files */
|
||||
#include "KTag.h"
|
||||
|
||||
static uint8_t SubmenuIndex = 0;
|
||||
static MenuItem_T const * const Submenus[] =
|
||||
{
|
||||
&GameMenuItem,
|
||||
&HardwareMenuItem
|
||||
};
|
||||
static const uint8_t N_SUBMENUS = (sizeof(Submenus) / sizeof(MenuItem_T *));
|
||||
|
||||
static void RootMenuOnFocus(bool IncludeDetails);
|
||||
static MenuItem_T const * RootMenuOnSelect();
|
||||
static void RootMenuOnIncrement();
|
||||
static void RootMenuOnDecrement();
|
||||
|
||||
static const MenuItem_T Root_Menu_Item =
|
||||
{
|
||||
.OnFocus = RootMenuOnFocus,
|
||||
.OnSelect = RootMenuOnSelect,
|
||||
.OnIncrement = RootMenuOnIncrement,
|
||||
.OnDecrement = RootMenuOnDecrement
|
||||
|
||||
};
|
||||
|
||||
MenuItem_T const * const RootMenu = &Root_Menu_Item;
|
||||
|
||||
static void RootMenuOnFocus(bool IncludeDetails)
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_MENU_PROMPT, .Play_To_Completion = true, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueAudio, &audio_action, 0);
|
||||
|
||||
if (IncludeDetails == true)
|
||||
{
|
||||
if (Submenus[SubmenuIndex]->OnFocus != NULL)
|
||||
{
|
||||
Submenus[SubmenuIndex]->OnFocus(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static MenuItem_T const * RootMenuOnSelect()
|
||||
{
|
||||
if (Submenus[SubmenuIndex]->OnSelect != NULL)
|
||||
{
|
||||
Submenus[SubmenuIndex]->OnSelect();
|
||||
}
|
||||
|
||||
return Submenus[SubmenuIndex];
|
||||
}
|
||||
|
||||
static void RootMenuOnIncrement()
|
||||
{
|
||||
if (SubmenuIndex < (N_SUBMENUS -1))
|
||||
{
|
||||
SubmenuIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wrap around.
|
||||
SubmenuIndex = 0;
|
||||
}
|
||||
|
||||
if (Submenus[SubmenuIndex]->OnFocus != NULL)
|
||||
{
|
||||
Submenus[SubmenuIndex]->OnFocus(false);
|
||||
}
|
||||
}
|
||||
|
||||
static void RootMenuOnDecrement()
|
||||
{
|
||||
if (SubmenuIndex > 0)
|
||||
{
|
||||
SubmenuIndex--;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wrap around.
|
||||
SubmenuIndex = (N_SUBMENUS -1);
|
||||
}
|
||||
|
||||
if (Submenus[SubmenuIndex]->OnFocus != NULL)
|
||||
{
|
||||
Submenus[SubmenuIndex]->OnFocus(false);
|
||||
}
|
||||
}
|
28
2020TPCApp1.cydsn/Menu/Menu.h
Normal file
28
2020TPCApp1.cydsn/Menu/Menu.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef MENU_H
|
||||
#define MENU_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef struct MenuItem_S
|
||||
{
|
||||
// Performs the actions required when this MenuItem receives focus.
|
||||
void (*OnFocus)(bool IncludeDetails);
|
||||
// Performs the actions required when this MenuItem receives focus.
|
||||
struct MenuItem_S const * (*OnSelect)(void);
|
||||
void (*OnIncrement)(void);
|
||||
void (*OnDecrement)(void);
|
||||
|
||||
} MenuItem_T;
|
||||
|
||||
MenuItem_T const * const RootMenu;
|
||||
|
||||
#include "GameSettings/GameMenuItem.h"
|
||||
#include "GameSettings/PlayerIDMenuItem.h"
|
||||
#include "GameSettings/TeamIDMenuItem.h"
|
||||
#include "HardwareSettings/HardwareMenuItem.h"
|
||||
#include "HardwareSettings/VolumeMenuItem.h"
|
||||
#include "HardwareSettings/HandedMenuItem.h"
|
||||
|
||||
#endif // MENU_H
|
105
2020TPCApp1.cydsn/NVM/NVM.h
Normal file
105
2020TPCApp1.cydsn/NVM/NVM.h
Normal 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
|
72
2020TPCApp1.cydsn/NVM/NVM_CRC.c
Normal file
72
2020TPCApp1.cydsn/NVM/NVM_CRC.c
Normal 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;
|
||||
}
|
115
2020TPCApp1.cydsn/NVM/NVM_CRC.h
Normal file
115
2020TPCApp1.cydsn/NVM/NVM_CRC.h
Normal 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 */
|
302
2020TPCApp1.cydsn/NVM/NVM_ExternalEEPROM.c
Normal file
302
2020TPCApp1.cydsn/NVM/NVM_ExternalEEPROM.c
Normal 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 */
|
44
2020TPCApp1.cydsn/NVM/NVM_ExternalEEPROM.h
Normal file
44
2020TPCApp1.cydsn/NVM/NVM_ExternalEEPROM.h
Normal 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
|
153
2020TPCApp1.cydsn/NVM/NVM_ExternalEEPROMEntries.c
Normal file
153
2020TPCApp1.cydsn/NVM/NVM_ExternalEEPROMEntries.c
Normal 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 *));
|
||||
|
135
2020TPCApp1.cydsn/NVM/NVM_ExternalEEPROMEntries.h
Normal file
135
2020TPCApp1.cydsn/NVM/NVM_ExternalEEPROMEntries.h
Normal 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
|
||||
|
260
2020TPCApp1.cydsn/NVM/NVM_OnChipEEPROM.c
Normal file
260
2020TPCApp1.cydsn/NVM/NVM_OnChipEEPROM.c
Normal 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 */
|
42
2020TPCApp1.cydsn/NVM/NVM_OnChipEEPROM.h
Normal file
42
2020TPCApp1.cydsn/NVM/NVM_OnChipEEPROM.h
Normal 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
|
63
2020TPCApp1.cydsn/NVM/NVM_OnChipEEPROMEntries.c
Normal file
63
2020TPCApp1.cydsn/NVM/NVM_OnChipEEPROMEntries.c
Normal 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 *));
|
||||
|
60
2020TPCApp1.cydsn/NVM/NVM_OnChipEEPROMEntries.h
Normal file
60
2020TPCApp1.cydsn/NVM/NVM_OnChipEEPROMEntries.h
Normal 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
|
||||
|
125
2020TPCApp1.cydsn/NVM/NVM_Settings.c
Normal file
125
2020TPCApp1.cydsn/NVM/NVM_Settings.c
Normal 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;
|
||||
}
|
93
2020TPCApp1.cydsn/Sample_Tasks.c
Normal file
93
2020TPCApp1.cydsn/Sample_Tasks.c
Normal 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 */
|
9
2020TPCApp1.cydsn/Sample_Tasks.h
Normal file
9
2020TPCApp1.cydsn/Sample_Tasks.h
Normal 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
|
196
2020TPCApp1.cydsn/Switches.c
Normal file
196
2020TPCApp1.cydsn/Switches.c
Normal 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);
|
||||
}
|
||||
}
|
9
2020TPCApp1.cydsn/Switches.h
Normal file
9
2020TPCApp1.cydsn/Switches.h
Normal 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
|
1
2020TPCApp1.cydsn/SystemK
Submodule
1
2020TPCApp1.cydsn/SystemK
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 4fe072f2d3280b19aa53e197bd22ec44b174ff88
|
582
2020TPCApp1.cydsn/Tag_Sensors.c
Normal file
582
2020TPCApp1.cydsn/Tag_Sensors.c
Normal 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);
|
||||
}
|
||||
|
16
2020TPCApp1.cydsn/Tag_Sensors.h
Normal file
16
2020TPCApp1.cydsn/Tag_Sensors.h
Normal 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
|
BIN
2020TPCApp1.cydsn/TopDesign/TopDesign.cysch
Normal file
BIN
2020TPCApp1.cydsn/TopDesign/TopDesign.cysch
Normal file
Binary file not shown.
41
2020TPCApp1.cydsn/UTIL/UTIL.h
Normal file
41
2020TPCApp1.cydsn/UTIL/UTIL.h
Normal 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
|
160
2020TPCApp1.cydsn/UTIL/UTIL_CircularBuffer.c
Normal file
160
2020TPCApp1.cydsn/UTIL/UTIL_CircularBuffer.c
Normal 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;
|
||||
}
|
41
2020TPCApp1.cydsn/UTIL/UTIL_CircularBuffer.h
Normal file
41
2020TPCApp1.cydsn/UTIL/UTIL_CircularBuffer.h
Normal 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
|
94
2020TPCApp1.cydsn/common.h
Normal file
94
2020TPCApp1.cydsn/common.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*******************************************************************************
|
||||
* File Name: common.h
|
||||
*
|
||||
* Version 1.0
|
||||
*
|
||||
* Description:
|
||||
* Contains the function prototypes and constants available to the example
|
||||
* project.
|
||||
*
|
||||
********************************************************************************
|
||||
* Copyright 2017, Cypress Semiconductor Corporation. All rights reserved.
|
||||
* You may use this file only in accordance with the license, terms, conditions,
|
||||
* disclaimers, and limitations in the end user license agreement accompanying
|
||||
* the software package with which this file was provided.
|
||||
*******************************************************************************/
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#include <project.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/***************************************
|
||||
* Conditional Compilation Parameters
|
||||
***************************************/
|
||||
#define ENABLED (1u)
|
||||
#define DISABLED (0u)
|
||||
#define DEBUG_UART_ENABLED ENABLED
|
||||
|
||||
|
||||
/***************************************
|
||||
* API Constants
|
||||
***************************************/
|
||||
#define ADV_TIMER_TIMEOUT (1u) /* Сounts in seconds */
|
||||
#define SW2_PRESS_TIME_DEL_BOND_LIST (0x04u)
|
||||
|
||||
/* BAS service defines */
|
||||
#define BATTERY_TIMEOUT (30u) /* Battery simulation timeout */
|
||||
|
||||
/***************************************
|
||||
* External Function Prototypes
|
||||
***************************************/
|
||||
int HostMain(void);
|
||||
|
||||
/* Function prototypes from debug.c */
|
||||
void ShowValue(cy_stc_ble_gatt_value_t *value);
|
||||
char HexToAscii(uint8_t value, uint8_t nibble);
|
||||
void Set32ByPtr(uint8_t ptr[], uint32_t value);
|
||||
void PrintStackVersion(void);
|
||||
void PrintApiResult(cy_en_ble_api_result_t apiResult);
|
||||
void ShowError(void);
|
||||
|
||||
/* Function prototypes from bond.c */
|
||||
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);
|
||||
|
||||
|
||||
/***************************************
|
||||
* UART_DEB Macros / prototypes
|
||||
***************************************/
|
||||
#if (DEBUG_UART_ENABLED == ENABLED)
|
||||
#define DBG_PRINTF(...) (printf(__VA_ARGS__))
|
||||
#define UART_DEB_PUT_CHAR(...) while(1UL != UART_DEB_Put(__VA_ARGS__))
|
||||
#define UART_DEB_GET_CHAR(...) (UART_DEB_Get())
|
||||
#define UART_DEB_IS_TX_COMPLETE(...) (UART_DEB_IsTxComplete())
|
||||
#define UART_DEB_WAIT_TX_COMPLETE(...) while(UART_DEB_IS_TX_COMPLETE() == 0) ;
|
||||
#define UART_DEB_SCB_CLEAR_RX_FIFO(...) (Cy_SCB_ClearRxFifo(UART_DEB_SCB__HW))
|
||||
#define UART_START(...) (UART_DEB_Start(__VA_ARGS__))
|
||||
#else
|
||||
#define DBG_PRINTF(...)
|
||||
#define UART_DEB_PUT_CHAR(...)
|
||||
#define UART_DEB_GET_CHAR(...) (0u)
|
||||
#define UART_DEB_IS_TX_COMPLETE(...) (1u)
|
||||
#define UART_DEB_WAIT_TX_COMPLETE(...) (0u)
|
||||
#define UART_DEB_SCB_CLEAR_RX_FIFO(...) (0u)
|
||||
#define UART_START(...)
|
||||
#endif /* (DEBUG_UART_ENABLED == ENABLED) */
|
||||
|
||||
#define UART_DEB_NO_DATA (char8) CY_SCB_UART_RX_NO_DATA
|
||||
|
||||
|
||||
/***************************************
|
||||
* External data references
|
||||
***************************************/
|
||||
extern cy_stc_ble_conn_handle_t appConnHandle;
|
||||
|
||||
|
||||
#endif /* COMMON_H */
|
||||
|
||||
/* [] END OF FILE */
|
218
2020TPCApp1.cydsn/cy8c6xx7_cm0plus.icf
Normal file
218
2020TPCApp1.cydsn/cy8c6xx7_cm0plus.icf
Normal 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 */
|
402
2020TPCApp1.cydsn/cy8c6xx7_cm0plus.ld
Normal file
402
2020TPCApp1.cydsn/cy8c6xx7_cm0plus.ld
Normal 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 */
|
207
2020TPCApp1.cydsn/cy8c6xx7_cm0plus.scat
Normal file
207
2020TPCApp1.cydsn/cy8c6xx7_cm0plus.scat
Normal 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 */
|
219
2020TPCApp1.cydsn/cy8c6xx7_cm4_dual.icf
Normal file
219
2020TPCApp1.cydsn/cy8c6xx7_cm4_dual.icf
Normal 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 */
|
408
2020TPCApp1.cydsn/cy8c6xx7_cm4_dual.ld
Normal file
408
2020TPCApp1.cydsn/cy8c6xx7_cm4_dual.ld
Normal 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 */
|
213
2020TPCApp1.cydsn/cy8c6xx7_cm4_dual.scat
Normal file
213
2020TPCApp1.cydsn/cy8c6xx7_cm4_dual.scat
Normal 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 */
|
66
2020TPCApp1.cydsn/cy_ble_config.h
Normal file
66
2020TPCApp1.cydsn/cy_ble_config.h
Normal 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 */
|
129
2020TPCApp1.cydsn/cy_si_config.h
Normal file
129
2020TPCApp1.cydsn/cy_si_config.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
/***************************************************************************//**
|
||||
* \file cy_si_config.h
|
||||
* \version 1.0.1
|
||||
*
|
||||
* \brief
|
||||
* Definitions and function prototypes for Secure Image.
|
||||
*
|
||||
********************************************************************************
|
||||
* \copyright
|
||||
* Copyright 2017-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 _CY_SI_CONFIG_H_
|
||||
#define _CY_SI_CONFIG_H_
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************
|
||||
* Macros
|
||||
***************************************/
|
||||
/*
|
||||
* Macros to define the secure image version and ID.
|
||||
*/
|
||||
#define CY_SI_VERSION_MAJOR 1UL /**< Major version */
|
||||
#define CY_SI_VERSION_MINOR 0UL /**< Minor version */
|
||||
#define CY_SI_APP_VERSION ((CY_SI_VERSION_MAJOR << 24u) | (CY_SI_VERSION_MINOR << 16u)) /**< App Version */
|
||||
#define CY_SI_ID CY_PDL_DRV_ID(0x38u) /**< Secure Image ID */
|
||||
#define CY_SI_ID_INFO (uint32_t)( CY_SI_ID | CY_PDL_STATUS_INFO ) /**< Secure Image INFO ID */
|
||||
#define CY_SI_ID_WARNING (uint32_t)( CY_SI_ID | CY_PDL_STATUS_WARNING) /**< Secure Image WARNING ID */
|
||||
#define CY_SI_ID_ERROR (uint32_t)( CY_SI_ID | CY_PDL_STATUS_ERROR) /**< Secure Image ERROR ID */
|
||||
#define CY_SI_CHECKID(val) ((uint32_t)(val) & (CY_PDL_MODULE_ID_Msk << CY_PDL_MODULE_ID_Pos)) /**< Check ID macro */
|
||||
|
||||
/*
|
||||
* Clock selection for Flash boot execution.
|
||||
*/
|
||||
#define CY_SI_FLASHBOOT_CLK_25MHZ (0x00UL) /**< 25MHz clock selection for Flashboot */
|
||||
#define CY_SI_FLASHBOOT_CLK_8MHZ (0x01UL) /**< 8MHz clock selection for Flashboot */
|
||||
#define CY_SI_FLASHBOOT_CLK_50MHZ (0x02UL) /**< 50MHz clock selection for Flashboot */
|
||||
|
||||
/*
|
||||
* Debugger wait window selection for Flash boot execution.
|
||||
*/
|
||||
#define CY_SI_FLASHBOOT_WAIT_20MS (0x00UL) /**< 20ms debugger wait window for Flashboot */
|
||||
#define CY_SI_FLASHBOOT_WAIT_10MS (0x01UL) /**< 10ms debugger wait window for Flashboot */
|
||||
#define CY_SI_FLASHBOOT_WAIT_1MS (0x02UL) /**< 1ms debugger wait window for Flashboot */
|
||||
#define CY_SI_FLASHBOOT_WAIT_0MS (0x03UL) /**< 0ms debugger wait window for Flashboot */
|
||||
#define CY_SI_FLASHBOOT_WAIT_100MS (0x04UL) /**< 100ms debugger wait window for Flashboot */
|
||||
|
||||
/*
|
||||
* Flash boot validation selection in chip NORMAL mode.
|
||||
*/
|
||||
#define CY_SI_FLASHBOOT_VALIDATE_NO (0x00UL) /**< Do not validate app1 in NORMAL mode */
|
||||
#define CY_SI_FLASHBOOT_VALIDATE_YES (0x01UL) /**< Validate app1 in NORMAL mode */
|
||||
|
||||
/*
|
||||
* Application format selection for secure boot.
|
||||
*/
|
||||
#define CY_SI_APP_FORMAT_BASIC (0UL) /**< Basic application format (no header) */
|
||||
#define CY_SI_APP_FORMAT_CYPRESS (1UL) /**< Cypress application format (Cypress header) */
|
||||
|
||||
|
||||
/*
|
||||
* Application type selection for secure boot.
|
||||
*/
|
||||
#define CY_SI_APP_ID_FLASHBOOT (0x8001UL) /**< Flash boot ID Type */
|
||||
#define CY_SI_APP_ID_SECUREIMG (0x8002UL) /**< Secure image ID Type */
|
||||
#define CY_SI_APP_ID_BOOTLOADER (0x8003UL) /**< Bootloader ID Type */
|
||||
|
||||
|
||||
/***************************************
|
||||
* Constants
|
||||
***************************************/
|
||||
#define CY_ARM_CM0P_CPUID (0xC6000000u) /** CM0+ partNo value from ARM CPUID[15:4] register shifted to [31:20] bits */
|
||||
#define CY_ARM_CM4_CPUID (0xC2400000u) /** CM4 partNo value from ARM CPUID[15:4] register shifted to [31:20] bits */
|
||||
|
||||
#define CY_SI_TOC_FLAGS_CLOCKS_MASK (0x00000003UL) /**< Mask for Flashboot clock selection */
|
||||
#define CY_SI_TOC_FLAGS_CLOCKS_POS (0UL) /**< Bit position of Flashboot clock selection */
|
||||
#define CY_SI_TOC_FLAGS_DELAY_MASK (0x0000001CUL) /**< Mask for Flashboot wait window selection */
|
||||
#define CY_SI_TOC_FLAGS_DELAY_POS (2UL) /**< Bit position of Flashboot wait window selection */
|
||||
#define CY_SI_TOC_FLAGS_APP_VERIFY_MASK (0x80000000UL) /**< Mask for Flashboot NORMAL mode app1 validation */
|
||||
#define CY_SI_TOC_FLAGS_APP_VERIFY_POS (31UL) /**< Bit position of Flashboot NORMAL mode app1 validation */
|
||||
|
||||
#define CY_SI_TOC2_MAGICNUMBER (0x01211220UL) /**< TOC2 identifier */
|
||||
|
||||
/***************************************
|
||||
* Structs
|
||||
***************************************/
|
||||
/** Table of Content structure */
|
||||
typedef struct{
|
||||
volatile uint32_t objSize; /**< Object size (Bytes) */
|
||||
volatile uint32_t magicNum; /**< TOC ID (magic number) */
|
||||
volatile uint32_t userKeyAddr; /**< Secure key address in user Flash */
|
||||
volatile uint32_t smifCfgAddr; /**< SMIF configuration structure */
|
||||
volatile uint32_t appAddr1; /**< First user application object address */
|
||||
volatile uint32_t appFormat1; /**< First user application format */
|
||||
volatile uint32_t appAddr2; /**< Second user application object address */
|
||||
volatile uint32_t appFormat2; /**< Second user application format */
|
||||
volatile uint32_t shashObj; /**< Number of additional objects to be verified (S-HASH) */
|
||||
volatile uint32_t sigKeyAddr; /**< Signature verification key address */
|
||||
volatile uint32_t addObj[116]; /**< Additional objects to include in S-HASH */
|
||||
volatile uint32_t tocFlags; /**< Flags in TOC to control Flash boot options */
|
||||
volatile uint32_t crc; /**< CRC16-CCITT */
|
||||
}cy_stc_si_toc_t;
|
||||
|
||||
/** User application header in Cypress format */
|
||||
typedef struct{
|
||||
volatile uint32_t objSize; /**< Object size (Bytes) */
|
||||
volatile uint32_t appId; /**< Application ID/version */
|
||||
volatile uint32_t appAttributes; /**< Attributes (reserved for future use) */
|
||||
volatile uint32_t numCores; /**< Number of cores */
|
||||
volatile uint32_t core0Vt; /**< (CM0+)VT offset - offset to the vector table from that entry */
|
||||
volatile uint32_t core1Vt; /**< (CM4)VT offset - offset to the vector table from that entry */
|
||||
volatile uint32_t core0Id; /**< CM0+ core ID */
|
||||
volatile uint32_t core1Id; /**< CM4 core ID */
|
||||
}cy_stc_user_appheader_t;
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CY_SI_CONFIG_H_ */
|
||||
|
||||
/* [] END OF FILE */
|
297
2020TPCApp1.cydsn/debug.c
Normal file
297
2020TPCApp1.cydsn/debug.c
Normal file
|
@ -0,0 +1,297 @@
|
|||
/*******************************************************************************
|
||||
* File Name: debug.c
|
||||
*
|
||||
* Version: 1.0
|
||||
*
|
||||
* Description:
|
||||
* This file contains functions for printf functionality.
|
||||
*
|
||||
* Hardware Dependency:
|
||||
* CY8CKIT-062 PSoC6 BLE Pioneer Kit
|
||||
*
|
||||
********************************************************************************
|
||||
* Copyright 2017, Cypress Semiconductor Corporation. All rights reserved.
|
||||
* You may use this file only in accordance with the license, terms, conditions,
|
||||
* disclaimers, and limitations in the end user license agreement accompanying
|
||||
* the software package with which this file was provided.
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#include "common.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
#if (DEBUG_UART_ENABLED == ENABLED)
|
||||
|
||||
#if defined(__ARMCC_VERSION)
|
||||
|
||||
/* For MDK/RVDS compiler revise fputc function for printf functionality */
|
||||
struct __FILE
|
||||
{
|
||||
int handle;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
STDIN_HANDLE,
|
||||
STDOUT_HANDLE,
|
||||
STDERR_HANDLE
|
||||
};
|
||||
|
||||
FILE __stdin = {STDIN_HANDLE};
|
||||
FILE __stdout = {STDOUT_HANDLE};
|
||||
FILE __stderr = {STDERR_HANDLE};
|
||||
|
||||
int fputc(int ch, FILE *file)
|
||||
{
|
||||
int ret = EOF;
|
||||
|
||||
switch( file->handle )
|
||||
{
|
||||
case STDOUT_HANDLE:
|
||||
UART_DEB_PUT_CHAR(ch);
|
||||
ret = ch ;
|
||||
break ;
|
||||
|
||||
case STDERR_HANDLE:
|
||||
ret = ch ;
|
||||
break ;
|
||||
|
||||
default:
|
||||
file = file;
|
||||
break ;
|
||||
}
|
||||
return ret ;
|
||||
}
|
||||
|
||||
#elif defined (__ICCARM__) /* IAR */
|
||||
|
||||
/* For IAR compiler revise __write() function for printf functionality */
|
||||
size_t __write(int handle, const unsigned char * buffer, size_t size)
|
||||
{
|
||||
size_t nChars = 0;
|
||||
|
||||
if (buffer == 0)
|
||||
{
|
||||
/*
|
||||
* This means that we should flush internal buffers. Since we
|
||||
* don't we just return. (Remember, "handle" == -1 means that all
|
||||
* handles should be flushed.)
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
for (/* Empty */; size != 0; --size)
|
||||
{
|
||||
UART_DEB_PUT_CHAR(*buffer);
|
||||
++buffer;
|
||||
++nChars;
|
||||
}
|
||||
|
||||
return (nChars);
|
||||
}
|
||||
|
||||
#else /* (__GNUC__) GCC */
|
||||
|
||||
/* For GCC compiler revise _write() function for printf functionality */
|
||||
int _write(int file, char *ptr, int len)
|
||||
{
|
||||
int i;
|
||||
file = file;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
UART_DEB_PUT_CHAR(*ptr);
|
||||
++ptr;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
#endif /* (__ARMCC_VERSION) */
|
||||
|
||||
#endif /* DEBUG_UART_ENABLED == ENABLED */
|
||||
|
||||
void ShowValue(cy_stc_ble_gatt_value_t *value)
|
||||
{
|
||||
int16_t i;
|
||||
|
||||
for(i = 0; i < value->len; i++)
|
||||
{
|
||||
DBG_PRINTF("%2.2x ", value->val[i]);
|
||||
}
|
||||
DBG_PRINTF("\r\n");
|
||||
}
|
||||
|
||||
|
||||
void Set32ByPtr(uint8_t ptr[], uint32_t value)
|
||||
{
|
||||
ptr[0u] = (uint8_t) value;
|
||||
ptr[1u] = (uint8_t) (value >> 8u);
|
||||
ptr[2u] = (uint8_t) (value >> 16u);
|
||||
ptr[3u] = (uint8_t) (value >> 24u);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name: ShowError
|
||||
********************************************************************************
|
||||
*
|
||||
* Summary:
|
||||
* Shows error condition: Turn On all LEDs - white color will indicate error.
|
||||
*
|
||||
*******************************************************************************/
|
||||
void ShowError(void)
|
||||
{
|
||||
EnableAllLeds();
|
||||
|
||||
/* Halt CPU in Debug mode */
|
||||
CY_ASSERT(0u != 0u);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name: HexToAscii
|
||||
********************************************************************************
|
||||
*
|
||||
* Summary:
|
||||
* Hexadecimal to ASCII converter
|
||||
*
|
||||
* Parameters:
|
||||
* value: Hexadecimal value
|
||||
* digit: Which nibble to be obtained
|
||||
*
|
||||
* Return:
|
||||
* char: the ASCII equivalent of that nibble
|
||||
*
|
||||
* Theory:
|
||||
* Converts hexadecimal to ASCII
|
||||
*
|
||||
*******************************************************************************/
|
||||
char HexToAscii(uint8_t value, uint8_t nibble)
|
||||
{
|
||||
if(nibble == 1)
|
||||
{
|
||||
value = value & 0xf0;
|
||||
value = value >> 4;
|
||||
|
||||
/* bit-shift the result to the right by four bits (i.e. quickly divides by 16) */
|
||||
if (value > 9)
|
||||
{
|
||||
value = value - 10 + 'A';
|
||||
}
|
||||
else
|
||||
{
|
||||
value = value + '0';
|
||||
}
|
||||
}
|
||||
else if (nibble == 0)
|
||||
{
|
||||
/* means use a bitwise AND to take the bottom four bits from the byte,
|
||||
0x0F is 00001111 in binary */
|
||||
value = value & 0x0F;
|
||||
if (value > 9)
|
||||
{
|
||||
value = value - 10 + 'A';
|
||||
}
|
||||
else
|
||||
{
|
||||
value = value + '0';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value = ' ';
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name: PrintStackVersion
|
||||
********************************************************************************
|
||||
*
|
||||
* Summary:
|
||||
* Prints the BLE Stack version if the PRINT_STACK_VERSION is defined.
|
||||
*
|
||||
*******************************************************************************/
|
||||
void PrintStackVersion(void)
|
||||
{
|
||||
cy_stc_ble_stack_lib_version_t stackVersion;
|
||||
cy_en_ble_api_result_t apiResult;
|
||||
|
||||
apiResult = Cy_BLE_GetStackLibraryVersion(&stackVersion);
|
||||
if(apiResult != CY_BLE_SUCCESS)
|
||||
{
|
||||
DBG_PRINTF("Cy_BLE_GetStackLibraryVersion API Error: ");
|
||||
PrintApiResult(apiResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG_PRINTF("BLE Stack Version: %d.%d.%d.%d\r\n", stackVersion.majorVersion,
|
||||
stackVersion.minorVersion,
|
||||
stackVersion.patch,
|
||||
stackVersion.buildNumber);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name: PrintApiResult
|
||||
********************************************************************************
|
||||
*
|
||||
* Summary:
|
||||
* Decodes and prints the apiResult global variable value.
|
||||
*
|
||||
*******************************************************************************/
|
||||
void PrintApiResult(cy_en_ble_api_result_t apiResult)
|
||||
{
|
||||
DBG_PRINTF("0x%2.2x ", apiResult);
|
||||
|
||||
switch(apiResult)
|
||||
{
|
||||
case CY_BLE_SUCCESS:
|
||||
DBG_PRINTF("ok\r\n");
|
||||
break;
|
||||
|
||||
case CY_BLE_ERROR_INVALID_PARAMETER:
|
||||
DBG_PRINTF("invalid parameter\r\n");
|
||||
break;
|
||||
|
||||
case CY_BLE_ERROR_INVALID_OPERATION:
|
||||
DBG_PRINTF("invalid operation\r\n");
|
||||
break;
|
||||
|
||||
case CY_BLE_ERROR_NO_DEVICE_ENTITY:
|
||||
DBG_PRINTF("no device entity\r\n");
|
||||
break;
|
||||
|
||||
case CY_BLE_ERROR_NTF_DISABLED:
|
||||
DBG_PRINTF("notification is disabled\r\n");
|
||||
break;
|
||||
|
||||
case CY_BLE_ERROR_IND_DISABLED:
|
||||
DBG_PRINTF("indication is disabled\r\n");
|
||||
break;
|
||||
|
||||
case CY_BLE_ERROR_CHAR_IS_NOT_DISCOVERED:
|
||||
DBG_PRINTF("characteristic is not discovered\r\n");
|
||||
break;
|
||||
|
||||
case CY_BLE_ERROR_INVALID_STATE:
|
||||
DBG_PRINTF("invalid state");
|
||||
break;
|
||||
|
||||
case CY_BLE_ERROR_GATT_DB_INVALID_ATTR_HANDLE:
|
||||
DBG_PRINTF("invalid attribute handle\r\n");
|
||||
break;
|
||||
|
||||
case CY_BLE_ERROR_FLASH_WRITE_NOT_PERMITED:
|
||||
DBG_PRINTF("flash write not permitted\r\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
DBG_PRINTF("other api result\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* [] END OF FILE */
|
251
2020TPCApp1.cydsn/dfu_cm0p.icf
Normal file
251
2020TPCApp1.cydsn/dfu_cm0p.icf
Normal file
|
@ -0,0 +1,251 @@
|
|||
/***************************************************************************//**
|
||||
* \file dfu_cm0p.icf
|
||||
* \version 3.0
|
||||
*
|
||||
* The linker file for the the IAR compiler.
|
||||
*
|
||||
* \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.
|
||||
*******************************************************************************/
|
||||
|
||||
/*-Editor annotation file-*/
|
||||
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Start of CM4 and CM0+ linker script common region
|
||||
*******************************************************************************/
|
||||
|
||||
/*-Memory Regions-*/
|
||||
/* 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;
|
||||
|
||||
|
||||
define memory mem with size = 4G;
|
||||
|
||||
/* Memory regions for all applications are defined here */
|
||||
define region FLASH_app0_core0 = mem:[from 0x10000000 size 0x10000];
|
||||
define region FLASH_app0_core1 = mem:[from 0x10010000 size 0x10000];
|
||||
define region FLASH_app1_core0 = mem:[from 0x10040000 size 0x10000];
|
||||
define region FLASH_app1_core1 = mem:[from 0x10050000 size 0x10000];
|
||||
|
||||
/*
|
||||
* The region for DFU SDK metadata
|
||||
* when it is outside of any application
|
||||
*/
|
||||
define region FLASH_boot_meta = mem:[from 0x100FFA00 size 0x200];
|
||||
|
||||
|
||||
/* eFuse */
|
||||
define region ROM_EFUSE = mem:[from 0x90700000 size 0x100000];
|
||||
|
||||
/* SFlash NAR */
|
||||
define region SFLASH_NAR = mem:[from 0x16001A00 size 0x200];
|
||||
|
||||
/* SFlash User Data */
|
||||
define region SFLASH_USER_DATA = mem:[from 0x16000800 size 0x800];
|
||||
|
||||
/* SFlash Public Key, 6 SFlash rows */
|
||||
define region SFLASH_PUBLIC_KEY = mem:[from 0x16005A00 size 0xC00];
|
||||
|
||||
/* Table of Content part 2, two SFlash rows */
|
||||
define region SFLASH_TOC = mem:[from 0x16007C00 size 0x400];
|
||||
|
||||
|
||||
/* Emulated EEPROM app regions */
|
||||
define region EM_EEPROM_app0_core0 = mem:[from 0x14000000 size 0x8000];
|
||||
define region EM_EEPROM_app0_core1 = mem:[from 0x14000000 size 0x8000];
|
||||
define region EM_EEPROM_app1_core0 = mem:[from 0x14000000 size 0x8000];
|
||||
define region EM_EEPROM_app1_core1 = mem:[from 0x14000000 size 0x8000];
|
||||
|
||||
/* XIP/SMIF app regions */
|
||||
define region EROM_app0_core0 = mem:[from 0x18000000 size 0x1000];
|
||||
define region EROM_app0_core1 = mem:[from 0x18000000 size 0x1000];
|
||||
define region EROM_app1_core0 = mem:[from 0x18000000 size 0x1000];
|
||||
define region EROM_app1_core1 = mem:[from 0x18000000 size 0x1000];
|
||||
|
||||
/* used for RAM sharing across applications */
|
||||
define region IRAM_common = mem:[from 0x08000000 size 0x0100];
|
||||
|
||||
/* note: all the IRAM_appX_core0 regions has to be 0x100 aligned */
|
||||
/* and the IRAM_appX_core1 regions has to be 0x400 aligned */
|
||||
/* as they contain Interrupt Vector Table Remapped at the start */
|
||||
define region IRAM_app0_core0 = mem:[from 0x08000100 size 0x1F00];
|
||||
define region IRAM_app0_core1 = mem:[from 0x08002000 size 0x8000];
|
||||
define region IRAM_app1_core0 = mem:[from 0x08000100 size 0x1F00];
|
||||
define region IRAM_app1_core1 = mem:[from 0x08002000 size 0x8000];
|
||||
|
||||
|
||||
/* Used by all DFU SDK and CyMCUElfTool */
|
||||
define exported symbol __cy_boot_metadata_addr = 0x100FFA00;
|
||||
define exported symbol __cy_boot_metadata_length = __cy_memory_0_row_size;
|
||||
|
||||
/* Used by CyMCUElfTool to generate ProductID for DFU SDK apps */
|
||||
define exported symbol __cy_product_id = 0x01020304;
|
||||
|
||||
/* Used by CyMCUElfTool to generate ChecksumType for DFU SDK apps */
|
||||
define exported symbol __cy_checksum_type = 0;
|
||||
|
||||
/*
|
||||
* The size of the application signature.
|
||||
* E.g. 4 for CRC-32,
|
||||
* 32 for SHA256,
|
||||
* 256 for RSA 2048.
|
||||
*/
|
||||
define exported symbol __cy_boot_signature_size = 4;
|
||||
|
||||
/* Used by DFU SDK projects, in dfu_user.c to fill in the metadata table */
|
||||
define exported symbol __cy_app0_verify_start = start(FLASH_app0_core0);
|
||||
define exported symbol __cy_app0_verify_length = size (FLASH_app0_core0) + size (FLASH_app0_core1)
|
||||
- __cy_boot_signature_size;
|
||||
|
||||
define exported symbol __cy_app1_verify_start = start(FLASH_app1_core0);
|
||||
define exported symbol __cy_app1_verify_length = size (FLASH_app1_core0) + size (FLASH_app1_core1)
|
||||
- __cy_boot_signature_size;
|
||||
|
||||
/*******************************************************************************
|
||||
* End of CM4 and CM0+ linker script common region
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* Used by CM0+ to start the CM4 core in DFU SDK applications.
|
||||
* Make sure the correct app no. is entered here.
|
||||
*/
|
||||
define exported symbol __cy_app_core1_start_addr = start(FLASH_app0_core1);
|
||||
|
||||
/* CyMCUElfTool uses this symbol to set a proper app number */
|
||||
define exported symbol __cy_app_id = 0;
|
||||
|
||||
/* CyMCUElfTool uses these to generate an application signature */
|
||||
/* The size of the default signature (CRC-32C) is 4 bytes */
|
||||
define exported symbol __cy_app_verify_start = start(FLASH_app0_core0);
|
||||
define exported symbol __cy_app_verify_length = size(FLASH_app0_core0) + size(FLASH_app0_core1)
|
||||
- __cy_boot_signature_size;
|
||||
|
||||
|
||||
/*-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;
|
||||
}
|
||||
|
||||
|
||||
define region IROM1_region = FLASH_app0_core0; /* Flash, user app */
|
||||
define region IROM2_region = EM_EEPROM_app0_core0; /* Emulated EEPROM */
|
||||
define region IROM3_region = SFLASH_USER_DATA; /* SFlash User Data */
|
||||
define region IROM4_region = SFLASH_NAR; /* SFlash NAR */
|
||||
define region IROM5_region = SFLASH_PUBLIC_KEY; /* SFlash Public Key */
|
||||
define region IROM6_region = SFLASH_TOC; /* SFlash TOC part 2 */
|
||||
define region IROM7_region = ROM_EFUSE; /* eFuse */
|
||||
define region EROM1_region = EROM_app0_core0; /* XIP / SMIF */
|
||||
define region IRAM1_region = IRAM_app0_core0; /* RAM */
|
||||
|
||||
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,
|
||||
section .cy_boot_noinit.appId, section .cy_boot_noinit };
|
||||
|
||||
|
||||
/*-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 };
|
||||
|
||||
/* eFuse */
|
||||
".cy_efuse" : place at start of IROM7_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 IRAM_common { readwrite section .cy_boot_noinit.appId };
|
||||
place in IRAM_common { readwrite section .cy_boot_noinit };
|
||||
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_sflash_toc_2,
|
||||
section .cy_efuse,
|
||||
section .cy_xip,
|
||||
section .cymeta,
|
||||
section .cy_boot_noinit,
|
||||
section .cy_boot_noinit.appId,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* EOF */
|
485
2020TPCApp1.cydsn/dfu_cm0p.ld
Normal file
485
2020TPCApp1.cydsn/dfu_cm0p.ld
Normal file
|
@ -0,0 +1,485 @@
|
|||
/***************************************************************************//**
|
||||
* \file dfu_cm0p.ld
|
||||
* \version 3.0
|
||||
*
|
||||
* The linker file for the GNU C compiler.
|
||||
* Used for DFU SDK core0 firmware projects.
|
||||
*
|
||||
* \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, 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)
|
||||
|
||||
|
||||
/*
|
||||
* Forces symbol to be added to the output file.
|
||||
* Otherwise linker may remove it if founds that it is not used in the project.
|
||||
* This command has the same effect as the -u command-line option.
|
||||
*/
|
||||
EXTERN(Reset_Handler)
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Start of CM4 and CM0+ linker script common region
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
* Memory regions, for each application and MCU core.
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
flash_app0_core0 (rx) : ORIGIN = 0x10000000, LENGTH = 0x10000
|
||||
flash_app0_core1 (rx) : ORIGIN = 0x10010000, LENGTH = 0x30000
|
||||
flash_app1_core0 (rx) : ORIGIN = 0x10040000, LENGTH = 0x30000
|
||||
flash_app1_core1 (rx) : ORIGIN = 0x10070000, LENGTH = 0x50000
|
||||
|
||||
flash_storage (rw) : ORIGIN = 0x100D0000, LENGTH = 0x1000
|
||||
flash_boot_meta (rw) : ORIGIN = 0x100FFA00, LENGTH = 0x400
|
||||
|
||||
sflash_user_data (rx) : ORIGIN = 0x16000800, LENGTH = 0x800
|
||||
sflash_nar (rx) : ORIGIN = 0x16001A00, LENGTH = 0x200
|
||||
sflash_public_key (rx) : ORIGIN = 0x16005A00, LENGTH = 0xC00
|
||||
sflash_toc_2 (rx) : ORIGIN = 0x16007C00, LENGTH = 0x400
|
||||
|
||||
efuse (r) : ORIGIN = 0x90700000, LENGTH = 0x100000
|
||||
|
||||
ram_common (rwx) : ORIGIN = 0x08000000, LENGTH = 0x0100
|
||||
|
||||
/* note: all the ram_appX_core0 regions has to be 0x100 aligned */
|
||||
/* and the ram_appX_core1 regions has to be 0x400 aligned */
|
||||
/* as they contain Interrupt Vector Table Remapped at the start */
|
||||
ram_app0_core0 (rwx) : ORIGIN = 0x08000100, LENGTH = 0x7F00
|
||||
ram_app0_core1 (rwx) : ORIGIN = 0x08008000, LENGTH = 0x8000
|
||||
|
||||
ram_app1_core0 (rwx) : ORIGIN = 0x08000100, LENGTH = 0x7F00
|
||||
ram_app1_core1 (rwx) : ORIGIN = 0x08008000, LENGTH = 0x30000
|
||||
|
||||
/* 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 */
|
||||
|
||||
xip (rx) : ORIGIN = 0x18000000, LENGTH = 0x08000000
|
||||
}
|
||||
|
||||
/* Regions parameters */
|
||||
/* 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;
|
||||
|
||||
/* The DFU SDK metadata limits */
|
||||
__cy_boot_metadata_addr = ORIGIN(flash_boot_meta);
|
||||
__cy_boot_metadata_length = __cy_memory_0_row_size;
|
||||
|
||||
/* The Product ID, used by CyMCUElfTool to generate a updating file */
|
||||
__cy_product_id = 0x01020304;
|
||||
|
||||
/* The checksum type used by CyMCUElfTool to generate a updating file */
|
||||
__cy_checksum_type = 0x00;
|
||||
|
||||
/* Used by the DFU SDK application to set the metadata */
|
||||
__cy_app0_verify_start = ORIGIN(flash_app0_core0);
|
||||
__cy_app0_verify_length = LENGTH(flash_app0_core0) + LENGTH(flash_app0_core1) - __cy_boot_signature_size;
|
||||
__cy_app1_verify_start = ORIGIN(flash_app1_core0);
|
||||
__cy_app1_verify_length = LENGTH(flash_app1_core0) + LENGTH(flash_app1_core1) - __cy_boot_signature_size;
|
||||
|
||||
/*
|
||||
* The size of the application signature.
|
||||
* E.g. 4 for CRC-32,
|
||||
* 32 for SHA256,
|
||||
* 256 for RSA 2048.
|
||||
*/
|
||||
__cy_boot_signature_size = 256;
|
||||
|
||||
/*******************************************************************************
|
||||
* End of CM4 and CM0+ linker script common region
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* DFU SDK specific: aliases regions, so the rest of code does not use
|
||||
* application specific memory region names
|
||||
*/
|
||||
REGION_ALIAS("flash", flash_app1_core0);
|
||||
REGION_ALIAS("flash_core1", flash_app1_core1);
|
||||
REGION_ALIAS("ram", ram_app1_core0);
|
||||
|
||||
/* DFU SDK specific: sets an app Id */
|
||||
__cy_app_id = 1;
|
||||
|
||||
/*
|
||||
* DFU SDK specific: sets a start address of the Core1 application image,
|
||||
* more specifically an address of the Core1 interrupt vector table.
|
||||
* CM0+ uses this information to launch Core1.
|
||||
*/
|
||||
__cy_app_core1_start_addr = ORIGIN(flash_core1); /* used to start Core1 from Core0 */
|
||||
|
||||
/* DFU SDK specific */
|
||||
/* CyMCUElfTool uses these ELF symbols to generate an application signature */
|
||||
__cy_app_verify_start = ORIGIN(flash);
|
||||
__cy_app_verify_length = LENGTH(flash) + LENGTH(flash_core1) - __cy_boot_signature_size;
|
||||
|
||||
|
||||
/* Library configurations */
|
||||
GROUP(libgcc.a libc.a libm.a libnosys.a)
|
||||
|
||||
/* The linker script defines how 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
|
||||
*
|
||||
* This linker script defines the symbols, which can be used by code without a 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
|
||||
*
|
||||
* For the DFU SDK, these additional symbols are defined:
|
||||
* __cy_app_id
|
||||
* __cy_product_id
|
||||
* __cy_checksum_type
|
||||
* __cy_app_core1_start_addr
|
||||
* __cy_boot_metadata_addr
|
||||
* __cy_boot_metadata_length
|
||||
*/
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* DFU SDK specific */
|
||||
/* The noinit section, used across all the applications */
|
||||
.cy_boot_noinit (NOLOAD) :
|
||||
{
|
||||
KEEP(*(.cy_boot_noinit));
|
||||
} > ram_common
|
||||
|
||||
/* The last byte of the section is used for AppId to be shared between all the applications */
|
||||
.cy_boot_noinit.appId ORIGIN(ram_common) + LENGTH(ram_common) - 1 (NOLOAD) :
|
||||
{
|
||||
KEEP(*(.cy_boot_noinit.appId));
|
||||
} > ram_common
|
||||
|
||||
/* App0 uses it to initialize DFU SDK metadata, in the dfu_user.c file */
|
||||
.cy_boot_metadata :
|
||||
{
|
||||
KEEP(*(.cy_boot_metadata))
|
||||
} > flash_boot_meta
|
||||
|
||||
.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 the RAM sections,
|
||||
* uncomment .copy.table section and,
|
||||
* define __STARTUP_COPY_MULTIPLE in startup_{device}_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_{device}_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 the linker that the .bss section does not consume
|
||||
* any space in the image. The NOLOAD attribute changes the .bss type to
|
||||
* NOBITS, and that makes the linker: A) not allocate the section in memory;
|
||||
* B) put information to clear the section with all zeros during application
|
||||
* loading.
|
||||
*
|
||||
* Without the NOLOAD attribute, the .bss section might get the PROGBITS type.
|
||||
* This makes the linker: A) allocate the zeroed section in memory; 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
|
||||
|
||||
|
||||
/* The .stack_dummy section doesn't contain any symbols. It is only
|
||||
* used for the linker to calculate the size of the stack sections, and assign
|
||||
* values to the stack symbols later */
|
||||
.stack_dummy (NOLOAD):
|
||||
{
|
||||
KEEP(*(.stack*))
|
||||
} > ram
|
||||
|
||||
|
||||
/* Set the stack top to the end of RAM, and the stack limit move down by
|
||||
* the size of the 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
|
||||
|
||||
|
||||
/* Places the code in the Execute in the 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
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
189
2020TPCApp1.cydsn/dfu_cm0p.scat
Normal file
189
2020TPCApp1.cydsn/dfu_cm0p.scat
Normal file
|
@ -0,0 +1,189 @@
|
|||
#! armcc -E
|
||||
; The first line specifies a preprocessor command that the linker invokes
|
||||
; to pass a scatter file through a C preprocessor.
|
||||
|
||||
;*******************************************************************************
|
||||
;* \file dfu_cm0p.scat
|
||||
;* \version 3.0
|
||||
;*
|
||||
;* The linker file for the ARMCC.
|
||||
;*
|
||||
;* \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.
|
||||
;******************************************************************************/
|
||||
|
||||
;* DFU SDK specific: includes defines common across all the applications
|
||||
#include "dfu_mdk_common.h"
|
||||
|
||||
;* DFU SDK specific: defines the memory regions
|
||||
;* Make sure the correct app no. is entered here.
|
||||
|
||||
; Flash
|
||||
#define FLASH_START CY_APP0_CORE0_FLASH_ADDR
|
||||
#define FLASH_SIZE CY_APP0_CORE0_FLASH_LENGTH
|
||||
|
||||
; Emulated EEPROM Flash area
|
||||
#define EM_EEPROM_START CY_APP0_CORE0_EM_EEPROM_ADDR
|
||||
#define EM_EEPROM_SIZE CY_APP0_CORE0_EM_EEPROM_LENGTH
|
||||
|
||||
; 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 0x00000400
|
||||
|
||||
; External memory
|
||||
#define XIP_START CY_APP0_CORE0_SMIF_ADDR
|
||||
#define XIP_SIZE CY_APP0_CORE0_SMIF_LENGTH
|
||||
|
||||
; eFuse
|
||||
#define EFUSE_START 0x90700000
|
||||
#define EFUSE_SIZE 0x100000
|
||||
|
||||
; RAM
|
||||
#define RAM_START CY_APP0_CORE0_RAM_ADDR
|
||||
#define RAM_SIZE CY_APP0_CORE0_RAM_LENGTH
|
||||
|
||||
|
||||
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_COMMON CY_APP_RAM_COMMON_ADDR UNINIT
|
||||
{
|
||||
* (.cy_boot_noinit.appId)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
; Places the code in the Execute in the 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 */
|
248
2020TPCApp1.cydsn/dfu_cm4.icf
Normal file
248
2020TPCApp1.cydsn/dfu_cm4.icf
Normal file
|
@ -0,0 +1,248 @@
|
|||
/***************************************************************************//**
|
||||
* \file dfu_cm4.icf
|
||||
* \version 3.0
|
||||
*
|
||||
* The linker file for the the IAR compiler.
|
||||
*
|
||||
* \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.
|
||||
*******************************************************************************/
|
||||
|
||||
/*-Editor annotation file-*/
|
||||
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Start of CM4 and CM0+ linker script common region
|
||||
*******************************************************************************/
|
||||
|
||||
/*-Memory Regions-*/
|
||||
/* 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;
|
||||
|
||||
|
||||
define memory mem with size = 4G;
|
||||
|
||||
/* Memory regions for all applications are defined here */
|
||||
define region FLASH_app0_core0 = mem:[from 0x10000000 size 0x10000];
|
||||
define region FLASH_app0_core1 = mem:[from 0x10010000 size 0x10000];
|
||||
define region FLASH_app1_core0 = mem:[from 0x10040000 size 0x10000];
|
||||
define region FLASH_app1_core1 = mem:[from 0x10050000 size 0x10000];
|
||||
|
||||
/*
|
||||
* The region for DFU SDK metadata
|
||||
* when it is outside of any application
|
||||
*/
|
||||
define region FLASH_boot_meta = mem:[from 0x100FFA00 size 0x200];
|
||||
|
||||
|
||||
/* eFuse */
|
||||
define region ROM_EFUSE = mem:[from 0x90700000 size 0x100000];
|
||||
|
||||
/* SFlash NAR */
|
||||
define region SFLASH_NAR = mem:[from 0x16001A00 size 0x200];
|
||||
|
||||
/* SFlash User Data */
|
||||
define region SFLASH_USER_DATA = mem:[from 0x16000800 size 0x800];
|
||||
|
||||
/* SFlash Public Key, 6 SFlash rows */
|
||||
define region SFLASH_PUBLIC_KEY = mem:[from 0x16005A00 size 0xC00];
|
||||
|
||||
/* Table of Content part 2, two SFlash rows */
|
||||
define region SFLASH_TOC = mem:[from 0x16007C00 size 0x400];
|
||||
|
||||
|
||||
/* Emulated EEPROM app regions */
|
||||
define region EM_EEPROM_app0_core0 = mem:[from 0x14000000 size 0x8000];
|
||||
define region EM_EEPROM_app0_core1 = mem:[from 0x14000000 size 0x8000];
|
||||
define region EM_EEPROM_app1_core0 = mem:[from 0x14000000 size 0x8000];
|
||||
define region EM_EEPROM_app1_core1 = mem:[from 0x14000000 size 0x8000];
|
||||
|
||||
/* XIP/SMIF app regions */
|
||||
define region EROM_app0_core0 = mem:[from 0x18000000 size 0x1000];
|
||||
define region EROM_app0_core1 = mem:[from 0x18000000 size 0x1000];
|
||||
define region EROM_app1_core0 = mem:[from 0x18000000 size 0x1000];
|
||||
define region EROM_app1_core1 = mem:[from 0x18000000 size 0x1000];
|
||||
|
||||
/* used for RAM sharing across applications */
|
||||
define region IRAM_common = mem:[from 0x08000000 size 0x0100];
|
||||
|
||||
/* note: all the IRAM_appX_core0 regions has to be 0x100 aligned */
|
||||
/* and the IRAM_appX_core1 regions has to be 0x400 aligned */
|
||||
/* as they contain Interrupt Vector Table Remapped at the start */
|
||||
define region IRAM_app0_core0 = mem:[from 0x08000100 size 0x1F00];
|
||||
define region IRAM_app0_core1 = mem:[from 0x08002000 size 0x8000];
|
||||
define region IRAM_app1_core0 = mem:[from 0x08000100 size 0x1F00];
|
||||
define region IRAM_app1_core1 = mem:[from 0x08002000 size 0x8000];
|
||||
|
||||
|
||||
/* Used by all DFU SDK and CyMCUElfTool */
|
||||
define exported symbol __cy_boot_metadata_addr = 0x100FFA00;
|
||||
define exported symbol __cy_boot_metadata_length = __cy_memory_0_row_size;
|
||||
|
||||
/* Used by CyMCUElfTool to generate ProductID for DFU SDK apps */
|
||||
define exported symbol __cy_product_id = 0x01020304;
|
||||
|
||||
/* Used by CyMCUElfTool to generate ChecksumType for DFU SDK apps */
|
||||
define exported symbol __cy_checksum_type = 0;
|
||||
|
||||
/*
|
||||
* The size of the application signature.
|
||||
* E.g. 4 for CRC-32,
|
||||
* 32 for SHA256,
|
||||
* 256 for RSA 2048.
|
||||
*/
|
||||
define exported symbol __cy_boot_signature_size = 4;
|
||||
|
||||
/* Used by DFU SDK projects, in dfu_user.c to fill in the metadata table */
|
||||
define exported symbol __cy_app0_verify_start = start(FLASH_app0_core0);
|
||||
define exported symbol __cy_app0_verify_length = size (FLASH_app0_core0) + size (FLASH_app0_core1)
|
||||
- __cy_boot_signature_size;
|
||||
|
||||
define exported symbol __cy_app1_verify_start = start(FLASH_app1_core0);
|
||||
define exported symbol __cy_app1_verify_length = size (FLASH_app1_core0) + size (FLASH_app1_core1)
|
||||
- __cy_boot_signature_size;
|
||||
|
||||
/*******************************************************************************
|
||||
* End of CM4 and CM0+ linker script common region
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/* CyMCUElfTool uses this symbol to set a proper app number */
|
||||
define exported symbol __cy_app_id = 0;
|
||||
|
||||
/* CyMCUElfTool uses these to generate an application signature */
|
||||
/* The size of the default signature (CRC-32C) is 4 bytes */
|
||||
define exported symbol __cy_app_verify_start = start(FLASH_app0_core0);
|
||||
define exported symbol __cy_app_verify_length = size(FLASH_app0_core0) + size(FLASH_app0_core1)
|
||||
- __cy_boot_signature_size;
|
||||
|
||||
|
||||
/*-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;
|
||||
}
|
||||
|
||||
|
||||
define region IROM1_region = FLASH_app0_core1; /* Flash, user app */
|
||||
define region IROM2_region = EM_EEPROM_app0_core1; /* Emulated EEPROM */
|
||||
define region IROM3_region = SFLASH_USER_DATA; /* SFlash User Data */
|
||||
define region IROM4_region = SFLASH_NAR; /* SFlash NAR */
|
||||
define region IROM5_region = SFLASH_PUBLIC_KEY; /* SFlash Public Key */
|
||||
define region IROM6_region = SFLASH_TOC; /* SFlash TOC part 2 */
|
||||
define region IROM7_region = ROM_EFUSE; /* eFuse */
|
||||
define region EROM1_region = EROM_app0_core1; /* XIP / SMIF */
|
||||
define region IRAM1_region = IRAM_app0_core1; /* RAM */
|
||||
|
||||
|
||||
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,
|
||||
section .cy_boot_noinit.appId, section .cy_boot_noinit };
|
||||
|
||||
|
||||
/*-Placement-*/
|
||||
|
||||
/* Flash */
|
||||
place at start of IROM1_region { block RO };
|
||||
".cy_app_signature": place at end of IROM1_region { 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 };
|
||||
|
||||
/* eFuse */
|
||||
".cy_efuse" : place at start of IROM7_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 IRAM_common { readwrite section .cy_boot_noinit.appId };
|
||||
place in IRAM_common { readwrite section .cy_boot_noinit };
|
||||
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 };
|
||||
|
||||
/* App0 uses it to initialize DFU SDK metadata, in the dfu_user.c file */
|
||||
".cy_boot_metadata" : place at start of FLASH_boot_meta { section .cy_boot_metadata };
|
||||
|
||||
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_sflash_toc_2,
|
||||
section .cy_efuse,
|
||||
section .cy_xip,
|
||||
section .cymeta,
|
||||
section .cy_boot_metadata,
|
||||
section .cy_boot_noinit,
|
||||
section .cy_boot_noinit.appId,
|
||||
};
|
||||
|
||||
|
||||
/* EOF */
|
484
2020TPCApp1.cydsn/dfu_cm4.ld
Normal file
484
2020TPCApp1.cydsn/dfu_cm4.ld
Normal file
|
@ -0,0 +1,484 @@
|
|||
/***************************************************************************//**
|
||||
* \file dfu_cm4.ld
|
||||
* \version 3.0
|
||||
*
|
||||
* The linker file for the GNU C compiler.
|
||||
* Used for DFU SDK core1 firmware projects.
|
||||
*
|
||||
* \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, 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)
|
||||
|
||||
|
||||
/*
|
||||
* Forces symbol to be added to the output file.
|
||||
* Otherwise linker may remove it if founds that it is not used in the project.
|
||||
* This command has the same effect as the -u command-line option.
|
||||
*/
|
||||
EXTERN(Reset_Handler)
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Start of CM4 and CM0+ linker script common region
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
* Memory regions, for each application and MCU core.
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
flash_app0_core0 (rx) : ORIGIN = 0x10000000, LENGTH = 0x10000
|
||||
flash_app0_core1 (rx) : ORIGIN = 0x10010000, LENGTH = 0x30000
|
||||
flash_app1_core0 (rx) : ORIGIN = 0x10040000, LENGTH = 0x30000
|
||||
flash_app1_core1 (rx) : ORIGIN = 0x10070000, LENGTH = 0x50000
|
||||
|
||||
flash_storage (rw) : ORIGIN = 0x100D0000, LENGTH = 0x1000
|
||||
flash_boot_meta (rw) : ORIGIN = 0x100FFA00, LENGTH = 0x400
|
||||
|
||||
sflash_user_data (rx) : ORIGIN = 0x16000800, LENGTH = 0x800
|
||||
sflash_nar (rx) : ORIGIN = 0x16001A00, LENGTH = 0x200
|
||||
sflash_public_key (rx) : ORIGIN = 0x16005A00, LENGTH = 0xC00
|
||||
sflash_toc_2 (rx) : ORIGIN = 0x16007C00, LENGTH = 0x400
|
||||
|
||||
efuse (r) : ORIGIN = 0x90700000, LENGTH = 0x100000
|
||||
|
||||
ram_common (rwx) : ORIGIN = 0x08000000, LENGTH = 0x0100
|
||||
|
||||
/* note: all the ram_appX_core0 regions has to be 0x100 aligned */
|
||||
/* and the ram_appX_core1 regions has to be 0x400 aligned */
|
||||
/* as they contain Interrupt Vector Table Remapped at the start */
|
||||
ram_app0_core0 (rwx) : ORIGIN = 0x08000100, LENGTH = 0x7F00
|
||||
ram_app0_core1 (rwx) : ORIGIN = 0x08008000, LENGTH = 0x8000
|
||||
|
||||
ram_app1_core0 (rwx) : ORIGIN = 0x08000100, LENGTH = 0x7F00
|
||||
ram_app1_core1 (rwx) : ORIGIN = 0x08008000, LENGTH = 0x30000
|
||||
|
||||
/* 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 */
|
||||
|
||||
xip (rx) : ORIGIN = 0x18000000, LENGTH = 0x08000000
|
||||
}
|
||||
|
||||
/* Regions parameters */
|
||||
/* 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;
|
||||
|
||||
/* The DFU SDK metadata limits */
|
||||
__cy_boot_metadata_addr = ORIGIN(flash_boot_meta);
|
||||
__cy_boot_metadata_length = __cy_memory_0_row_size;
|
||||
|
||||
/* The Product ID, used by CyMCUElfTool to generate a updating file */
|
||||
__cy_product_id = 0x01020304;
|
||||
|
||||
/* The checksum type used by CyMCUElfTool to generate a updating file */
|
||||
__cy_checksum_type = 0x00;
|
||||
|
||||
/* Used by the DFU SDK application to set the metadata */
|
||||
__cy_app0_verify_start = ORIGIN(flash_app0_core0);
|
||||
__cy_app0_verify_length = LENGTH(flash_app0_core0) + LENGTH(flash_app0_core1) - __cy_boot_signature_size;
|
||||
__cy_app1_verify_start = ORIGIN(flash_app1_core0);
|
||||
__cy_app1_verify_length = LENGTH(flash_app1_core0) + LENGTH(flash_app1_core1) - __cy_boot_signature_size;
|
||||
|
||||
/*
|
||||
* The size of the application signature.
|
||||
* E.g. 4 for CRC-32,
|
||||
* 32 for SHA256,
|
||||
* 256 for RSA 2048.
|
||||
*/
|
||||
__cy_boot_signature_size = 256;
|
||||
|
||||
/*******************************************************************************
|
||||
* End of CM4 and CM0+ linker script common region
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* DFU SDK specific: aliases regions, so the rest of code does not use
|
||||
* application specific memory region names
|
||||
*/
|
||||
REGION_ALIAS("flash_core0", flash_app1_core0);
|
||||
REGION_ALIAS("flash", flash_app1_core1);
|
||||
REGION_ALIAS("ram", ram_app1_core1);
|
||||
|
||||
/* DFU SDK specific: sets an app Id */
|
||||
__cy_app_id = 1;
|
||||
|
||||
|
||||
/* DFU SDK specific */
|
||||
/* CyMCUElfTool uses these ELF symbols to generate an application signature */
|
||||
__cy_app_verify_start = ORIGIN(flash_core0);
|
||||
__cy_app_verify_length = LENGTH(flash_core0) + LENGTH(flash) - __cy_boot_signature_size;
|
||||
|
||||
|
||||
/* Library configurations */
|
||||
GROUP(libgcc.a libc.a libm.a libnosys.a)
|
||||
|
||||
/* The linker script defines how 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
|
||||
*
|
||||
* This linker script defines the symbols, which can be used by code without a 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
|
||||
*
|
||||
* For the DFU SDK, these additional symbols are defined:
|
||||
* __cy_app_id
|
||||
* __cy_product_id
|
||||
* __cy_checksum_type
|
||||
* __cy_app_core1_start_addr
|
||||
* __cy_boot_metadata_addr
|
||||
* __cy_boot_metadata_length
|
||||
*/
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* DFU SDK specific */
|
||||
/* The noinit section, used across all the applications */
|
||||
.cy_boot_noinit (NOLOAD) :
|
||||
{
|
||||
KEEP(*(.cy_boot_noinit));
|
||||
} > ram_common
|
||||
|
||||
/* The last byte of the section is used for AppId to be shared between all the applications */
|
||||
.cy_boot_noinit.appId ORIGIN(ram_common) + LENGTH(ram_common) - 1 (NOLOAD) :
|
||||
{
|
||||
KEEP(*(.cy_boot_noinit.appId));
|
||||
} > ram_common
|
||||
|
||||
/* App0 uses it to initialize DFU SDK metadata, in the dfu_user.c file */
|
||||
.cy_boot_metadata :
|
||||
{
|
||||
KEEP(*(.cy_boot_metadata))
|
||||
} > flash_boot_meta
|
||||
|
||||
|
||||
.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 the RAM sections,
|
||||
* uncomment .copy.table section and,
|
||||
* define __STARTUP_COPY_MULTIPLE in startup_{device}_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_{device}_cm4.S */
|
||||
.zero.table :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__zero_table_start__ = .;
|
||||
LONG (__bss_start__)
|
||||
LONG (__bss_end__ - __bss_start__)
|
||||
__zero_table_end__ = .;
|
||||
} > flash
|
||||
|
||||
__etext = . ;
|
||||
|
||||
/*
|
||||
* The DFU SDK section for an app verification signature.
|
||||
* Must be placed at the end of the application.
|
||||
* In this case, last N bytes of the last Flash row inside the application.
|
||||
*/
|
||||
.cy_app_signature ABSOLUTE(ORIGIN(flash) + LENGTH(flash) - __cy_boot_signature_size) :
|
||||
{
|
||||
KEEP(*(.cy_app_signature))
|
||||
} > flash = 0
|
||||
|
||||
.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 the linker that the .bss section does not consume
|
||||
* any space in the image. The NOLOAD attribute changes the .bss type to
|
||||
* NOBITS, and that makes the linker: A) not allocate the section in memory;
|
||||
* B) put information to clear the section with all zeros during application
|
||||
* loading.
|
||||
*
|
||||
* Without the NOLOAD attribute, the .bss section might get the PROGBITS type.
|
||||
* This makes the linker: A) allocate the zeroed section in memory; 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
|
||||
|
||||
|
||||
/* The .stack_dummy section doesn't contain any symbols. It is only
|
||||
* used for the linker to calculate the size of the stack sections, and assign
|
||||
* values to the stack symbols later */
|
||||
.stack_dummy (NOLOAD):
|
||||
{
|
||||
KEEP(*(.stack*))
|
||||
} > ram
|
||||
|
||||
|
||||
/* Set the stack top to the end of RAM, and the stack limit move down by
|
||||
* the size of the 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
|
||||
|
||||
|
||||
/* Places the code in the Execute in the 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
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
206
2020TPCApp1.cydsn/dfu_cm4.scat
Normal file
206
2020TPCApp1.cydsn/dfu_cm4.scat
Normal file
|
@ -0,0 +1,206 @@
|
|||
#! armcc -E
|
||||
; The first line specifies a preprocessor command that the linker invokes
|
||||
; to pass a scatter file through a C preprocessor.
|
||||
|
||||
;*******************************************************************************
|
||||
;* \file dfu_cm4.scat
|
||||
;* \version 3.0
|
||||
;*
|
||||
;* The linker file for the ARMCC.
|
||||
;*
|
||||
;* \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.
|
||||
;******************************************************************************/
|
||||
|
||||
;* DFU SDK specific: includes defines common across all the applications
|
||||
#include "dfu_mdk_common.h"
|
||||
|
||||
;* DFU SDK specific: defines the memory regions
|
||||
;* Make sure the correct app no. is entered here
|
||||
|
||||
; Flash
|
||||
#define FLASH_START CY_APP0_CORE1_FLASH_ADDR
|
||||
#define FLASH_SIZE CY_APP0_CORE1_FLASH_LENGTH
|
||||
|
||||
; Flash Toc
|
||||
#define FLASH_TOC_START CY_TOC_START
|
||||
#define FLASH_TOC_SIZE CY_TOC_SIZE
|
||||
|
||||
; Emulated EEPROM Flash area
|
||||
#define EM_EEPROM_START CY_APP0_CORE1_EM_EEPROM_ADDR
|
||||
#define EM_EEPROM_SIZE CY_APP0_CORE1_EM_EEPROM_LENGTH
|
||||
|
||||
; 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 0x00000400
|
||||
|
||||
; External memory
|
||||
#define XIP_START CY_APP0_CORE1_SMIF_ADDR
|
||||
#define XIP_SIZE CY_APP0_CORE1_SMIF_LENGTH
|
||||
|
||||
; eFuse
|
||||
#define EFUSE_START 0x90700000
|
||||
#define EFUSE_SIZE 0x100000
|
||||
|
||||
; RAM
|
||||
#define RAM_START CY_APP0_CORE1_RAM_ADDR
|
||||
#define RAM_SIZE CY_APP0_CORE1_RAM_LENGTH
|
||||
|
||||
|
||||
LR_FLASH FLASH_START FLASH_SIZE
|
||||
{
|
||||
ER_FLASH_VECTORS +0
|
||||
{
|
||||
* (RESET, +FIRST)
|
||||
}
|
||||
|
||||
ER_FLASH_CODE +0 FIXED
|
||||
{
|
||||
* (InRoot$$Sections)
|
||||
* (+RO)
|
||||
}
|
||||
|
||||
ER_RAM_COMMON CY_APP_RAM_COMMON_ADDR UNINIT
|
||||
{
|
||||
* (.cy_boot_noinit.appId)
|
||||
}
|
||||
|
||||
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
|
||||
; a device startup.
|
||||
ER_RAM_NOINIT_DATA +0 UNINIT
|
||||
{
|
||||
* (.noinit)
|
||||
}
|
||||
|
||||
|
||||
; Used for the digital signature of the secure application and the
|
||||
; DFU SDK application. The size of the section depends on the required
|
||||
; data size.
|
||||
.cy_app_signature (FLASH_START + FLASH_SIZE - CY_BOOT_SIGNATURE_SIZE) FIXED
|
||||
{
|
||||
* (.cy_app_signature)
|
||||
}
|
||||
}
|
||||
|
||||
; App0 uses it to initialize DFU SDK metadata, in dfu_user.c file
|
||||
LR_CY_BOOT_METADATA CY_BOOT_META_FLASH_ADDR CY_BOOT_META_FLASH_LENGTH
|
||||
{
|
||||
.cy_boot_metadata + 0
|
||||
{
|
||||
* (.cy_boot_metadata)
|
||||
}
|
||||
}
|
||||
|
||||
; 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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
; 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 */
|
114
2020TPCApp1.cydsn/dfu_mdk_common.h
Normal file
114
2020TPCApp1.cydsn/dfu_mdk_common.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*******************************************************************************
|
||||
* \file dfu_mdk_common.h
|
||||
* \version 3.0
|
||||
*
|
||||
* This file provides only macro definitions to use for
|
||||
* project configuration.
|
||||
* They may be used in both scatter files and source code files.
|
||||
*
|
||||
********************************************************************************
|
||||
* \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 DFU_MDK_COMMON_H_
|
||||
#define DFU_MDK_COMMON_H_
|
||||
|
||||
/* DFU SDK parameters */
|
||||
/* The user application may either update them or leave the defaults if they fit */
|
||||
#define CY_BOOT_METADATA_ADDR 0x100FFA00
|
||||
#define CY_BOOT_METADATA_LENGTH 0x200
|
||||
#define CY_PRODUCT_ID 0x01020304
|
||||
#define CY_CHECKSUM_TYPE 0x00
|
||||
|
||||
/*
|
||||
* The size of the section .cy_app_signature.
|
||||
* 1,2, or 4 for a checksum
|
||||
* 4 for CRC-32
|
||||
* 20 for SHA1
|
||||
* 32 for SHA256
|
||||
* 256 for RSASSA-PKCS1-v1.5 with the 2048 bit RSA key.
|
||||
*
|
||||
* SHA1 must be used.
|
||||
*/
|
||||
#define CY_BOOT_SIGNATURE_SIZE 4
|
||||
|
||||
/* For the MDK linker script, defines TOC parameters */
|
||||
/* Update per device series to be in the last Flash row */
|
||||
#define CY_TOC_START 0x16007C00
|
||||
#define CY_TOC_SIZE 0x400
|
||||
|
||||
|
||||
/* Memory region ranges per core and app */
|
||||
#define CY_APP0_CORE0_FLASH_ADDR 0x10000000
|
||||
#define CY_APP0_CORE0_FLASH_LENGTH 0x10000
|
||||
|
||||
#define CY_APP0_CORE1_FLASH_ADDR 0x10010000
|
||||
#define CY_APP0_CORE1_FLASH_LENGTH 0x10000
|
||||
|
||||
#define CY_APP1_CORE0_FLASH_ADDR 0x10040000
|
||||
#define CY_APP1_CORE0_FLASH_LENGTH 0x10000
|
||||
|
||||
#define CY_APP1_CORE1_FLASH_ADDR 0x10050000
|
||||
#define CY_APP1_CORE1_FLASH_LENGTH 0x10000
|
||||
|
||||
/* DFU SDK metadata address range in Flash */
|
||||
#define CY_BOOT_META_FLASH_ADDR 0x100FFA00
|
||||
#define CY_BOOT_META_FLASH_LENGTH 0x200
|
||||
|
||||
/* Application ranges in emulated EEPROM */
|
||||
#define CY_APP0_CORE0_EM_EEPROM_ADDR 0x14000000
|
||||
#define CY_APP0_CORE0_EM_EEPROM_LENGTH 0x00000000
|
||||
|
||||
#define CY_APP0_CORE1_EM_EEPROM_ADDR (CY_APP0_CORE0_EM_EEPROM_ADDR + CY_APP0_CORE0_EM_EEPROM_LENGTH)
|
||||
#define CY_APP0_CORE1_EM_EEPROM_LENGTH 0x0000
|
||||
|
||||
#define CY_APP1_CORE0_EM_EEPROM_ADDR 0x14000000
|
||||
#define CY_APP1_CORE0_EM_EEPROM_LENGTH 0x00000000
|
||||
|
||||
#define CY_APP1_CORE1_EM_EEPROM_ADDR (CY_APP1_CORE0_EM_EEPROM_ADDR + CY_APP1_CORE0_EM_EEPROM_LENGTH)
|
||||
#define CY_APP1_CORE1_EM_EEPROM_LENGTH 0x00000000
|
||||
|
||||
/* Application ranges in SMIF XIP */
|
||||
#define CY_APP0_CORE0_SMIF_ADDR 0x18000000
|
||||
#define CY_APP0_CORE0_SMIF_LENGTH 0x00000000
|
||||
|
||||
#define CY_APP0_CORE1_SMIF_ADDR (CY_APP0_CORE0_SMIF_ADDR + CY_APP0_CORE0_SMIF_LENGTH)
|
||||
#define CY_APP0_CORE1_SMIF_LENGTH 0x00000000
|
||||
|
||||
#define CY_APP1_CORE0_SMIF_ADDR 0x14000200
|
||||
#define CY_APP1_CORE0_SMIF_LENGTH 0x00000000
|
||||
|
||||
#define CY_APP1_CORE1_SMIF_ADDR (CY_APP1_CORE0_SMIF_ADDR + CY_APP1_CORE0_SMIF_LENGTH)
|
||||
#define CY_APP1_CORE1_SMIF_LENGTH 0x00000000
|
||||
|
||||
/* Application ranges in RAM */
|
||||
#define CY_APP_RAM_COMMON_ADDR 0x08000000
|
||||
#define CY_APP_RAM_COMMON_LENGTH 0x00000100
|
||||
|
||||
/* note: all the CY_APPX_CORE0_RAM regions has to be 0x100 aligned */
|
||||
/* and the CY_APPX_CORE1_RAM regions has to be 0x400 aligned */
|
||||
/* as they contain Interrupt Vector Table Remapped at the start */
|
||||
|
||||
#define CY_APP0_CORE0_RAM_ADDR 0x08000100
|
||||
#define CY_APP0_CORE0_RAM_LENGTH 0x00001F00
|
||||
|
||||
#define CY_APP0_CORE1_RAM_ADDR (CY_APP0_CORE0_RAM_ADDR + CY_APP0_CORE0_RAM_LENGTH)
|
||||
#define CY_APP0_CORE1_RAM_LENGTH 0x00008000
|
||||
|
||||
#define CY_APP1_CORE0_RAM_ADDR CY_APP0_CORE0_RAM_ADDR
|
||||
#define CY_APP1_CORE0_RAM_LENGTH 0x00001F00
|
||||
|
||||
#define CY_APP1_CORE1_RAM_ADDR (CY_APP1_CORE0_RAM_ADDR + CY_APP1_CORE0_RAM_LENGTH)
|
||||
#define CY_APP1_CORE1_RAM_LENGTH 0x00008000
|
||||
|
||||
|
||||
__asm void cy_DFU_mdkAsmDummy(void);
|
||||
|
||||
#endif /* DFU_MDK_COMMON_H_ */
|
||||
|
||||
|
||||
/* [] END OF FILE */
|
66
2020TPCApp1.cydsn/dfu_mdk_symbols.c
Normal file
66
2020TPCApp1.cydsn/dfu_mdk_symbols.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*******************************************************************************
|
||||
* \file dfu_mdk_symbols.c
|
||||
* \version 3.0
|
||||
*
|
||||
* This file provides symbols to add to an ELF file required by
|
||||
* CyMCUElfTool to generate correct HEX and CYACD2 files.
|
||||
*
|
||||
********************************************************************************
|
||||
* \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 "dfu_mdk_common.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name: cy_DFU_mdkAsmDummy
|
||||
********************************************************************************
|
||||
* This function provides ELF file symbols through
|
||||
* the inline assembly.
|
||||
* The inline assembly in the *.c file is chosen, because it allows using
|
||||
* #include <mdk_linker_common.h> where the user configuration is updated.
|
||||
*
|
||||
* Note that this function does not have code, so no additional memory
|
||||
* is allocated for it.
|
||||
*******************************************************************************/
|
||||
__asm void cy_DFU_mdkAsmDummy(void)
|
||||
{
|
||||
EXPORT __cy_boot_metadata_addr
|
||||
EXPORT __cy_boot_metadata_length
|
||||
|
||||
EXPORT __cy_app_core1_start_addr
|
||||
|
||||
EXPORT __cy_product_id
|
||||
EXPORT __cy_checksum_type
|
||||
EXPORT __cy_app_id
|
||||
|
||||
EXPORT __cy_app_verify_start
|
||||
EXPORT __cy_app_verify_length
|
||||
|
||||
/* Used by all DFU SDK applications to switch to another app */
|
||||
__cy_boot_metadata_addr EQU __cpp(CY_BOOT_METADATA_ADDR)
|
||||
/* Used by CyMCUElfTool to update DFU SDK metadata with CRC-32C */
|
||||
__cy_boot_metadata_length EQU __cpp(CY_BOOT_METADATA_LENGTH)
|
||||
|
||||
/* Used by CM0+ to start CM4 core in the DFU SDK applications. */
|
||||
/* Make sure the correct app no. is entered here */
|
||||
__cy_app_core1_start_addr EQU __cpp(CY_APP0_CORE1_FLASH_ADDR)
|
||||
|
||||
/* Used by CyMCUElfTool to generate ProductID */
|
||||
__cy_product_id EQU __cpp(CY_PRODUCT_ID)
|
||||
/* Used by CyMCUElfTool to generate ChecksumType */
|
||||
__cy_checksum_type EQU __cpp(CY_CHECKSUM_TYPE)
|
||||
/* Application number (ID) */
|
||||
__cy_app_id EQU 0
|
||||
|
||||
/* CyMCUElfTool uses these to generate an application signature */
|
||||
/* The size of the default signature (CRC-32C) is 4 bytes */
|
||||
__cy_app_verify_start EQU __cpp(CY_APP0_CORE0_FLASH_ADDR)
|
||||
__cy_app_verify_length EQU __cpp(CY_APP0_CORE0_FLASH_LENGTH + CY_APP0_CORE1_FLASH_LENGTH - CY_BOOT_SIGNATURE_SIZE)
|
||||
}
|
||||
|
||||
|
||||
/* [] END OF FILE */
|
151
2020TPCApp1.cydsn/dfu_user.h
Normal file
151
2020TPCApp1.cydsn/dfu_user.h
Normal file
|
@ -0,0 +1,151 @@
|
|||
/***************************************************************************//**
|
||||
* \file dfu_user.h
|
||||
* \version 3.0
|
||||
*
|
||||
* This file provides declarations that can be modified by the user but
|
||||
* are used by the DFU SDK.
|
||||
*
|
||||
********************************************************************************
|
||||
* \copyright
|
||||
* Copyright 2016-2019, Cypress Semiconductor Corporation. All rights reserved.
|
||||
* You may use this file only in accordance with the license, terms, conditions,
|
||||
* disclaimers, and limitations in the end user license agreement accompanying
|
||||
* the software package with which this file was provided.
|
||||
*******************************************************************************/
|
||||
|
||||
#if !defined(DFU_USER_H)
|
||||
#define DFU_USER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cy_flash.h"
|
||||
|
||||
|
||||
/**
|
||||
* \addtogroup group_dfu_macro_config
|
||||
* \{
|
||||
*/
|
||||
|
||||
/** The size of a buffer to hold DFU commands */
|
||||
/* 16 bytes is a maximum overhead of a DFU packet and additional data for the Program Data command */
|
||||
#define CY_DFU_SIZEOF_CMD_BUFFER (CY_FLASH_SIZEOF_ROW + 16u)
|
||||
|
||||
/** The size of a buffer to hold an NVM row of data to write or verify */
|
||||
#define CY_DFU_SIZEOF_DATA_BUFFER (CY_FLASH_SIZEOF_ROW + 16u)
|
||||
|
||||
/**
|
||||
* Set to non-zero for the DFU SDK Program Data command to check
|
||||
* if the Golden image is going to be overwritten while updating.
|
||||
*/
|
||||
#define CY_DFU_OPT_GOLDEN_IMAGE (0)
|
||||
|
||||
/**
|
||||
* List of Golden Image Application IDs.
|
||||
* Here "Golden Image Application" means an application that cannot be changed with
|
||||
* CommandProgramData()
|
||||
*
|
||||
* Usage. Define the list of Golden Image Application IDs without enclosing
|
||||
* parenthesis, e.g.
|
||||
* \code #define CY_DFU_GOLDEN_IMAGE_IDS() 0u, 1u, 3u \endcode
|
||||
* later it is used in cy_dfu.c file:
|
||||
* \code uint8_t goldenImages[] = { CY_DFU_GOLDEN_IMAGE_IDS() }; \endcode
|
||||
*/
|
||||
#define CY_DFU_GOLDEN_IMAGE_IDS() 0u
|
||||
|
||||
/**
|
||||
* The number of applications in the metadata,
|
||||
* for 512 bytes in a Flash row - 63 is the maximum possible value,
|
||||
* because 4 bytes are reserved for the entire metadata CRC.
|
||||
*
|
||||
* The smallest metadata size if CY_DFU_MAX_APPS * 8 (bytes per one app) + 4 (bytes for CRC-32C)
|
||||
*/
|
||||
#define CY_DFU_MAX_APPS (2u)
|
||||
|
||||
|
||||
/** A non-zero value enables the Verify Data DFU command */
|
||||
#define CY_DFU_OPT_VERIFY_DATA (1)
|
||||
|
||||
/** A non-zero value enables the Erase Data DFU command */
|
||||
#define CY_DFU_OPT_ERASE_DATA (1)
|
||||
|
||||
/** A non-zero value enables the Verify App DFU command */
|
||||
#define CY_DFU_OPT_VERIFY_APP (1)
|
||||
|
||||
/**
|
||||
* A non-zero value enables the Send Data DFU command.
|
||||
* If the "Send Data" DFU command is enabled, \c packetBuffer and \c dataBuffer
|
||||
* must be non-overlapping.
|
||||
*
|
||||
* Else, \c dataBuffer must be inside \c packetBuffer with an offset of
|
||||
* \c CY_DFU_PACKET_DATA_IDX, typically 4 bytes. \n
|
||||
* <code>params->dataBuffer = &packetBuffer[4];</code> \n
|
||||
* \note that \c packetBuffer in this case must be 4 bytes aligned, as
|
||||
* \c dataBuffer is required to be 4 bytes aligned.
|
||||
*/
|
||||
#define CY_DFU_OPT_SEND_DATA (1)
|
||||
|
||||
/** A non-zero value enables the Get Metadata DFU command */
|
||||
#define CY_DFU_OPT_GET_METADATA (1)
|
||||
|
||||
/** A non-zero value enables the Set EI Vector DFU command */
|
||||
#define CY_DFU_OPT_SET_EIVECTOR (0)
|
||||
|
||||
/**
|
||||
* A non-zero value allows writing metadata
|
||||
* with the Set App Metadata DFU command.
|
||||
*/
|
||||
#define CY_DFU_METADATA_WRITABLE (1)
|
||||
|
||||
/** Non-zero value enables the usage of hardware Crypto API */
|
||||
#define CY_DFU_OPT_CRYPTO_HW (0)
|
||||
|
||||
/** A non-zero value enables the usage of CRC-16 for DFU packet verification */
|
||||
#define CY_DFU_OPT_PACKET_CRC (0)
|
||||
|
||||
/** Set the default application-format-possible values defined in \ref group_dfu_macro_app_type */
|
||||
#define CY_DFU_APP_FORMAT (CY_DFU_BASIC_APP)
|
||||
|
||||
/** Set the default secure application-verification-type possible values
|
||||
* defined in \ref group_dfu_macro_ver_type */
|
||||
#define CY_DFU_SEC_APP_VERIFY_TYPE (CY_DFU_VERIFY_FAST)
|
||||
|
||||
/** \} group_dfu_macro_config */
|
||||
|
||||
#if !defined(CY_DOXYGEN)
|
||||
#if defined(__GNUC__) || defined(__ICCARM__)
|
||||
/*
|
||||
* These variables are defined in the linker scripts, the values of their addresses define
|
||||
* corresponding applications start address and length.
|
||||
*/
|
||||
extern uint8_t __cy_app0_verify_start;
|
||||
extern uint8_t __cy_app0_verify_length;
|
||||
extern uint8_t __cy_app1_verify_start;
|
||||
extern uint8_t __cy_app1_verify_length;
|
||||
extern uint8_t __cy_boot_signature_size;
|
||||
|
||||
#define CY_DFU_APP0_VERIFY_START ( (uint32_t)&__cy_app0_verify_start )
|
||||
#define CY_DFU_APP0_VERIFY_LENGTH ( (uint32_t)&__cy_app0_verify_length )
|
||||
#define CY_DFU_APP1_VERIFY_START ( (uint32_t)&__cy_app1_verify_start )
|
||||
#define CY_DFU_APP1_VERIFY_LENGTH ( (uint32_t)&__cy_app1_verify_length )
|
||||
#define CY_DFU_SIGNATURE_SIZE ( (uint32_t)&__cy_boot_signature_size )
|
||||
|
||||
#elif defined(__ARMCC_VERSION)
|
||||
#include "dfu_mdk_common.h"
|
||||
|
||||
#define CY_DFU_APP0_VERIFY_START ( CY_APP0_CORE0_FLASH_ADDR )
|
||||
#define CY_DFU_APP0_VERIFY_LENGTH ( CY_APP0_CORE0_FLASH_LENGTH + CY_APP0_CORE1_FLASH_LENGTH \
|
||||
- CY_BOOT_SIGNATURE_SIZE)
|
||||
#define CY_DFU_APP1_VERIFY_START ( CY_APP1_CORE0_FLASH_ADDR )
|
||||
#define CY_DFU_APP1_VERIFY_LENGTH ( CY_APP1_CORE0_FLASH_LENGTH + CY_APP1_CORE1_FLASH_LENGTH \
|
||||
- CY_BOOT_SIGNATURE_SIZE)
|
||||
#define CY_DFU_SIGNATURE_SIZE CY_BOOT_SIGNATURE_SIZE
|
||||
|
||||
#else
|
||||
#error "Not implemented for this compiler"
|
||||
#endif /* defined(__GNUC__) || defined(__ICCARM__) */
|
||||
#endif /* !defined(CY_DOXYGEN) */
|
||||
|
||||
|
||||
#endif /* !defined(DFU_USER_H) */
|
||||
|
||||
|
||||
/* [] END OF FILE */
|
404
2020TPCApp1.cydsn/gcc/startup_psoc6_01_cm0plus.S
Normal file
404
2020TPCApp1.cydsn/gcc/startup_psoc6_01_cm0plus.S
Normal 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 */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue