Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * This is the main file of the ESPLaboratory Demo project.
- * It implements simple sample functions for the usage of UART,
- * writing to the display and processing user inputs.
- *
- * @author: Alex Hoffman alex.hoffman@tum.de (RCS, TUM)
- * Jonathan M��ller-Boruttau,
- * Tobias Fuchs tobias.fuchs@tum.de
- * Nadja Peters nadja.peters@tum.de (RCS, TUM)
- *
- */
- #include "includes.h"
- #include <math.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <time.h>
- #include <unistd.h>
- #include "buttonDebounce.h"
- #include "staticFunctions.h"
- #define DISPLAY_SIZE_X 320
- #define DISPLAY_SIZE_Y 240
- #define PAUSED_TEXT_X(TEXT) DISPLAY_SIZE_X / 2 - (gdispGetStringWidth(TEXT, font1) / 2)
- #define PAUSED_TEXT_Y(LINE) DISPLAY_SIZE_Y / 2 - (gdispGetFontMetric(font1, fontHeight) * -(LINE + 0.5))
- #define TEXT_X(TEXT) DISPLAY_SIZE_X / 2 - (gdispGetStringWidth(TEXT, font1) / 2)
- #define TEXT_Y(LINE) DISPLAY_SIZE_Y / 2 - (gdispGetFontMetric(font1, fontHeight) * -(LINE + 0.5)) + 65
- #define SLIDING_TEXT_X(TEXT) DISPLAY_SIZE_X / 2 - (gdispGetStringWidth(TEXT, font1) / 2) + sliderCounter() - 100
- #define SLIDING_TEXT_Y(LINE) DISPLAY_SIZE_Y / 2 - (gdispGetFontMetric(font1, fontHeight) * -(LINE + 0.5)) - 100
- #define PI 3.14159265
- #define RAD_CONVERSION PI / 180
- #define ROTATION_RADIUS_CIRCLE 40
- #define ROTATING_CIRCLE_X DISPLAY_SIZE_X / 2 + ROTATION_RADIUS_CIRCLE * cos(circleRotate() * RAD_CONVERSION)
- #define ROTATING_CIRCLE_Y DISPLAY_SIZE_Y / 2 - 5 + ROTATION_RADIUS_CIRCLE * sin(circleRotate() * RAD_CONVERSION)
- #define ROTATION_RADIUS_SQUARE 40
- #define ROTATING_SQUARE_X DISPLAY_SIZE_X / 2 + ROTATION_RADIUS_SQUARE * cos((circleRotate() + 180) * RAD_CONVERSION)
- #define ROTATING_SQUARE_Y DISPLAY_SIZE_Y / 2 + ROTATION_RADIUS_SQUARE * sin((circleRotate() + 180) * RAD_CONVERSION)
- #define SCREEN_SLIDE_X screenMovementX()
- #define SCREEN_SLIDE_Y screenMovementY()
- #define BUTTON_QUEUE_LENGTH 20
- #define STATE_QUEUE_LENGTH 1
- #define FPS_QUEUE_LENGTH 20
- #define STATE_COUNT 3
- #define STATE_ONE 1
- #define STATE_TWO 2
- #define STATE_THREE 3
- #define NEXT_TASK 1
- #define PREV_TASK 2
- #define START_COUNTER_324 1
- #define STOP_COUNTER_324 2
- #define NUM_POINTS (sizeof(triangle)/sizeof(triangle[0]))
- #define STACK_SIZE 200
- #define RESET_TIMER_EX_3 15 //In seconds
- // Read only, there should be no globals being written to that are not locked via semaphores etc
- // Start and stop bytes for the UART protocol
- static const uint8_t startByte = 0xAA, stopByte = 0x55;
- //Coordinates for the triangle we are using in exercise 1
- static const point triangle[] = {
- { -15, 0 },
- { 0 , -20 },
- { 15, 0 },
- };
- font_t font1; // Load font for ugfx
- //Function prototypes
- void frameSwapTask(void * params);
- void basicStateMachine(void * params);
- void checkButtons(void * params);
- void exercise1Display(void * params);
- void exercise2Display(void * params);
- void exercise3Display(void * params);
- //Exercise 3.2.2
- void circleBlinkDynamic(void *params);
- void circleBlinkStatic(void * params);
- //Exercise 3.2.3
- void timesButtonAPressed(void * params);
- void timesButtonBPressed(void * params);
- void resetTimer(void * params);
- //Exercise 3.2.4
- void increaseVariable(void * params);
- QueueHandle_t ESPL_RxQueue; // Already defined in ESPL_Functions.h
- SemaphoreHandle_t ESPL_DisplayReady;
- SemaphoreHandle_t DrawReady; // After swapping buffer calll drawing
- //Exercise 3.2.2
- SemaphoreHandle_t BlinkCircle2Hz;
- SemaphoreHandle_t BlinkCircle1Hz;
- //Exercise 3.2.3
- SemaphoreHandle_t ButtonAPressed;
- SemaphoreHandle_t ButtonBPressed;
- SemaphoreHandle_t ResetTimer;
- //Exercise 3.2.4
- SemaphoreHandle_t increaseVariable_Semaphore;
- /*
- * All variables handled by multiple tasks should be sent in SAFE ways, ie. using queues.
- * Global variables should only be used for managing handles to the RTOS components used
- * to perform thread safe, multi-threaded programming.
- */
- // Stores lines to be drawn
- QueueHandle_t ButtonQueue;
- QueueHandle_t StateQueue;
- QueueHandle_t FPSQueue;
- QueueHandle_t resetTimerQueue;
- // Task handles, used for task control
- TaskHandle_t frameSwapHandle;
- TaskHandle_t exercise1DisplayHandle;
- TaskHandle_t exercise2DisplayHandle;
- TaskHandle_t exercise3DisplayHandle;
- TaskHandle_t stateMachineHandle;
- //Exercise 3.2.2
- TaskHandle_t circleBlinkDynamicHandle;
- StaticTask_t xTaskBuffer;
- StackType_t xStack[ STACK_SIZE ];
- //Exercise 3.2.3
- TaskHandle_t timesButtonAPressedHandle;
- TaskHandle_t timesButtonBPressedHandle;
- TaskHandle_t resetTimerHandle;
- //Exercise 3.2.4
- TaskHandle_t increaseVariableHandle;
- int main(void){
- // Initialize Board functions and graphics
- ESPL_SystemInit();
- font1 = gdispOpenFont("DejaVuSans24*");
- // Initializes Draw Queue with 100 lines buffer
- ButtonQueue = xQueueCreate(BUTTON_QUEUE_LENGTH, sizeof(struct buttons));
- StateQueue = xQueueCreate(STATE_QUEUE_LENGTH, sizeof(unsigned char));
- FPSQueue = xQueueCreate(FPS_QUEUE_LENGTH, sizeof(uint8_t));
- resetTimerQueue = xQueueCreate(FPS_QUEUE_LENGTH, sizeof(unsigned char));
- ESPL_DisplayReady = xSemaphoreCreateBinary();
- DrawReady = xSemaphoreCreateBinary();
- //Exercise 3.2.2
- BlinkCircle2Hz = xSemaphoreCreateBinary();
- BlinkCircle1Hz = xSemaphoreCreateBinary();
- //Exercise 3.2.3
- ButtonAPressed = xSemaphoreCreateBinary();
- ButtonBPressed = xSemaphoreCreateBinary();
- ResetTimer = xSemaphoreCreateBinary();
- //Exercise 3.2.4
- increaseVariable_Semaphore = xSemaphoreCreateBinary();
- // Initializes Tasks with their respective priority
- // Core tasks
- xTaskCreate(frameSwapTask, "frameSwapper", 1000, NULL, 4, &frameSwapHandle);
- xTaskCreate(basicStateMachine, "StateMachine", 1000, NULL, 3, stateMachineHandle);
- xTaskCreate(checkButtons, "checkButtons", 1000, NULL, 3, NULL);
- // display tasks for the different exercises
- xTaskCreate(exercise1Display, "exercise1Display", 1000, NULL, 2, &exercise1DisplayHandle);
- xTaskCreate(exercise2Display, "exercise2Display", 1000, NULL, 2, &exercise2DisplayHandle);
- xTaskCreate(exercise3Display, "exercise3Display", 1000, NULL, 2, &exercise3DisplayHandle);
- //Exercise 3.2.2
- xTaskCreate(circleBlinkDynamic, "circleBlinkDynamic", 1000, NULL, 3, &circleBlinkDynamicHandle);
- xTaskCreateStatic(circleBlinkStatic, "circleBlinkStatic", 200, NULL, 4, xStack, &xTaskBuffer);
- //Exercise 3.2.3
- xTaskCreate(timesButtonAPressed, "timesButtonAPressed", 1000, NULL, 2, ×ButtonAPressedHandle);
- xTaskCreate(timesButtonBPressed, "timesButtonBPressed", 1000, NULL, 3, ×ButtonBPressedHandle);
- xTaskCreate(resetTimer, "resetTimer", 1000, NULL, 2, &resetTimerHandle);
- //Exercise 3.2.4
- xTaskCreate(increaseVariable, "increaseVariable", 1000, NULL, 3, &increaseVariableHandle);
- vTaskSuspend(exercise1DisplayHandle);
- vTaskSuspend(exercise2DisplayHandle);
- vTaskSuspend(exercise3DisplayHandle);
- // Start FreeRTOS Scheduler
- vTaskStartScheduler();
- }
- /*
- * Frame swapping happens in the background, seperate to all other system tasks.
- * This way it can be guarenteed that the 50fps requirement of the system
- * can be met.
- */
- void frameSwapTask(void * params) {
- TickType_t xLastWakeTime;
- xLastWakeTime = xTaskGetTickCount();
- TickType_t xOldWakeTime;
- xOldWakeTime = 0;
- const TickType_t frameratePeriod = 20;
- while (1) {
- // Draw next frame
- xSemaphoreGive(DrawReady);
- // Wait for display to stop writing
- xSemaphoreTake(ESPL_DisplayReady, portMAX_DELAY);
- // Swap buffers
- ESPL_DrawLayer();
- xOldWakeTime = xLastWakeTime;
- vTaskDelayUntil(&xLastWakeTime, frameratePeriod);
- TickType_t xDifference;
- xDifference = xLastWakeTime - xOldWakeTime;
- uint8_t xFPS = 1000 / xDifference;
- xQueueSend(FPSQueue, &xFPS, 0);
- }
- }
- /*
- * Changes the state, either forwards of backwards
- */
- void changeState(volatile unsigned char *state, unsigned char forwards) {
- switch (forwards) {
- case 0:
- if (*state == 0)
- *state = STATE_COUNT;
- else
- (*state)--;
- break;
- case 1:
- if (*state == STATE_COUNT)
- *state = 0;
- else
- (*state)++;
- break;
- default:
- break;
- }
- }
- /*
- * Example basic state machine with sequential states
- */
- void basicStateMachine(void * params) {
- unsigned char current_state = 1; // Default state
- //unsigned int switch_state_direction = 1; //Default state switching direction is 1, incrementing
- unsigned char state_changed = 1; // Only re-evaluate state if it has changed
- unsigned char input = 0;
- unsigned char input_counter = 0;
- unsigned char toggle_counter_changed = 0;
- unsigned char toggle_counter = 0;
- while (1) {
- if (state_changed)
- goto initial_state;
- // Handle state machine input
- if (xQueueReceive(StateQueue, &input, portMAX_DELAY) == pdTRUE) {
- if (input == NEXT_TASK) {
- changeState(¤t_state, 1);
- state_changed = 1;
- }
- else if (input == PREV_TASK) {
- changeState(¤t_state, 0);
- changeState(¤t_state, 0);
- state_changed = 1;
- }
- }
- //Exercise 3.2.4
- /*
- if (xQueueReceive(resetTimerQueue, &input_counter, portMAX_DELAY) == pdTRUE) {
- if (input_counter == START_COUNTER) {
- toggle_counter_changed = 1;
- toggle_counter = input_counter;
- }
- else if (input_counter == START_COUNTER) {
- toggle_counter_changed = 1;
- toggle_counter = input_counter;
- }
- }
- */
- initial_state:
- // Handle current state
- if (state_changed) {
- switch (current_state) {
- case STATE_ONE:
- vTaskSuspend(exercise2DisplayHandle);
- vTaskSuspend(exercise3DisplayHandle);
- vTaskResume(exercise1DisplayHandle);
- state_changed = 0;
- break;
- case STATE_TWO:
- vTaskSuspend(exercise1DisplayHandle);
- vTaskSuspend(exercise3DisplayHandle);
- vTaskResume(exercise2DisplayHandle);
- state_changed = 0;
- break;
- case STATE_THREE:
- vTaskSuspend(exercise1DisplayHandle);
- vTaskSuspend(exercise2DisplayHandle);
- vTaskResume(exercise3DisplayHandle);
- state_changed = 0;
- break;
- default:
- break;
- }
- }
- //Exercise 3.2.4
- /*
- if(toggle_counter_changed){
- switch (toggle_counter){
- case START_COUNTER:
- vTaskResume(increaseVariable);
- break;
- case STOP_COUNTER:
- vTaskSuspend(increaseVariable);
- break;
- default:
- break;
- }
- }
- */
- }
- }
- void exercise1Display(void * params) {
- char str[100]; // buffer for messages to draw to display
- struct buttons buttonStatus; // joystick queue input buffer
- const unsigned char next_state_signal = NEXT_TASK;
- /* building the cave:
- caveX and caveY define the top left corner of the cave
- circle movment is limited by 64px from center in every direction
- (coordinates are stored as uint8_t unsigned bytes)
- so, cave size is 128px */
- //const uint16_t caveX = DISPLAY_SIZE_X / 2 - UINT8_MAX / 4, caveY =
- //DISPLAY_SIZE_Y / 2 - UINT8_MAX / 4, caveSize = UINT8_MAX / 2;
- int press_count_A = 0, press_count_B = 0, press_count_C = 0, press_count_D = 0;
- int sliding_text_position = 0, sliding_text_direction = 1;
- int sliderCounter(){
- int m = sliding_text_position;
- if(sliding_text_position == 0){
- sliding_text_position++;
- sliding_text_direction = 0;
- return m;
- }
- if (sliding_text_position < 200){
- if(!sliding_text_direction){
- sliding_text_position++;
- return m;
- }
- else{
- sliding_text_position--;
- return m;
- }
- }
- if (sliding_text_position == 200){
- sliding_text_position--;
- sliding_text_direction = 1;
- return m;
- }
- }
- int circle_angle = 0;
- int circleRotate(){
- int internal_angle = circle_angle;
- if(circle_angle < 360){
- circle_angle++;
- return internal_angle;
- }
- if(circle_angle == 360){
- circle_angle = 0;
- return internal_angle;
- }
- }
- int screen_slide_x = 0;
- int screen_slide_y = 0;
- int screenMovementX(){
- int internal_x = screen_slide_x;
- internal_x = (buttonStatus.joystick.x / 8);
- return internal_x;
- }
- int screenMovementY(){
- int internal_y = screen_slide_y;
- internal_y = (buttonStatus.joystick.y / 8);
- return internal_y;
- }
- // Start endless loop
- while (1) {
- if (xSemaphoreTake(DrawReady, portMAX_DELAY) == pdTRUE) { // Block until screen is ready
- while (xQueueReceive(ButtonQueue, &buttonStatus, 0) == pdTRUE)
- ;
- // State machine input
- if (buttonCount(BUT_E))
- xQueueSend(StateQueue, &next_state_signal, 100);
- // Clear background
- gdispClear(White);
- // Generate string with current joystick values
- sprintf(str, "X from left: %5d|Y from top: %5d|VBat: %5d",
- buttonStatus.joystick.x, buttonStatus.joystick.y,
- ADC_GetConversionValue(ESPL_ADC_VBat));
- // Print string of joystick values
- gdispDrawString(SCREEN_SLIDE_X,SCREEN_SLIDE_Y, str, font1, Black);
- //count number of presses
- if(buttonCount(BUT_A)){
- press_count_A++;
- }
- if(buttonCount(BUT_B)){
- press_count_B++;
- }
- if(buttonCount(BUT_C)){
- press_count_C++;
- }
- if(buttonCount(BUT_D)){
- press_count_D++;
- }
- if(buttonCount(BUT_K)){
- press_count_A = 0;
- press_count_B = 0;
- press_count_C = 0;
- press_count_D = 0;
- }
- // Generate string with number of times buttons have been pressed
- sprintf(str, "A: %d|B: %d|C: %d|D: %d", press_count_A,
- press_count_B, press_count_C, press_count_D);
- // Print string of number of presses
- gdispDrawString(SCREEN_SLIDE_X, 11 + SCREEN_SLIDE_Y, str, font1, Black);
- //Draw small teal triangle in the center
- gdispFillConvexPoly(DISPLAY_SIZE_X / 2 + SCREEN_SLIDE_X, DISPLAY_SIZE_Y / 2 + SCREEN_SLIDE_Y, triangle, NUM_POINTS, Teal);
- //Draw rotating orange square
- gdispFillArea(ROTATING_SQUARE_X + SCREEN_SLIDE_X, ROTATING_SQUARE_Y + SCREEN_SLIDE_Y, 12, 12, Orange);
- //Draw rotating olive circle
- gdispFillCircle(ROTATING_CIRCLE_X + SCREEN_SLIDE_X, ROTATING_CIRCLE_Y + SCREEN_SLIDE_Y, 12, Olive);
- //displaying sliding text above figures
- char str_slide[1][70] = { "ESPL LAB"};
- for (unsigned char j = 0; j < 1; j++)
- gdispDrawString(SLIDING_TEXT_X(str_slide[j]) + SCREEN_SLIDE_X, SLIDING_TEXT_Y(j) + SCREEN_SLIDE_Y, str_slide[j],
- font1, Black);
- //displaying text below figures
- char str[1][70] = {"GIVE ME A 100 PERCENT"};
- for (unsigned char i = 0; i < 1; i++)
- gdispDrawString(TEXT_X(str[i]) + SCREEN_SLIDE_X, TEXT_Y(i) + SCREEN_SLIDE_Y, str[i],
- font1, Black);
- }
- }
- }
- void exercise2Display(void * params) {
- char str[2][70] = { "EXERCISE 3", "Blue circle is dynamic, red is static" };
- struct buttons buttonStatus; // joystick queue input buffer
- const unsigned char next_state_signal = NEXT_TASK;
- unsigned int button_A_count = 0;
- unsigned int button_B_count = 0;
- char number_display_A[1][70] = {0};
- char number_display_B[1][70] = {0};
- char fps[1][20] = {0};
- uint8_t fps_num;
- uint8_t counter324 = 0;
- char counter324_str[1][20] = {0};
- int blink2Hz_toggle = 1;
- int blink1Hz_toggle = 1;
- uint8_t task_switch = 1;
- uint8_t task_changed = 0;
- while (1) {
- if (xSemaphoreTake(DrawReady, portMAX_DELAY) == pdTRUE) { // Block until screen is ready
- while (xQueueReceive(ButtonQueue, &buttonStatus, 0) == pdTRUE)
- ;
- // State machine input
- if (buttonCount(BUT_E)){
- xQueueSend(StateQueue, &next_state_signal, 100);
- }
- //Pausing and Resuming Task 3.2.4
- if (buttonCount(BUT_C)){
- task_switch = !task_switch;
- task_changed = 1;
- }
- if(task_changed == 1){
- if(task_switch == 1){
- vTaskResume(increaseVariableHandle);
- task_changed = 0;
- }
- else if(task_switch == 0){
- vTaskSuspend(increaseVariableHandle);
- task_changed = 0;
- }
- }
- // Clear background
- gdispClear(White);
- //Exercise 3.2.2
- if(xSemaphoreTake(BlinkCircle2Hz, 0) == pdTRUE){
- blink2Hz_toggle = !blink2Hz_toggle;
- }
- if(xSemaphoreTake(BlinkCircle1Hz, 0) == pdTRUE){
- blink1Hz_toggle = !blink1Hz_toggle;
- }
- if(blink2Hz_toggle == 1){
- gdispFillCircle(DISPLAY_SIZE_X / 2 - 20, DISPLAY_SIZE_Y / 2, 12, Blue);
- }
- if(blink1Hz_toggle == 1){
- gdispFillCircle(DISPLAY_SIZE_X / 2 + 20, DISPLAY_SIZE_Y / 2, 12, Red);
- }
- //Exercise 3.2.3
- if(xSemaphoreTake(ButtonAPressed, 0) == pdTRUE){
- button_A_count++;
- }
- if(xSemaphoreTake(ButtonBPressed, 0) == pdTRUE){
- button_B_count++;
- }
- if(xSemaphoreTake(ResetTimer, 0) == pdTRUE){
- button_A_count = 0;
- button_B_count = 0;
- }
- // Generate string with number of times buttons have been pressed
- sprintf(number_display_A, "A: %d", button_A_count);
- sprintf(number_display_B, "B: %d", button_B_count);
- // Print string of number of presses
- for (unsigned char i = 0; i < 1; i++){
- gdispDrawString(TEXT_X(number_display_A[i]) - 20, TEXT_Y(i) - 5, number_display_A[i], font1, Black);
- }
- for (unsigned char i = 0; i < 1; i++){
- gdispDrawString(TEXT_X(number_display_B[i]) + 20, TEXT_Y(i) - 5, number_display_B[i], font1, Black);
- }
- for (unsigned char i = 0; i < 2; i++)
- gdispDrawString(TEXT_X(str[i]), TEXT_Y(i) + 15, str[i], font1, Black);
- //FPS from 3.2.2.6
- xQueueReceive(FPSQueue, &fps_num, 0);
- sprintf(fps, "FPS: %d", fps_num);
- for (unsigned char i = 0; i < 1; i++)
- gdispDrawString(TEXT_X(fps[i]), TEXT_Y(i) + 5, fps[i], font1, Black);
- //Exercise 3.2.4
- if(xSemaphoreTake(increaseVariable_Semaphore, 0)){
- counter324++;
- }
- sprintf(counter324_str, "Ex. 3.2.4: %d", counter324);
- for (unsigned char i = 0; i < 1; i++)
- gdispDrawString(TEXT_X(counter324_str[i]), TEXT_Y(i) -15, counter324_str[i], font1, Black);
- }
- }
- }
- void exercise3Display(void * params){
- char str[1][70] = { " EXERCISE 4 " };
- struct buttons buttonStatus; // joystick queue input buffer
- const unsigned char next_state_signal = PREV_TASK;
- while (1) {
- if (xSemaphoreTake(DrawReady, portMAX_DELAY) == pdTRUE) { // Block until screen is ready
- while (xQueueReceive(ButtonQueue, &buttonStatus, 0) == pdTRUE)
- ;
- // State machine input
- if (buttonCount(BUT_E)){
- xQueueSend(StateQueue, &next_state_signal, 100);
- }
- // Clear background
- gdispClear(White);
- for (unsigned char i = 0; i < 1; i++)
- gdispDrawString(TEXT_X(str[i]), TEXT_Y(i) + 15, str[i], font1, Black);
- }
- }
- }
- //Exercise 3.2.2
- void circleBlinkDynamic(void *params){
- TickType_t xLastTickTime;
- xLastTickTime = xTaskGetTickCount();
- const TickType_t delayPeriod = 250;
- //unsigned int blink_var = 1;
- while (1) {
- xSemaphoreGive(BlinkCircle2Hz);
- vTaskDelay(delayPeriod);
- }
- }
- void circleBlinkStatic(void *params){
- TickType_t xLastTickTime;
- xLastTickTime = xTaskGetTickCount();
- const TickType_t delayPeriod = 500;
- while (1) {
- xSemaphoreGive(BlinkCircle1Hz);
- vTaskDelayUntil(&xLastTickTime, delayPeriod);
- }
- }
- //Exercise 3.2.3
- void timesButtonAPressed(void * params){
- TickType_t xLastTickTime;
- xLastTickTime = xTaskGetTickCount();
- const TickType_t pollingRate = 20;
- while(1){
- if(buttonCount(BUT_A)){
- xSemaphoreGive(ButtonAPressed);
- }
- vTaskDelayUntil(&xLastTickTime, pollingRate);
- }
- }
- void timesButtonBPressed(void * params){
- TickType_t xLastTickTime;
- xLastTickTime = xTaskGetTickCount();
- const TickType_t pollingRate = 20;
- while(1){
- if(buttonCount(BUT_B)){
- xSemaphoreGive(ButtonBPressed);
- }
- vTaskDelayUntil(&xLastTickTime, pollingRate);
- }
- }
- void resetTimer(void * params){
- TickType_t xLastTickTime;
- xLastTickTime = xTaskGetTickCount();
- const TickType_t delayTime = RESET_TIMER_EX_3 * 1000; //times 1000 to convert sec to ms
- while(1){
- xSemaphoreGive(ResetTimer);
- vTaskDelayUntil(&xLastTickTime, delayTime);
- }
- }
- //Exercise 3.2.4
- void increaseVariable(void * params){
- TickType_t xLastTickTime;
- xLastTickTime = xTaskGetTickCount();
- const TickType_t delayTime = 1000; // 1 second
- while(1){
- //code
- xSemaphoreGive(increaseVariable_Semaphore);
- vTaskDelayUntil(&xLastTickTime, delayTime);
- }
- }
- /**
- * This task polls the joystick value every 20 ticks
- */
- void checkButtons(void * params) {
- TickType_t xLastWakeTime;
- xLastWakeTime = xTaskGetTickCount();
- struct buttons buttonStatus = { { 0 } };
- const TickType_t PollingRate = 20;
- while (TRUE) {
- // Remember last joystick values
- buttonStatus.joystick.x = (uint8_t)(
- ADC_GetConversionValue(ESPL_ADC_Joystick_2) >> 4);
- buttonStatus.joystick.y = (uint8_t) 255
- - (ADC_GetConversionValue(ESPL_ADC_Joystick_1) >> 4);
- //get direct joystick value readout
- buttonStatus.joystick_direct.x = (uint8_t)(
- ADC_GetConversionValue(ESPL_ADC_Joystick_2) >> 4);
- buttonStatus.joystick_direct.y = (uint8_t) 255
- - (ADC_GetConversionValue(ESPL_ADC_Joystick_1) >> 4);
- // Buttons not debounced, delaying does not count as debouncing
- buttonStatus.A = !GPIO_ReadInputDataBit(ESPL_Register_Button_A,
- ESPL_Pin_Button_A);
- buttonStatus.B = !GPIO_ReadInputDataBit(ESPL_Register_Button_B,
- ESPL_Pin_Button_B);
- buttonStatus.C = !GPIO_ReadInputDataBit(ESPL_Register_Button_C,
- ESPL_Pin_Button_C);
- buttonStatus.D = !GPIO_ReadInputDataBit(ESPL_Register_Button_D,
- ESPL_Pin_Button_D);
- buttonStatus.E = !GPIO_ReadInputDataBit(ESPL_Register_Button_E,
- ESPL_Pin_Button_E);
- buttonStatus.K = !GPIO_ReadInputDataBit(ESPL_Register_Button_K,
- ESPL_Pin_Button_K);
- xQueueSend(ButtonQueue, &buttonStatus, 100);
- // Execute every 20 Ticks
- vTaskDelayUntil(&xLastWakeTime, PollingRate);
- }
- }
- /**
- * Example function to send data over UART
- *
- * Sends coordinates of a given position via UART.
- * Structure of a package:
- * 8 bit start byte
- * 8 bit x-coordinate
- * 8 bit y-coordinate
- * 8 bit checksum (= x-coord XOR y-coord)
- * 8 bit stop byte
- */
- void sendPosition(struct buttons buttonStatus) {
- const uint8_t checksum = buttonStatus.joystick.x ^ buttonStatus.joystick.y
- ^ buttonStatus.A ^ buttonStatus.B ^ buttonStatus.C ^ buttonStatus.D
- ^ buttonStatus.E ^ buttonStatus.K;
- UART_SendData(startByte);
- UART_SendData(buttonStatus.joystick.x);
- UART_SendData(buttonStatus.joystick.y);
- UART_SendData(buttonStatus.A);
- UART_SendData(buttonStatus.B);
- UART_SendData(buttonStatus.C);
- UART_SendData(buttonStatus.D);
- UART_SendData(buttonStatus.E);
- UART_SendData(buttonStatus.K);
- UART_SendData(checksum);
- UART_SendData(stopByte);
- }
- /**
- * Example how to receive data over UART (see protocol above)
- */
- void uartReceive() {
- char input;
- uint8_t pos = 0;
- char checksum;
- char buffer[11]; // Start byte,4* line byte, checksum (all xor), End byte
- struct buttons buttonStatus = { { 0 } };
- while (TRUE) {
- // wait for data in queue
- xQueueReceive(ESPL_RxQueue, &input, portMAX_DELAY);
- // decode package by buffer position
- switch (pos) {
- // start byte
- case 0:
- if (input != startByte)
- break;
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- // read received data in buffer
- buffer[pos] = input;
- pos++;
- break;
- case 10:
- // Check if package is corrupted
- checksum = buffer[1] ^ buffer[2] ^ buffer[3] ^ buffer[4] ^ buffer[5]
- ^ buffer[6] ^ buffer[7] ^ buffer[8];
- if (input == stopByte || checksum == buffer[9]) {
- // pass position to Joystick Queue
- buttonStatus.joystick.x = buffer[1];
- buttonStatus.joystick.y = buffer[2];
- buttonStatus.A = buffer[3];
- buttonStatus.B = buffer[4];
- buttonStatus.C = buffer[5];
- buttonStatus.D = buffer[6];
- buttonStatus.E = buffer[7];
- buttonStatus.K = buffer[8];
- xQueueSend(ButtonQueue, &buttonStatus, 100);
- }
- pos = 0;
- }
- }
- }
- // only toggle the LED if the new button state is HIGH
- /*
- * Hook definitions needed for FreeRTOS to function.
- */
- void vApplicationIdleHook() {
- while (TRUE) {
- };
- }
- void vApplicationMallocFailedHook() {
- while (TRUE) {
- };
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement