From 28a4c2187601a17e8d667fffad01edbd0c5c67a2 Mon Sep 17 00:00:00 2001 From: Peter Wittich Date: Tue, 14 May 2019 12:21:04 -0400 Subject: [PATCH] LED, i2c, power control tasks update interactive tasks. --- common/power_ctl.h | 2 + projects/project2/CommandLineTask.c | 139 ++++++++++++++++++++-------- projects/project2/LedTask.c | 19 +++- projects/project2/PowerSupplyTask.c | 9 +- 4 files changed, 118 insertions(+), 51 deletions(-) diff --git a/common/power_ctl.h b/common/power_ctl.h index 789add18..afc8a2cb 100644 --- a/common/power_ctl.h +++ b/common/power_ctl.h @@ -23,6 +23,8 @@ #define RED_LED_TOGGLE3 (8) #define RED_LED_TOGGLE4 (9) +#define HUH (99) + bool set_ps(bool KU15P, bool VU7PMGT1, bool VU7PMGT2); bool check_ps(void); diff --git a/projects/project2/CommandLineTask.c b/projects/project2/CommandLineTask.c index 99ff4cf5..b79e53ac 100644 --- a/projects/project2/CommandLineTask.c +++ b/projects/project2/CommandLineTask.c @@ -26,7 +26,7 @@ #include "FreeRTOS_CLI.h" // Generic C headers -- caveat emptor -// todo: do I need these +// todo: do I need these include files here #include "string.h" #include @@ -41,6 +41,7 @@ int snprintf( char *buf, unsigned int count, const char *format, ... ); // external definition extern QueueHandle_t xPwrQueue; +extern QueueHandle_t xLedQueue; #define MAX_INPUT_LENGTH 50 @@ -50,13 +51,13 @@ extern QueueHandle_t xPwrQueue; void vRegisterSampleCLICommands( void ); // Ugly hack for now -- I don't understand how to reconcile these -// two parts of the FreeRTOS-Plus code w/o casts o plenty +// two parts of the FreeRTOS-Plus code w/o casts-o-plenty #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpointer-sign" #pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" #pragma GCC diagnostic ignored "-Wformat=" -static BaseType_t i2c1_ctl(char *m, size_t s, const char *mm) +static BaseType_t i2c1_ctlr(char *m, size_t s, const char *mm) { int8_t *p1, *p2, *p3; @@ -73,17 +74,50 @@ static BaseType_t i2c1_ctl(char *m, size_t s, const char *mm) i2 = strtol(p2, NULL, 16); i3 = strtol(p3, NULL, 16); uint8_t data[10]; - memset(data,0,10); - if ( i3 > 10 ) i3 = 10; + memset(data,0,10*sizeof(uint8_t)); + if ( i3 > 10 ) + i3 = 10; char tmp[64]; - snprintf(tmp, 64, "readI2CReg1: command arguments are: %x %x %x\n", i1, i2, i3); + snprintf(tmp, 64, "readI2CReg1: command arguments are: 0x%x 0x%x 0x%x\n", i1, i2, i3); + Print(tmp); + snprintf(tmp, 64, "readI2CReg1: Read %d bytes from I2C address 0x%x\n", i3, i1); Print(tmp); readI2Creg(I2C1_BASE, i1, i2, data, i3); - // should actually do something here - snprintf(m, s, "Read: %d %d %d\n", data[0], data[1], data[2]); + + snprintf(m, s, "Read, 1st 3 bytes: %d %d %d\n", data[0], data[1], data[2]); return pdFALSE; } +static BaseType_t i2c1_ctlw(char *m, size_t s, const char *mm) +{ + + int8_t *p1, *p2, *p3; + BaseType_t p1l, p2l, p3l; + p1 = FreeRTOS_CLIGetParameter(mm, 1, &p1l); // address + p2 = FreeRTOS_CLIGetParameter(mm, 2, &p2l); // register + p3 = FreeRTOS_CLIGetParameter(mm, 3, &p3l); // byte to write + p1[p1l] = 0x00; // terminate strings + p2[p2l] = 0x00; // terminate strings + p3[p3l] = 0x00; // terminate strings + + BaseType_t i1, i2, i3; + i1 = strtol(p1, NULL, 16); + i2 = strtol(p2, NULL, 16); + i3 = strtol(p3, NULL, 16); + uint8_t data[10]; + memset(data,0,10*sizeof(uint8_t)); + data[0] = i3; + char tmp[64]; + snprintf(tmp, 64, "i2c1_ctlw: command arguments are: 0x%x 0x%x 0x%x\n", i1, i2, i3); + Print(tmp); + snprintf(tmp, 64, "i2c1_ctlw: write 0x%x to address 0x%x, register 0x%x\n", i3, i1, i2); + Print(tmp); + writeI2Creg(I2C1_BASE, i1, i2, data, 1); + + snprintf(m, s, "Wrote, 3 bytes: %d %d %d\n", data[0], data[1], data[2]); + return pdFALSE; +} + // send power control commands static BaseType_t power_ctl(char *m, size_t s, const char *mm) { @@ -104,7 +138,9 @@ static BaseType_t power_ctl(char *m, size_t s, const char *mm) else if ( i1 == 0 ) { message = PS_OFF; // turn off power supply } + // Send a message to the power supply task xQueueSendToBack(xPwrQueue, &message, pdMS_TO_TICKS(10)); + m[0] = '\0'; // no output from this command return pdFALSE; } @@ -118,21 +154,25 @@ static BaseType_t led_ctl(char *m, size_t s, const char *mm) p1[p1l] = 0x00; // terminate strings BaseType_t i1 = strtol(p1, NULL, 10); - uint32_t message; - if ( !(i1 == 1 || i1 == 0 )) { - snprintf(m, s, "led_ctl: invalid argument %d received\n", i1); - return pdFALSE; + uint32_t message = HUH; // default: message not understood + if ( i1 == 0 ) { // ToDo: make messages less clunky. break out color. + message = RED_LED_OFF; } - else if ( i1 == 0 ) { + else if (i1 == 1 ) { + message = RED_LED_ON; + } + else if ( i1 == 2 ) { message = RED_LED_TOGGLE; // turn on power supply } - else if ( i1 == 1 ) { + else if ( i1 == 3 ) { message = RED_LED_TOGGLE3; // turn off power supply } - else if ( i1 == 2 ) { + else if ( i1 == 4 ) { message = RED_LED_TOGGLE4; // turn off power supply } - xQueueSendToBack(xPwrQueue, &message, pdMS_TO_TICKS(10)); + // Send a message to the LED task + xQueueSendToBack(xLedQueue, &message, pdMS_TO_TICKS(10)); + m[0] = '\0'; // no output from this command return pdFALSE; } @@ -146,10 +186,17 @@ static const char * const pcWelcomeMessage = CLI_Command_Definition_t i2c_read_command = { .pcCommand="i2cr", .pcHelpString="i2cr
\n Read no1 I2C controller.\r\n", - .pxCommandInterpreter = i2c1_ctl, + .pxCommandInterpreter = i2c1_ctlr, 3 }; +CLI_Command_Definition_t i2c_write_command = { + .pcCommand="i2cw", + .pcHelpString="i2cw
\n Write no1 I2C controller.\r\n", + .pxCommandInterpreter = i2c1_ctlw, + 3 +}; + CLI_Command_Definition_t pwr_ctl_command = { .pcCommand="pwr", .pcHelpString="pwr (0|1)\n Turn on or off all power.\r\n", @@ -157,13 +204,19 @@ CLI_Command_Definition_t pwr_ctl_command = { 1 }; +CLI_Command_Definition_t led_ctl_command = { + .pcCommand="led", + .pcHelpString="led (0|1)\n Turn on red LED (for now).\r\n", + .pxCommandInterpreter = led_ctl, + 1 +}; + extern StreamBufferHandle_t xStreamBuffer; void vCommandLineTask( void *pvParameters ) { - // todo: echo what you typed uint8_t cRxedChar, cInputIndex = 0; BaseType_t xMoreDataToFollow; /* The input and output buffers are declared static to keep them off the stack. */ @@ -171,14 +224,17 @@ void vCommandLineTask( void *pvParameters ) // register the commands - FreeRTOS_CLIRegisterCommand(&i2c_read_command); - FreeRTOS_CLIRegisterCommand( &pwr_ctl_command); + FreeRTOS_CLIRegisterCommand(&i2c_read_command ); + FreeRTOS_CLIRegisterCommand(&i2c_write_command); + FreeRTOS_CLIRegisterCommand(&pwr_ctl_command ); + FreeRTOS_CLIRegisterCommand(&led_ctl_command ); // register sample commands vRegisterSampleCLICommands(); /* Send a welcome message to the user knows they are connected. */ Print(pcWelcomeMessage); + Print("% "); for( ;; ) { /* This implementation reads a single character at a time. Wait in the @@ -190,37 +246,40 @@ void vCommandLineTask( void *pvParameters ) /* A newline character was received, so the input command string is complete and can be processed. Transmit a line separator, just to make the output easier to read. */ - Print("\r\n"); + //Print("\r\n"); + if ( cInputIndex != 0 ) { // empty command -- skip - snprintf(pcOutputString, MAX_OUTPUT_LENGTH, "\nCalling command %s\n", - (const char*)pcInputString); + snprintf(pcOutputString, MAX_OUTPUT_LENGTH, "Calling command >%s<\n", + (const char*)pcInputString); - Print((const char*)pcOutputString); - /* The command interpreter is called repeatedly until it returns + Print((const char*)pcOutputString); + /* The command interpreter is called repeatedly until it returns pdFALSE. See the "Implementing a command" documentation for an explanation of why this is. */ - do { - /* Send the command string to the command interpreter. Any + do { + /* Send the command string to the command interpreter. Any output generated by the command interpreter will be placed in the pcOutputString buffer. */ - xMoreDataToFollow = FreeRTOS_CLIProcessCommand - ( - (const char*)pcInputString, /* The command string.*/ - (char*)pcOutputString, /* The output buffer. */ - MAX_OUTPUT_LENGTH/* The size of the output buffer. */ - ); - - /* Write the output generated by the command interpreter to the + xMoreDataToFollow = FreeRTOS_CLIProcessCommand + ( + (const char*)pcInputString, /* The command string.*/ + (char*)pcOutputString, /* The output buffer. */ + MAX_OUTPUT_LENGTH/* The size of the output buffer. */ + ); + + /* Write the output generated by the command interpreter to the console. */ - Print((char*)pcOutputString); + if ( pcOutputString[0] != '\0') + Print((char*)pcOutputString); - } while( xMoreDataToFollow != pdFALSE ); + } while( xMoreDataToFollow != pdFALSE ); - /* All the strings generated by the input command have been sent. + /* All the strings generated by the input command have been sent. Processing of the command is complete. Clear the input string ready to receive the next command. */ - cInputIndex = 0; - memset( pcInputString, 0x00, MAX_INPUT_LENGTH ); + cInputIndex = 0; + memset( pcInputString, 0x00, MAX_INPUT_LENGTH ); + } Print("% "); } else { diff --git a/projects/project2/LedTask.c b/projects/project2/LedTask.c index 7090b5c0..f7401f26 100644 --- a/projects/project2/LedTask.c +++ b/projects/project2/LedTask.c @@ -28,12 +28,13 @@ enum LEDpattern { OFF=0, ON=1, TOGGLE=2, TOGGLE3, TOGGLE4}; QueueHandle_t xLedQueue = NULL; // control the LED +// Todo: expand beyond just controlling the red LED, if needed, for the command line interface. Probably not needed. void LedTask(void *parameters) { TickType_t xLastWakeTime = xTaskGetTickCount(); uint32_t callcnt = 0; - enum LEDpattern greenLedPattern = TOGGLE; + enum LEDpattern greenLedPattern = OFF; enum LEDpattern blueLedPattern = OFF; enum LEDpattern redLedPattern = OFF; @@ -77,10 +78,20 @@ void LedTask(void *parameters) else if ( callcnt%greenLedPattern == 0 ) // toggle patterns toggle_gpio_pin(TM4C_LED_GREEN); // Red LED - if ( callcnt%blueLedPattern == 0 ) - toggle_gpio_pin(TM4C_LED_BLUE); - if ( callcnt%redLedPattern == 0 ) + if ( redLedPattern == OFF) + write_gpio_pin(TM4C_LED_RED, 0x0); + else if ( redLedPattern == ON ) + write_gpio_pin(TM4C_LED_RED, 0x1); + else if ( callcnt%redLedPattern == 0 ) // toggle patterns toggle_gpio_pin(TM4C_LED_RED); + // Blue LED + if ( blueLedPattern == OFF) + write_gpio_pin(TM4C_LED_BLUE, 0x0); + else if ( blueLedPattern == ON ) + write_gpio_pin(TM4C_LED_BLUE, 0x1); + else if ( callcnt%blueLedPattern == 0 ) // toggle patterns + toggle_gpio_pin(TM4C_LED_BLUE); + ++callcnt; // wait for next check vTaskDelayUntil( &xLastWakeTime, pdMS_TO_TICKS( 250 ) ); diff --git a/projects/project2/PowerSupplyTask.c b/projects/project2/PowerSupplyTask.c index c662e9e4..36e60566 100644 --- a/projects/project2/PowerSupplyTask.c +++ b/projects/project2/PowerSupplyTask.c @@ -42,12 +42,7 @@ void PowerSupplyTask(void *parameters) enum state oldState = UNKNOWN; // turn on the power supply at the start of the task - if ( set_ps(true,true,true) ) { - oldState = PWR_ON; - } - else { - oldState = PWR_OFF; - } + set_ps(true,true,true) ; // this function never returns for ( ;; ) { @@ -83,7 +78,7 @@ void PowerSupplyTask(void *parameters) xQueueSendToBack(xLedQueue, &message, pdMS_TO_TICKS(10));// todo: check on fail to send oldState = newstate; - // wait here for the x MS, where x is 2nd argument below. + // wait here for the x msec, where x is 2nd argument below. vTaskDelayUntil( &xLastWakeTime, pdMS_TO_TICKS( 250 ) ); } }