Advertisement
Guest User

Untitled

a guest
Nov 14th, 2019
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.80 KB | None | 0 0
  1. /**
  2. * This is the main file of the ESPLaboratory Demo project.
  3. * It implements simple sample functions for the usage of UART,
  4. * writing to the display and processing user inputs.
  5. *
  6. * @author: Alex Hoffman alex.hoffman@tum.de (RCS, TUM)
  7. * Jonathan M��ller-Boruttau,
  8. * Tobias Fuchs tobias.fuchs@tum.de
  9. * Nadja Peters nadja.peters@tum.de (RCS, TUM)
  10. *
  11. */
  12. #include "includes.h"
  13. #include <math.h>
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <time.h>
  17. #include <unistd.h>
  18. #include "buttonDebounce.h"
  19. #include "staticFunctions.h"
  20.  
  21. #define DISPLAY_SIZE_X 320
  22. #define DISPLAY_SIZE_Y 240
  23.  
  24. #define PAUSED_TEXT_X(TEXT) DISPLAY_SIZE_X / 2 - (gdispGetStringWidth(TEXT, font1) / 2)
  25. #define PAUSED_TEXT_Y(LINE) DISPLAY_SIZE_Y / 2 - (gdispGetFontMetric(font1, fontHeight) * -(LINE + 0.5))
  26.  
  27. #define TEXT_X(TEXT) DISPLAY_SIZE_X / 2 - (gdispGetStringWidth(TEXT, font1) / 2)
  28. #define TEXT_Y(LINE) DISPLAY_SIZE_Y / 2 - (gdispGetFontMetric(font1, fontHeight) * -(LINE + 0.5)) + 65
  29.  
  30. #define SLIDING_TEXT_X(TEXT) DISPLAY_SIZE_X / 2 - (gdispGetStringWidth(TEXT, font1) / 2) + sliderCounter() - 100
  31. #define SLIDING_TEXT_Y(LINE) DISPLAY_SIZE_Y / 2 - (gdispGetFontMetric(font1, fontHeight) * -(LINE + 0.5)) - 100
  32.  
  33. #define PI 3.14159265
  34. #define RAD_CONVERSION PI / 180
  35. #define ROTATION_RADIUS_CIRCLE 40
  36. #define ROTATING_CIRCLE_X DISPLAY_SIZE_X / 2 + ROTATION_RADIUS_CIRCLE * cos(circleRotate() * RAD_CONVERSION)
  37. #define ROTATING_CIRCLE_Y DISPLAY_SIZE_Y / 2 - 5 + ROTATION_RADIUS_CIRCLE * sin(circleRotate() * RAD_CONVERSION)
  38.  
  39. #define ROTATION_RADIUS_SQUARE 40
  40. #define ROTATING_SQUARE_X DISPLAY_SIZE_X / 2 + ROTATION_RADIUS_SQUARE * cos((circleRotate() + 180) * RAD_CONVERSION)
  41. #define ROTATING_SQUARE_Y DISPLAY_SIZE_Y / 2 + ROTATION_RADIUS_SQUARE * sin((circleRotate() + 180) * RAD_CONVERSION)
  42.  
  43. #define SCREEN_SLIDE_X screenMovementX()
  44. #define SCREEN_SLIDE_Y screenMovementY()
  45.  
  46. #define BUTTON_QUEUE_LENGTH 20
  47. #define STATE_QUEUE_LENGTH 1
  48. #define FPS_QUEUE_LENGTH 20
  49.  
  50. #define STATE_COUNT 3
  51.  
  52. #define STATE_ONE 1
  53. #define STATE_TWO 2
  54. #define STATE_THREE 3
  55.  
  56. #define NEXT_TASK 1
  57. #define PREV_TASK 2
  58. #define START_COUNTER_324 1
  59. #define STOP_COUNTER_324 2
  60. #define NUM_POINTS (sizeof(triangle)/sizeof(triangle[0]))
  61.  
  62. #define STACK_SIZE 200
  63. #define RESET_TIMER_EX_3 15 //In seconds
  64.  
  65. // Read only, there should be no globals being written to that are not locked via semaphores etc
  66. // Start and stop bytes for the UART protocol
  67. static const uint8_t startByte = 0xAA, stopByte = 0x55;
  68.  
  69. //Coordinates for the triangle we are using in exercise 1
  70. static const point triangle[] = {
  71. { -15, 0 },
  72. { 0 , -20 },
  73. { 15, 0 },
  74. };
  75.  
  76.  
  77. font_t font1; // Load font for ugfx
  78.  
  79. //Function prototypes
  80. void frameSwapTask(void * params);
  81. void basicStateMachine(void * params);
  82. void checkButtons(void * params);
  83.  
  84. void exercise1Display(void * params);
  85. void exercise2Display(void * params);
  86. void exercise3Display(void * params);
  87.  
  88. //Exercise 3.2.2
  89. void circleBlinkDynamic(void *params);
  90. void circleBlinkStatic(void * params);
  91.  
  92. //Exercise 3.2.3
  93. void timesButtonAPressed(void * params);
  94. void timesButtonBPressed(void * params);
  95. void resetTimer(void * params);
  96.  
  97. //Exercise 3.2.4
  98. void increaseVariable(void * params);
  99.  
  100. QueueHandle_t ESPL_RxQueue; // Already defined in ESPL_Functions.h
  101. SemaphoreHandle_t ESPL_DisplayReady;
  102. SemaphoreHandle_t DrawReady; // After swapping buffer calll drawing
  103.  
  104. //Exercise 3.2.2
  105. SemaphoreHandle_t BlinkCircle2Hz;
  106. SemaphoreHandle_t BlinkCircle1Hz;
  107.  
  108. //Exercise 3.2.3
  109. SemaphoreHandle_t ButtonAPressed;
  110. SemaphoreHandle_t ButtonBPressed;
  111. SemaphoreHandle_t ResetTimer;
  112.  
  113. //Exercise 3.2.4
  114. SemaphoreHandle_t increaseVariable_Semaphore;
  115.  
  116. /*
  117. * All variables handled by multiple tasks should be sent in SAFE ways, ie. using queues.
  118. * Global variables should only be used for managing handles to the RTOS components used
  119. * to perform thread safe, multi-threaded programming.
  120. */
  121. // Stores lines to be drawn
  122. QueueHandle_t ButtonQueue;
  123. QueueHandle_t StateQueue;
  124. QueueHandle_t FPSQueue;
  125. QueueHandle_t resetTimerQueue;
  126.  
  127. // Task handles, used for task control
  128. TaskHandle_t frameSwapHandle;
  129. TaskHandle_t exercise1DisplayHandle;
  130. TaskHandle_t exercise2DisplayHandle;
  131. TaskHandle_t exercise3DisplayHandle;
  132. TaskHandle_t stateMachineHandle;
  133.  
  134. //Exercise 3.2.2
  135. TaskHandle_t circleBlinkDynamicHandle;
  136. StaticTask_t xTaskBuffer;
  137. StackType_t xStack[ STACK_SIZE ];
  138.  
  139. //Exercise 3.2.3
  140. TaskHandle_t timesButtonAPressedHandle;
  141. TaskHandle_t timesButtonBPressedHandle;
  142. TaskHandle_t resetTimerHandle;
  143.  
  144. //Exercise 3.2.4
  145. TaskHandle_t increaseVariableHandle;
  146.  
  147. int main(void){
  148.  
  149.  
  150. // Initialize Board functions and graphics
  151. ESPL_SystemInit();
  152.  
  153. font1 = gdispOpenFont("DejaVuSans24*");
  154.  
  155. // Initializes Draw Queue with 100 lines buffer
  156. ButtonQueue = xQueueCreate(BUTTON_QUEUE_LENGTH, sizeof(struct buttons));
  157. StateQueue = xQueueCreate(STATE_QUEUE_LENGTH, sizeof(unsigned char));
  158. FPSQueue = xQueueCreate(FPS_QUEUE_LENGTH, sizeof(uint8_t));
  159. resetTimerQueue = xQueueCreate(FPS_QUEUE_LENGTH, sizeof(unsigned char));
  160.  
  161. ESPL_DisplayReady = xSemaphoreCreateBinary();
  162. DrawReady = xSemaphoreCreateBinary();
  163.  
  164. //Exercise 3.2.2
  165. BlinkCircle2Hz = xSemaphoreCreateBinary();
  166. BlinkCircle1Hz = xSemaphoreCreateBinary();
  167.  
  168.  
  169. //Exercise 3.2.3
  170. ButtonAPressed = xSemaphoreCreateBinary();
  171. ButtonBPressed = xSemaphoreCreateBinary();
  172. ResetTimer = xSemaphoreCreateBinary();
  173.  
  174. //Exercise 3.2.4
  175. increaseVariable_Semaphore = xSemaphoreCreateBinary();
  176.  
  177.  
  178. // Initializes Tasks with their respective priority
  179. // Core tasks
  180. xTaskCreate(frameSwapTask, "frameSwapper", 1000, NULL, 4, &frameSwapHandle);
  181. xTaskCreate(basicStateMachine, "StateMachine", 1000, NULL, 3, stateMachineHandle);
  182. xTaskCreate(checkButtons, "checkButtons", 1000, NULL, 3, NULL);
  183.  
  184. // display tasks for the different exercises
  185. xTaskCreate(exercise1Display, "exercise1Display", 1000, NULL, 2, &exercise1DisplayHandle);
  186. xTaskCreate(exercise2Display, "exercise2Display", 1000, NULL, 2, &exercise2DisplayHandle);
  187. xTaskCreate(exercise3Display, "exercise3Display", 1000, NULL, 2, &exercise3DisplayHandle);
  188.  
  189. //Exercise 3.2.2
  190. xTaskCreate(circleBlinkDynamic, "circleBlinkDynamic", 1000, NULL, 3, &circleBlinkDynamicHandle);
  191. xTaskCreateStatic(circleBlinkStatic, "circleBlinkStatic", 200, NULL, 4, xStack, &xTaskBuffer);
  192.  
  193.  
  194. //Exercise 3.2.3
  195. xTaskCreate(timesButtonAPressed, "timesButtonAPressed", 1000, NULL, 2, &timesButtonAPressedHandle);
  196. xTaskCreate(timesButtonBPressed, "timesButtonBPressed", 1000, NULL, 3, &timesButtonBPressedHandle);
  197. xTaskCreate(resetTimer, "resetTimer", 1000, NULL, 2, &resetTimerHandle);
  198.  
  199. //Exercise 3.2.4
  200. xTaskCreate(increaseVariable, "increaseVariable", 1000, NULL, 3, &increaseVariableHandle);
  201.  
  202. vTaskSuspend(exercise1DisplayHandle);
  203. vTaskSuspend(exercise2DisplayHandle);
  204. vTaskSuspend(exercise3DisplayHandle);
  205.  
  206. // Start FreeRTOS Scheduler
  207. vTaskStartScheduler();
  208. }
  209.  
  210. /*
  211. * Frame swapping happens in the background, seperate to all other system tasks.
  212. * This way it can be guarenteed that the 50fps requirement of the system
  213. * can be met.
  214. */
  215. void frameSwapTask(void * params) {
  216. TickType_t xLastWakeTime;
  217. xLastWakeTime = xTaskGetTickCount();
  218. TickType_t xOldWakeTime;
  219. xOldWakeTime = 0;
  220. const TickType_t frameratePeriod = 20;
  221.  
  222. while (1) {
  223.  
  224. // Draw next frame
  225. xSemaphoreGive(DrawReady);
  226. // Wait for display to stop writing
  227. xSemaphoreTake(ESPL_DisplayReady, portMAX_DELAY);
  228. // Swap buffers
  229. ESPL_DrawLayer();
  230. xOldWakeTime = xLastWakeTime;
  231. vTaskDelayUntil(&xLastWakeTime, frameratePeriod);
  232. TickType_t xDifference;
  233. xDifference = xLastWakeTime - xOldWakeTime;
  234. uint8_t xFPS = 1000 / xDifference;
  235. xQueueSend(FPSQueue, &xFPS, 0);
  236. }
  237. }
  238.  
  239. /*
  240. * Changes the state, either forwards of backwards
  241. */
  242. void changeState(volatile unsigned char *state, unsigned char forwards) {
  243.  
  244. switch (forwards) {
  245. case 0:
  246. if (*state == 0)
  247. *state = STATE_COUNT;
  248. else
  249. (*state)--;
  250. break;
  251. case 1:
  252. if (*state == STATE_COUNT)
  253. *state = 0;
  254. else
  255. (*state)++;
  256. break;
  257. default:
  258. break;
  259. }
  260. }
  261.  
  262. /*
  263. * Example basic state machine with sequential states
  264. */
  265. void basicStateMachine(void * params) {
  266. unsigned char current_state = 1; // Default state
  267. //unsigned int switch_state_direction = 1; //Default state switching direction is 1, incrementing
  268. unsigned char state_changed = 1; // Only re-evaluate state if it has changed
  269. unsigned char input = 0;
  270. unsigned char input_counter = 0;
  271. unsigned char toggle_counter_changed = 0;
  272. unsigned char toggle_counter = 0;
  273.  
  274. while (1) {
  275.  
  276. if (state_changed)
  277. goto initial_state;
  278.  
  279. // Handle state machine input
  280. if (xQueueReceive(StateQueue, &input, portMAX_DELAY) == pdTRUE) {
  281. if (input == NEXT_TASK) {
  282. changeState(&current_state, 1);
  283. state_changed = 1;
  284. }
  285. else if (input == PREV_TASK) {
  286. changeState(&current_state, 0);
  287. changeState(&current_state, 0);
  288. state_changed = 1;
  289. }
  290. }
  291.  
  292. //Exercise 3.2.4
  293. /*
  294. if (xQueueReceive(resetTimerQueue, &input_counter, portMAX_DELAY) == pdTRUE) {
  295. if (input_counter == START_COUNTER) {
  296. toggle_counter_changed = 1;
  297. toggle_counter = input_counter;
  298. }
  299. else if (input_counter == START_COUNTER) {
  300. toggle_counter_changed = 1;
  301. toggle_counter = input_counter;
  302. }
  303. }
  304. */
  305.  
  306. initial_state:
  307. // Handle current state
  308. if (state_changed) {
  309. switch (current_state) {
  310. case STATE_ONE:
  311. vTaskSuspend(exercise2DisplayHandle);
  312. vTaskSuspend(exercise3DisplayHandle);
  313. vTaskResume(exercise1DisplayHandle);
  314. state_changed = 0;
  315. break;
  316. case STATE_TWO:
  317. vTaskSuspend(exercise1DisplayHandle);
  318. vTaskSuspend(exercise3DisplayHandle);
  319. vTaskResume(exercise2DisplayHandle);
  320. state_changed = 0;
  321. break;
  322. case STATE_THREE:
  323. vTaskSuspend(exercise1DisplayHandle);
  324. vTaskSuspend(exercise2DisplayHandle);
  325. vTaskResume(exercise3DisplayHandle);
  326. state_changed = 0;
  327. break;
  328. default:
  329. break;
  330. }
  331. }
  332.  
  333. //Exercise 3.2.4
  334. /*
  335. if(toggle_counter_changed){
  336. switch (toggle_counter){
  337. case START_COUNTER:
  338. vTaskResume(increaseVariable);
  339. break;
  340. case STOP_COUNTER:
  341. vTaskSuspend(increaseVariable);
  342. break;
  343. default:
  344. break;
  345. }
  346. }
  347. */
  348.  
  349. }
  350. }
  351.  
  352.  
  353. void exercise1Display(void * params) {
  354. char str[100]; // buffer for messages to draw to display
  355. struct buttons buttonStatus; // joystick queue input buffer
  356. const unsigned char next_state_signal = NEXT_TASK;
  357.  
  358. /* building the cave:
  359. caveX and caveY define the top left corner of the cave
  360. circle movment is limited by 64px from center in every direction
  361. (coordinates are stored as uint8_t unsigned bytes)
  362. so, cave size is 128px */
  363. //const uint16_t caveX = DISPLAY_SIZE_X / 2 - UINT8_MAX / 4, caveY =
  364. //DISPLAY_SIZE_Y / 2 - UINT8_MAX / 4, caveSize = UINT8_MAX / 2;
  365.  
  366.  
  367. int press_count_A = 0, press_count_B = 0, press_count_C = 0, press_count_D = 0;
  368.  
  369.  
  370. int sliding_text_position = 0, sliding_text_direction = 1;
  371.  
  372. int sliderCounter(){
  373. int m = sliding_text_position;
  374. if(sliding_text_position == 0){
  375. sliding_text_position++;
  376. sliding_text_direction = 0;
  377. return m;
  378. }
  379. if (sliding_text_position < 200){
  380. if(!sliding_text_direction){
  381. sliding_text_position++;
  382. return m;
  383. }
  384. else{
  385. sliding_text_position--;
  386. return m;
  387. }
  388. }
  389. if (sliding_text_position == 200){
  390. sliding_text_position--;
  391. sliding_text_direction = 1;
  392. return m;
  393. }
  394. }
  395.  
  396.  
  397. int circle_angle = 0;
  398.  
  399. int circleRotate(){
  400. int internal_angle = circle_angle;
  401. if(circle_angle < 360){
  402. circle_angle++;
  403. return internal_angle;
  404. }
  405. if(circle_angle == 360){
  406. circle_angle = 0;
  407. return internal_angle;
  408. }
  409. }
  410.  
  411.  
  412. int screen_slide_x = 0;
  413. int screen_slide_y = 0;
  414.  
  415. int screenMovementX(){
  416. int internal_x = screen_slide_x;
  417. internal_x = (buttonStatus.joystick.x / 8);
  418. return internal_x;
  419. }
  420. int screenMovementY(){
  421. int internal_y = screen_slide_y;
  422. internal_y = (buttonStatus.joystick.y / 8);
  423. return internal_y;
  424. }
  425.  
  426. // Start endless loop
  427. while (1) {
  428.  
  429. if (xSemaphoreTake(DrawReady, portMAX_DELAY) == pdTRUE) { // Block until screen is ready
  430.  
  431. while (xQueueReceive(ButtonQueue, &buttonStatus, 0) == pdTRUE)
  432. ;
  433.  
  434. // State machine input
  435. if (buttonCount(BUT_E))
  436. xQueueSend(StateQueue, &next_state_signal, 100);
  437.  
  438. // Clear background
  439. gdispClear(White);
  440.  
  441.  
  442. // Generate string with current joystick values
  443. sprintf(str, "X from left: %5d|Y from top: %5d|VBat: %5d",
  444. buttonStatus.joystick.x, buttonStatus.joystick.y,
  445. ADC_GetConversionValue(ESPL_ADC_VBat));
  446. // Print string of joystick values
  447. gdispDrawString(SCREEN_SLIDE_X,SCREEN_SLIDE_Y, str, font1, Black);
  448.  
  449.  
  450. //count number of presses
  451. if(buttonCount(BUT_A)){
  452. press_count_A++;
  453. }
  454. if(buttonCount(BUT_B)){
  455. press_count_B++;
  456. }
  457. if(buttonCount(BUT_C)){
  458. press_count_C++;
  459. }
  460. if(buttonCount(BUT_D)){
  461. press_count_D++;
  462. }
  463. if(buttonCount(BUT_K)){
  464. press_count_A = 0;
  465. press_count_B = 0;
  466. press_count_C = 0;
  467. press_count_D = 0;
  468. }
  469.  
  470. // Generate string with number of times buttons have been pressed
  471. sprintf(str, "A: %d|B: %d|C: %d|D: %d", press_count_A,
  472. press_count_B, press_count_C, press_count_D);
  473.  
  474. // Print string of number of presses
  475. gdispDrawString(SCREEN_SLIDE_X, 11 + SCREEN_SLIDE_Y, str, font1, Black);
  476.  
  477.  
  478. //Draw small teal triangle in the center
  479. gdispFillConvexPoly(DISPLAY_SIZE_X / 2 + SCREEN_SLIDE_X, DISPLAY_SIZE_Y / 2 + SCREEN_SLIDE_Y, triangle, NUM_POINTS, Teal);
  480.  
  481. //Draw rotating orange square
  482. gdispFillArea(ROTATING_SQUARE_X + SCREEN_SLIDE_X, ROTATING_SQUARE_Y + SCREEN_SLIDE_Y, 12, 12, Orange);
  483.  
  484. //Draw rotating olive circle
  485. gdispFillCircle(ROTATING_CIRCLE_X + SCREEN_SLIDE_X, ROTATING_CIRCLE_Y + SCREEN_SLIDE_Y, 12, Olive);
  486.  
  487.  
  488. //displaying sliding text above figures
  489. char str_slide[1][70] = { "ESPL LAB"};
  490. for (unsigned char j = 0; j < 1; j++)
  491. gdispDrawString(SLIDING_TEXT_X(str_slide[j]) + SCREEN_SLIDE_X, SLIDING_TEXT_Y(j) + SCREEN_SLIDE_Y, str_slide[j],
  492. font1, Black);
  493.  
  494.  
  495. //displaying text below figures
  496. char str[1][70] = {"GIVE ME A 100 PERCENT"};
  497. for (unsigned char i = 0; i < 1; i++)
  498. gdispDrawString(TEXT_X(str[i]) + SCREEN_SLIDE_X, TEXT_Y(i) + SCREEN_SLIDE_Y, str[i],
  499. font1, Black);
  500. }
  501. }
  502. }
  503.  
  504. void exercise2Display(void * params) {
  505. char str[2][70] = { "EXERCISE 3", "Blue circle is dynamic, red is static" };
  506. struct buttons buttonStatus; // joystick queue input buffer
  507. const unsigned char next_state_signal = NEXT_TASK;
  508. unsigned int button_A_count = 0;
  509. unsigned int button_B_count = 0;
  510. char number_display_A[1][70] = {0};
  511. char number_display_B[1][70] = {0};
  512. char fps[1][20] = {0};
  513. uint8_t fps_num;
  514. uint8_t counter324 = 0;
  515. char counter324_str[1][20] = {0};
  516.  
  517. int blink2Hz_toggle = 1;
  518. int blink1Hz_toggle = 1;
  519.  
  520.  
  521. uint8_t task_switch = 1;
  522. uint8_t task_changed = 0;
  523.  
  524. while (1) {
  525. if (xSemaphoreTake(DrawReady, portMAX_DELAY) == pdTRUE) { // Block until screen is ready
  526.  
  527. while (xQueueReceive(ButtonQueue, &buttonStatus, 0) == pdTRUE)
  528. ;
  529.  
  530. // State machine input
  531. if (buttonCount(BUT_E)){
  532. xQueueSend(StateQueue, &next_state_signal, 100);
  533. }
  534.  
  535. //Pausing and Resuming Task 3.2.4
  536. if (buttonCount(BUT_C)){
  537. task_switch = !task_switch;
  538. task_changed = 1;
  539. }
  540. if(task_changed == 1){
  541. if(task_switch == 1){
  542. vTaskResume(increaseVariableHandle);
  543. task_changed = 0;
  544. }
  545. else if(task_switch == 0){
  546. vTaskSuspend(increaseVariableHandle);
  547. task_changed = 0;
  548. }
  549. }
  550.  
  551.  
  552. // Clear background
  553. gdispClear(White);
  554.  
  555. //Exercise 3.2.2
  556. if(xSemaphoreTake(BlinkCircle2Hz, 0) == pdTRUE){
  557. blink2Hz_toggle = !blink2Hz_toggle;
  558. }
  559. if(xSemaphoreTake(BlinkCircle1Hz, 0) == pdTRUE){
  560. blink1Hz_toggle = !blink1Hz_toggle;
  561. }
  562.  
  563. if(blink2Hz_toggle == 1){
  564. gdispFillCircle(DISPLAY_SIZE_X / 2 - 20, DISPLAY_SIZE_Y / 2, 12, Blue);
  565. }
  566. if(blink1Hz_toggle == 1){
  567. gdispFillCircle(DISPLAY_SIZE_X / 2 + 20, DISPLAY_SIZE_Y / 2, 12, Red);
  568. }
  569.  
  570.  
  571. //Exercise 3.2.3
  572. if(xSemaphoreTake(ButtonAPressed, 0) == pdTRUE){
  573. button_A_count++;
  574. }
  575.  
  576. if(xSemaphoreTake(ButtonBPressed, 0) == pdTRUE){
  577. button_B_count++;
  578. }
  579.  
  580. if(xSemaphoreTake(ResetTimer, 0) == pdTRUE){
  581. button_A_count = 0;
  582. button_B_count = 0;
  583. }
  584.  
  585. // Generate string with number of times buttons have been pressed
  586. sprintf(number_display_A, "A: %d", button_A_count);
  587. sprintf(number_display_B, "B: %d", button_B_count);
  588.  
  589. // Print string of number of presses
  590. for (unsigned char i = 0; i < 1; i++){
  591. gdispDrawString(TEXT_X(number_display_A[i]) - 20, TEXT_Y(i) - 5, number_display_A[i], font1, Black);
  592. }
  593. for (unsigned char i = 0; i < 1; i++){
  594. gdispDrawString(TEXT_X(number_display_B[i]) + 20, TEXT_Y(i) - 5, number_display_B[i], font1, Black);
  595. }
  596.  
  597. for (unsigned char i = 0; i < 2; i++)
  598. gdispDrawString(TEXT_X(str[i]), TEXT_Y(i) + 15, str[i], font1, Black);
  599.  
  600.  
  601. //FPS from 3.2.2.6
  602. xQueueReceive(FPSQueue, &fps_num, 0);
  603. sprintf(fps, "FPS: %d", fps_num);
  604. for (unsigned char i = 0; i < 1; i++)
  605. gdispDrawString(TEXT_X(fps[i]), TEXT_Y(i) + 5, fps[i], font1, Black);
  606.  
  607. //Exercise 3.2.4
  608. if(xSemaphoreTake(increaseVariable_Semaphore, 0)){
  609. counter324++;
  610. }
  611. sprintf(counter324_str, "Ex. 3.2.4: %d", counter324);
  612. for (unsigned char i = 0; i < 1; i++)
  613. gdispDrawString(TEXT_X(counter324_str[i]), TEXT_Y(i) -15, counter324_str[i], font1, Black);
  614.  
  615. }
  616. }
  617. }
  618.  
  619. void exercise3Display(void * params){
  620. char str[1][70] = { " EXERCISE 4 " };
  621. struct buttons buttonStatus; // joystick queue input buffer
  622.  
  623. const unsigned char next_state_signal = PREV_TASK;
  624.  
  625. while (1) {
  626. if (xSemaphoreTake(DrawReady, portMAX_DELAY) == pdTRUE) { // Block until screen is ready
  627.  
  628. while (xQueueReceive(ButtonQueue, &buttonStatus, 0) == pdTRUE)
  629. ;
  630.  
  631. // State machine input
  632. if (buttonCount(BUT_E)){
  633. xQueueSend(StateQueue, &next_state_signal, 100);
  634. }
  635.  
  636. // Clear background
  637. gdispClear(White);
  638.  
  639. for (unsigned char i = 0; i < 1; i++)
  640. gdispDrawString(TEXT_X(str[i]), TEXT_Y(i) + 15, str[i], font1, Black);
  641. }
  642. }
  643. }
  644.  
  645.  
  646. //Exercise 3.2.2
  647. void circleBlinkDynamic(void *params){
  648. TickType_t xLastTickTime;
  649. xLastTickTime = xTaskGetTickCount();
  650. const TickType_t delayPeriod = 250;
  651. //unsigned int blink_var = 1;
  652. while (1) {
  653. xSemaphoreGive(BlinkCircle2Hz);
  654. vTaskDelay(delayPeriod);
  655. }
  656. }
  657.  
  658. void circleBlinkStatic(void *params){
  659. TickType_t xLastTickTime;
  660. xLastTickTime = xTaskGetTickCount();
  661. const TickType_t delayPeriod = 500;
  662. while (1) {
  663. xSemaphoreGive(BlinkCircle1Hz);
  664. vTaskDelayUntil(&xLastTickTime, delayPeriod);
  665. }
  666. }
  667.  
  668.  
  669. //Exercise 3.2.3
  670. void timesButtonAPressed(void * params){
  671. TickType_t xLastTickTime;
  672. xLastTickTime = xTaskGetTickCount();
  673. const TickType_t pollingRate = 20;
  674. while(1){
  675. if(buttonCount(BUT_A)){
  676. xSemaphoreGive(ButtonAPressed);
  677. }
  678. vTaskDelayUntil(&xLastTickTime, pollingRate);
  679. }
  680. }
  681.  
  682. void timesButtonBPressed(void * params){
  683. TickType_t xLastTickTime;
  684. xLastTickTime = xTaskGetTickCount();
  685. const TickType_t pollingRate = 20;
  686. while(1){
  687. if(buttonCount(BUT_B)){
  688. xSemaphoreGive(ButtonBPressed);
  689. }
  690. vTaskDelayUntil(&xLastTickTime, pollingRate);
  691. }
  692. }
  693.  
  694. void resetTimer(void * params){
  695. TickType_t xLastTickTime;
  696. xLastTickTime = xTaskGetTickCount();
  697. const TickType_t delayTime = RESET_TIMER_EX_3 * 1000; //times 1000 to convert sec to ms
  698. while(1){
  699. xSemaphoreGive(ResetTimer);
  700. vTaskDelayUntil(&xLastTickTime, delayTime);
  701. }
  702. }
  703.  
  704. //Exercise 3.2.4
  705. void increaseVariable(void * params){
  706. TickType_t xLastTickTime;
  707. xLastTickTime = xTaskGetTickCount();
  708. const TickType_t delayTime = 1000; // 1 second
  709. while(1){
  710. //code
  711. xSemaphoreGive(increaseVariable_Semaphore);
  712. vTaskDelayUntil(&xLastTickTime, delayTime);
  713. }
  714. }
  715.  
  716. /**
  717. * This task polls the joystick value every 20 ticks
  718. */
  719. void checkButtons(void * params) {
  720. TickType_t xLastWakeTime;
  721. xLastWakeTime = xTaskGetTickCount();
  722. struct buttons buttonStatus = { { 0 } };
  723. const TickType_t PollingRate = 20;
  724.  
  725. while (TRUE) {
  726. // Remember last joystick values
  727. buttonStatus.joystick.x = (uint8_t)(
  728. ADC_GetConversionValue(ESPL_ADC_Joystick_2) >> 4);
  729. buttonStatus.joystick.y = (uint8_t) 255
  730. - (ADC_GetConversionValue(ESPL_ADC_Joystick_1) >> 4);
  731.  
  732. //get direct joystick value readout
  733. buttonStatus.joystick_direct.x = (uint8_t)(
  734. ADC_GetConversionValue(ESPL_ADC_Joystick_2) >> 4);
  735. buttonStatus.joystick_direct.y = (uint8_t) 255
  736. - (ADC_GetConversionValue(ESPL_ADC_Joystick_1) >> 4);
  737.  
  738. // Buttons not debounced, delaying does not count as debouncing
  739. buttonStatus.A = !GPIO_ReadInputDataBit(ESPL_Register_Button_A,
  740. ESPL_Pin_Button_A);
  741. buttonStatus.B = !GPIO_ReadInputDataBit(ESPL_Register_Button_B,
  742. ESPL_Pin_Button_B);
  743. buttonStatus.C = !GPIO_ReadInputDataBit(ESPL_Register_Button_C,
  744. ESPL_Pin_Button_C);
  745. buttonStatus.D = !GPIO_ReadInputDataBit(ESPL_Register_Button_D,
  746. ESPL_Pin_Button_D);
  747. buttonStatus.E = !GPIO_ReadInputDataBit(ESPL_Register_Button_E,
  748. ESPL_Pin_Button_E);
  749. buttonStatus.K = !GPIO_ReadInputDataBit(ESPL_Register_Button_K,
  750. ESPL_Pin_Button_K);
  751.  
  752. xQueueSend(ButtonQueue, &buttonStatus, 100);
  753.  
  754. // Execute every 20 Ticks
  755. vTaskDelayUntil(&xLastWakeTime, PollingRate);
  756. }
  757. }
  758.  
  759. /**
  760. * Example function to send data over UART
  761. *
  762. * Sends coordinates of a given position via UART.
  763. * Structure of a package:
  764. * 8 bit start byte
  765. * 8 bit x-coordinate
  766. * 8 bit y-coordinate
  767. * 8 bit checksum (= x-coord XOR y-coord)
  768. * 8 bit stop byte
  769. */
  770. void sendPosition(struct buttons buttonStatus) {
  771. const uint8_t checksum = buttonStatus.joystick.x ^ buttonStatus.joystick.y
  772. ^ buttonStatus.A ^ buttonStatus.B ^ buttonStatus.C ^ buttonStatus.D
  773. ^ buttonStatus.E ^ buttonStatus.K;
  774.  
  775. UART_SendData(startByte);
  776. UART_SendData(buttonStatus.joystick.x);
  777. UART_SendData(buttonStatus.joystick.y);
  778. UART_SendData(buttonStatus.A);
  779. UART_SendData(buttonStatus.B);
  780. UART_SendData(buttonStatus.C);
  781. UART_SendData(buttonStatus.D);
  782. UART_SendData(buttonStatus.E);
  783. UART_SendData(buttonStatus.K);
  784. UART_SendData(checksum);
  785. UART_SendData(stopByte);
  786. }
  787.  
  788. /**
  789. * Example how to receive data over UART (see protocol above)
  790. */
  791. void uartReceive() {
  792. char input;
  793. uint8_t pos = 0;
  794. char checksum;
  795. char buffer[11]; // Start byte,4* line byte, checksum (all xor), End byte
  796. struct buttons buttonStatus = { { 0 } };
  797. while (TRUE) {
  798. // wait for data in queue
  799. xQueueReceive(ESPL_RxQueue, &input, portMAX_DELAY);
  800.  
  801. // decode package by buffer position
  802. switch (pos) {
  803. // start byte
  804. case 0:
  805. if (input != startByte)
  806. break;
  807. case 1:
  808. case 2:
  809. case 3:
  810. case 4:
  811. case 5:
  812. case 6:
  813. case 7:
  814. case 8:
  815. case 9:
  816. // read received data in buffer
  817. buffer[pos] = input;
  818. pos++;
  819. break;
  820. case 10:
  821. // Check if package is corrupted
  822. checksum = buffer[1] ^ buffer[2] ^ buffer[3] ^ buffer[4] ^ buffer[5]
  823. ^ buffer[6] ^ buffer[7] ^ buffer[8];
  824. if (input == stopByte || checksum == buffer[9]) {
  825. // pass position to Joystick Queue
  826. buttonStatus.joystick.x = buffer[1];
  827. buttonStatus.joystick.y = buffer[2];
  828. buttonStatus.A = buffer[3];
  829. buttonStatus.B = buffer[4];
  830. buttonStatus.C = buffer[5];
  831. buttonStatus.D = buffer[6];
  832. buttonStatus.E = buffer[7];
  833. buttonStatus.K = buffer[8];
  834. xQueueSend(ButtonQueue, &buttonStatus, 100);
  835. }
  836. pos = 0;
  837. }
  838. }
  839. }
  840. // only toggle the LED if the new button state is HIGH
  841.  
  842. /*
  843. * Hook definitions needed for FreeRTOS to function.
  844. */
  845. void vApplicationIdleHook() {
  846. while (TRUE) {
  847. };
  848. }
  849.  
  850. void vApplicationMallocFailedHook() {
  851. while (TRUE) {
  852. };
  853. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement