Initial public release.
This commit is contained in:
parent
7b169e8116
commit
dac4af8d25
255 changed files with 68595 additions and 2 deletions
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)
|
Loading…
Add table
Add a link
Reference in a new issue