diff --git a/Core/Src/main.c b/Core/Src/main.c index b38c52aa1c8cd2b896a5e9ddec3fdee1ed257c40..7923db85fb488835020840a307e1de90a6dc923e 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -139,7 +139,7 @@ static void MX_USART3_UART_Init(void); static void MX_USB_OTG_FS_PCD_Init(void); static void MX_TIM2_Init(void); void Levels(void *argument); -void Task02(void *argument); +void LEDMatrix(void *argument); void Validate(void *argument); void Display(void *argument); @@ -246,7 +246,7 @@ int main(void) Task1Handle = osThreadNew(Levels, NULL, &Task1_attributes); /* creation of Task2 */ - Task2Handle = osThreadNew(Task02, NULL, &Task2_attributes); + Task2Handle = osThreadNew(LEDMatrix, NULL, &Task2_attributes); /* creation of Task3 */ Task3Handle = osThreadNew(Validate, NULL, &Task3_attributes); @@ -718,172 +718,165 @@ void Levels(void *argument) /* USER CODE END 5 */ } -/* USER CODE BEGIN Header_Task02 */ +/* USER CODE BEGIN Header_LEDMatrix */ /** * @brief Function implementing the Task2 thread. * @param argument: Not used * @retval None */ -/* USER CODE END Header_Task02 */ -void Task02(void *argument) +/* USER CODE END Header_LEDMatrix */ +void LEDMatrix(void *argument) { - /* USER CODE BEGIN Task02 */ - - // init constants & variables - enum ROW { ROW1, ROW2, ROW3, ROW4 }; - const uint8_t ROWS = 4; - const uint8_t FIELDS = 16; // 4 rows and 4 columns = 16 - uint32_t colors[] = { - WHITE - ,BLUE - ,PURPLE - ,RED - ,GREEN - ,ORANGE - ,TURQUOISE - ,YELLOW - ,SPRINGGREEN - ,OCEAN - ,CYAN - ,RASPBERRY - }; - uint32_t led_matrix[] = { - 0,0,0,0, - 0,0,0,0, - 0,0,0,0, - 0,0,0,0 - }; - - uint8_t num_colors = sizeof(colors) / sizeof(uint32_t); - LED led = *get_instance(); - const uint8_t gameRowXOR = 0xf; - uint16_t delay = 400; - bool isRunning = false; - bool scrollOut = false; - uint8_t scrollCounter = 0; - - // init Matrix - const uint8_t say_hi[] = {1,2,3,6,9,10,11,12,14,15}; - const uint8_t say_hi_length = sizeof(say_hi) / sizeof(uint8_t); - for(uint8_t i=0; i < say_hi_length-3; i++) led_matrix[say_hi[i]] = TURQUOISE; - for(uint8_t i=say_hi_length-3; i < say_hi_length; i++) led_matrix[say_hi[i]] = RED; - - /* Infinite loop */ - while(1) { - - // set led matrix to current colors - led.LED_set_all_off(0); - uint8_t LEDMatrixIndex = 0; - for(uint8_t cube = 0; cube < FIELDS;) { - for(uint8_t column = 0; column <= 6; column+=2) { - led.LED_set_RGB_32(LEDMatrixIndex , led_matrix[cube]); - led.LED_set_RGB_32(LEDMatrixIndex ^ gameRowXOR , led_matrix[cube]); - led.LED_set_RGB_32(LEDMatrixIndex+1 , led_matrix[cube]); - led.LED_set_RGB_32(LEDMatrixIndex+1 ^ gameRowXOR, led_matrix[cube]); - cube++; - LEDMatrixIndex += 2; - } - LEDMatrixIndex += 8; - } - led.LED_transmit(); - // end set colors - - // try to take Semaphore from IRQ if user pressed USER_BTN to start game - if ( scrollOut || xSemaphoreTake( SemStartGameHandle, ( TickType_t ) 10 ) == pdTRUE ) { - //scroll out "Hi" - scrollOut = true; - scrollCounter++; - if (scrollCounter > 5) { - isRunning = true; - // release Levels Semaphore - xSemaphoreGive( SemLevelsHandle ); - } - } - // end take sem from IRQ - - if (isRunning) { - // check matrix if set a color - // 3,7,11,15 = last elements in each row - activeLED_s activeLEDs; - activeLEDs.leds = 0; - activeLEDs.delay = delay; - if (led_matrix[3] > 0) activeLEDs.leds += 1; - if (led_matrix[7] > 0) activeLEDs.leds += 2; - if (led_matrix[11] > 0) activeLEDs.leds += 4; - if (led_matrix[15] > 0) activeLEDs.leds += 8; - -// uint8_t lenPoints = log10(activeLEDs.leds) + 2; -// char charPoints[lenPoints]; -// sprintf(charPoints,"-%d",activeLEDs.leds); -// HAL_UART_Transmit(&huart3,charPoints,sizeof(charPoints),1000); - if (activeLEDs.leds > 0) xQueueSend(fromLEDMatrixHandle, &activeLEDs, (portTickType) 1); - // end check last row - } - - if (isRunning || scrollOut) { - // shift matrix to next LED in each row after vTaskDelay - for(uint8_t row = 0; row < FIELDS; row+=ROWS) { - for(uint8_t i = row+ROW4; i > row; i--) { - led_matrix[i] = led_matrix[i-1]; - //if (i%1 == 0) - led_matrix[i-1] = OFF; - } - } - // end shifting down - } - - if (isRunning) { - // checking queue for new incoming elements - matrix_s recvQueue; - if (xQueueReceive(toLEDMatrixHandle, &recvQueue, (portTickType) 10 ) == true) - { - // player lost, showing "ToT", reseting values - if (recvQueue.hasLost) { - while(true) { - const uint8_t say_tot[] = { - 1,9,10,11,12,13,14,17, // 8 - 20,21,25,28,35,38,42, // 7 - 43,46,49,50,51,52,53,54,62}; // 9 - led.LED_set_all_off(0); - const uint8_t say_tot_length = sizeof(say_tot) / sizeof(uint8_t); - for(uint8_t i=0; i < 8; i++) led.LED_set_RGB_32(say_tot[i], TURQUOISE); - for(uint8_t i=15; i < say_tot_length; i++) led.LED_set_RGB_32(say_tot[i], RED); - for(uint8_t i=8; i < 8+8; i++) led.LED_set_RGB_32(say_tot[i], YELLOW); - led.LED_transmit(); - delay = 250; - vTaskDelay(delay); - led.LED_set_all_off(0); - led.LED_transmit(); - vTaskDelay(delay); - - //for(uint8_t i = 0; i < FIELDS; i++) led_matrix[i] = 0; // Reset game table - } - //xSemaphoreGive( SemStartGameHandle ); - } - // end "hasLost" - - // set color if received a specific 1-bit - // first in row: 0, 4, 8, 12 - if (recvQueue.nextLED > 0) { - for(uint8_t i=ROW1; i <= ROW4; i++) { - uint8_t checkBit = 1 << i; - if ((recvQueue.nextLED & checkBit) == checkBit) { - // select a random color from color_array - uint32_t newColor = colors[rand() % num_colors]; - led_matrix[i*4] = newColor; - } - } - delay = recvQueue.delay; - } - // end set nextLED - xSemaphoreGive( SemLevelsHandle ); - } - // end queue check - } - // end isRunning - vTaskDelay(delay); - } - /* USER CODE END Task02 */ + /* USER CODE BEGIN LEDMatrix */ + + // init constants & variables + enum ROW { ROW1, ROW2, ROW3, ROW4 }; + const uint8_t ROWS = 4; + const uint8_t FIELDS = 16; // 4 rows and 4 columns = 16 + uint32_t colors[] = { + WHITE + ,BLUE + ,PURPLE + ,RED + ,GREEN + ,ORANGE + ,TURQUOISE + ,YELLOW + ,SPRINGGREEN + ,OCEAN + ,CYAN + ,RASPBERRY + }; + uint32_t led_matrix[] = { + 0,0,0,0, + 0,0,0,0, + 0,0,0,0, + 0,0,0,0 + }; + + uint8_t num_colors = sizeof(colors) / sizeof(uint32_t); + LED led = *get_instance(); + const uint8_t gameRowXOR = 0xf; + uint16_t delay = 400; + bool isRunning = false; + bool scrollOut = false; + uint8_t scrollCounter = 0; + + // init Matrix + const uint8_t say_hi[] = {1,2,3,6,9,10,11,12,14,15}; + const uint8_t say_hi_length = sizeof(say_hi) / sizeof(uint8_t); + for(uint8_t i=0; i < say_hi_length-3; i++) led_matrix[say_hi[i]] = TURQUOISE; + for(uint8_t i=say_hi_length-3; i < say_hi_length; i++) led_matrix[say_hi[i]] = RED; + + /* Infinite loop */ + while(1) { + + // set led matrix to current colors + led.LED_set_all_off(0); + uint8_t LEDMatrixIndex = 0; + for(uint8_t cube = 0; cube < FIELDS;) { + for(uint8_t column = 0; column <= 6; column+=2) { + led.LED_set_RGB_32(LEDMatrixIndex, led_matrix[cube]); + led.LED_set_RGB_32(LEDMatrixIndex ^ gameRowXOR , led_matrix[cube]); + led.LED_set_RGB_32(LEDMatrixIndex+1, led_matrix[cube]); + led.LED_set_RGB_32(LEDMatrixIndex+1 ^ gameRowXOR, led_matrix[cube]); + cube++; + LEDMatrixIndex += 2; + } + LEDMatrixIndex += 8; + } + led.LED_transmit(); + // end set colors + + // try to take Semaphore from IRQ if user pressed USER_BTN to start game + if ( scrollOut || xSemaphoreTake( SemStartGameHandle, ( TickType_t ) 10 ) == pdTRUE ) { + //scroll out "Hi" + scrollOut = true; + scrollCounter++; + if (scrollCounter > 5) { + isRunning = true; + // release Levels Semaphore + xSemaphoreGive( SemLevelsHandle ); + } + } + // end take sem from IRQ + + if (isRunning) { + // check matrix if set a color + // 3,7,11,15 = last elements in each row + activeLED_s activeLEDs; + activeLEDs.leds = 0; + activeLEDs.delay = delay; + if (led_matrix[3] > 0) activeLEDs.leds += 1; + if (led_matrix[7] > 0) activeLEDs.leds += 2; + if (led_matrix[11] > 0) activeLEDs.leds += 4; + if (led_matrix[15] > 0) activeLEDs.leds += 8; + + if (activeLEDs.leds > 0) xQueueSend(fromLEDMatrixHandle, &activeLEDs, (portTickType) 1); + // end check last row + } + + if (isRunning || scrollOut) { + // shift matrix to next LED in each row after vTaskDelay + for(uint8_t row = 0; row < FIELDS; row+=ROWS) { + for(uint8_t i = row+ROW4; i > row; i--) { + led_matrix[i] = led_matrix[i-1]; + //if (i%1 == 0) + led_matrix[i-1] = OFF; + } + } + // end shifting down + } + + if (isRunning) { + // checking queue for new incoming elements + matrix_s recvQueue; + if (xQueueReceive(toLEDMatrixHandle, &recvQueue, (portTickType) 10 ) == true) + { + // player lost, showing "ToT", reseting values + if (recvQueue.hasLost) { + while(true) { + const uint8_t say_tot[] = { + 1,9,10,11,12,13,14,17, // 8 + 20,21,25,28,35,38,42, // 7 + 43,46,49,50,51,52,53,54,62}; // 9 + led.LED_set_all_off(0); + const uint8_t say_tot_length = sizeof(say_tot) / sizeof(uint8_t); + for(uint8_t i=0; i < 8; i++) led.LED_set_RGB_32(say_tot[i], TURQUOISE); + for(uint8_t i=15; i < say_tot_length; i++) led.LED_set_RGB_32(say_tot[i], RED); + for(uint8_t i=8; i < 8+8; i++) led.LED_set_RGB_32(say_tot[i], YELLOW); + led.LED_transmit(); + delay = 250; + vTaskDelay(delay); + led.LED_set_all_off(0); + led.LED_transmit(); + vTaskDelay(delay); + } + } + // end "hasLost" + + // set color if received a specific 1-bit + // first in row: 0, 4, 8, 12 + if (recvQueue.nextLED > 0) { + for(uint8_t i=ROW1; i <= ROW4; i++) { + uint8_t checkBit = 1 << i; + if ((recvQueue.nextLED & checkBit) == checkBit) { + // select a random color from color_array + uint32_t newColor = colors[rand() % num_colors]; + led_matrix[i*4] = newColor; + } + } + delay = recvQueue.delay; + } + // end set nextLED + xSemaphoreGive( SemLevelsHandle ); + } + // end queue check + } + // end isRunning + vTaskDelay(delay); + } + /* USER CODE END LEDMatrix */ } /* USER CODE BEGIN Header_Validate */ diff --git a/F413_FreeRTOS_LED_Matrix_Game.ioc b/F413_FreeRTOS_LED_Matrix_Game.ioc index ae548b6ea9740d50e0701b74a90078b4fe1dde89..c3df331b60eeb3200c9d4941f22b10ae3f59db62 100644 --- a/F413_FreeRTOS_LED_Matrix_Game.ioc +++ b/F413_FreeRTOS_LED_Matrix_Game.ioc @@ -13,8 +13,8 @@ Dma.TIM2_CH1.0.Priority=DMA_PRIORITY_VERY_HIGH Dma.TIM2_CH1.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode FREERTOS.FootprintOK=true FREERTOS.IPParameters=Tasks01,FootprintOK,configUSE_PREEMPTION,configUSE_OS2_TIMER,Queues01 -FREERTOS.Queues01=toLEDMatrix,16,matrix_s,0,Dynamic,NULL,NULL;fromLEDMatrix,16,matrix_s,0,Dynamic,NULL,NULL;toDisplayQueue,16,uint16_t,0,Dynamic,NULL,NULL -FREERTOS.Tasks01=Task1,24,128,Levels,Default,NULL,Dynamic,NULL,NULL;Task2,24,128,Task02,Default,NULL,Dynamic,NULL,NULL;Task3,24,128,Validate,Default,NULL,Dynamic,NULL,NULL;Task4,8,128,Display,Default,NULL,Dynamic,NULL,NULL +FREERTOS.Queues01=toLEDMatrix,16,matrix_s,0,Dynamic,NULL,NULL;fromLEDMatrix,16,activeLED_s,0,Dynamic,NULL,NULL;toDisplayQueue,16,uint16_t,0,Dynamic,NULL,NULL +FREERTOS.Tasks01=Task1,24,128,Levels,Default,NULL,Dynamic,NULL,NULL;Task2,24,128,LEDMatrix,Default,NULL,Dynamic,NULL,NULL;Task3,24,128,Validate,Default,NULL,Dynamic,NULL,NULL;Task4,8,128,Display,Default,NULL,Dynamic,NULL,NULL FREERTOS.configUSE_OS2_TIMER=1 FREERTOS.configUSE_PREEMPTION=1 File.Version=6