config before timer setup; using mutex and notifs

master
Dmitry Maylarov 7 years ago
parent 2c18224621
commit 7fdf8de718

@ -12,21 +12,7 @@
"configFiles": [ "configFiles": [
"target/stlink.cfg", "target/stlink.cfg",
"target/stm32f1x.cfg" "target/stm32f1x.cfg"
], ]
"swoConfig": {
"source": "probe",
"enabled": true,
"swoFrequency": 4000000,
"cpuFrequency": 48000000,
"decoders": [
{
"port": 0,
"label": "Output",
"type": "console",
"encoding":"ascii"
}
]
}
} }
] ]
} }

@ -9,7 +9,8 @@
"task.h": "c", "task.h": "c",
"music.h": "c", "music.h": "c",
"usb_device.h": "c", "usb_device.h": "c",
"main.h": "c" "main.h": "c",
"game.h": "c"
} }
} }
} }

@ -82,7 +82,7 @@
#define configUSE_16_BIT_TICKS 0 #define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1 #define configIDLE_SHOULD_YIELD 1
#define configUSE_TASK_NOTIFICATIONS 1 #define configUSE_TASK_NOTIFICATIONS 1
#define configUSE_MUTEXES 0 #define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 0 #define configUSE_RECURSIVE_MUTEXES 0
#define configUSE_COUNTING_SEMAPHORES 0 #define configUSE_COUNTING_SEMAPHORES 0
@ -110,6 +110,7 @@ to exclude the API function. */
#define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskNotifyGive 1
#define INCLUDE_xResumeFromISR 1 #define INCLUDE_xResumeFromISR 1
#define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1 #define INCLUDE_vTaskDelay 1

@ -7,11 +7,10 @@ void InitGameEngine() {
game.countScores = true; game.countScores = true;
game.activePlayers = 0; game.activePlayers = 0;
game.currentPlayer = 1; game.currentPlayer = 1;
game.turnTime = TIMER_MAX / 2; game.turnTime = TIMER_STEP;
game.timerValue = game.turnTime; game.timerValue = game.turnTime;
for (int i=0; i<MAX_PLAYERS+1; i++) for (int i=0; i<MAX_PLAYERS+1; i++)
game.scores[i] = 999; game.scores[i] = 999;
game.scores[1] = 0;
} }
void DecrementTurnTime() { void DecrementTurnTime() {
@ -31,14 +30,14 @@ void IncrementTurnTime() {
} }
void AddPlayer() { void AddPlayer() {
if (game.activePlayers <= MAX_PLAYERS) { if (game.activePlayers < MAX_PLAYERS) {
game.scores[++game.activePlayers] = 0; game.scores[(1+game.activePlayers++)] = 0;
} }
} }
void RemovePlayer() { void RemovePlayer() {
if (game.activePlayers > 1) { if (game.activePlayers > 1) {
game.scores[--game.activePlayers] = -1; game.scores[1+(--game.activePlayers)] = 999;
} }
} }
@ -51,6 +50,8 @@ void ResetTurnTimer() {
} }
void NextPlayer() { void NextPlayer() {
game.currentPlayer = ((game.currentPlayer) % (game.activePlayers+1) + 1 ); game.currentPlayer--;
game.currentPlayer = ((game.currentPlayer + 1) % game.activePlayers);
game.currentPlayer++;
ResetTurnTimer(); ResetTurnTimer();
} }

@ -81,8 +81,10 @@ HAL_StatusTypeDef LCD_SendInternal(LCD_HandleTypeDef *lcd, uint8_t data, uint8_t
data_arr[2] = lo|flags|LCD_BACKLIGHT|LCD_PIN_EN; data_arr[2] = lo|flags|LCD_BACKLIGHT|LCD_PIN_EN;
data_arr[3] = lo|flags|LCD_BACKLIGHT; data_arr[3] = lo|flags|LCD_BACKLIGHT;
taskENTER_CRITICAL();
res = HAL_I2C_Master_Transmit(lcd->I2C_Handle, lcd->address, data_arr, res = HAL_I2C_Master_Transmit(lcd->I2C_Handle, lcd->address, data_arr,
sizeof(data_arr), HAL_MAX_DELAY); sizeof(data_arr), HAL_MAX_DELAY);
taskEXIT_CRITICAL();
vTaskDelay(LCD_DELAY_MS); vTaskDelay(LCD_DELAY_MS);
return res; return res;
} }

@ -100,6 +100,7 @@ TimerHandle_t xSecondsTimerHandle = NULL;
TaskHandle_t xMusicHandle = NULL; TaskHandle_t xMusicHandle = NULL;
TaskHandle_t xLCDUpdaterHandle = NULL; TaskHandle_t xLCDUpdaterHandle = NULL;
xSemaphoreHandle xButtonPressed; xSemaphoreHandle xButtonPressed;
xSemaphoreHandle xLCD;
asm( asm(
"tetris:\n\t" "tetris:\n\t"
@ -130,14 +131,18 @@ static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */ /* USER CODE BEGIN PFP */
void PrintTime() { void PrintTime() {
LCD_MoveCursor(&hlcd, 0, 0); if( xSemaphoreTake( xLCD, portMAX_DELAY ) == pdTRUE )
sprintf( {
lcdBuffer, sprintf(
(game.timerValue > 0 ? " %1d:%02d " : " -%d:%02d "), lcdBuffer,
abs(game.timerValue / 60), (game.timerValue > 0 ? " %1d:%02d " : " -%d:%02d "),
abs(game.timerValue % 60) abs(game.timerValue / 60),
); abs(game.timerValue % 60)
LCD_SendString(&hlcd, lcdBuffer); );
LCD_MoveCursor(&hlcd, 0, 0);
LCD_SendString(&hlcd, lcdBuffer);
xSemaphoreGive( xLCD );
}
} }
/* USER CODE END PFP */ /* USER CODE END PFP */
@ -182,6 +187,9 @@ int main(void)
/* USER CODE BEGIN 2 */ /* USER CODE BEGIN 2 */
InitGameEngine(); InitGameEngine();
xLCD = xSemaphoreCreateMutex();
xButtonPressed = xSemaphoreCreateBinary();
xTaskCreate(vTaskPlayerSetup, "Player", configMINIMAL_STACK_SIZE, NULL, 1, NULL); xTaskCreate(vTaskPlayerSetup, "Player", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
xTaskCreate(vTaskButtonPoll, "Buttons", configMINIMAL_STACK_SIZE, NULL, 1, NULL); xTaskCreate(vTaskButtonPoll, "Buttons", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
vTaskStartScheduler(); vTaskStartScheduler();
@ -494,24 +502,49 @@ void vTaskPlayerSetup(void *parameter)
} }
} }
} }
xTaskCreate(vTaskTimerSetup, "TaskTimerSetup", configMINIMAL_STACK_SIZE, NULL, 1, NULL); xTaskCreate(vTaskConfig, "Config", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
vTaskDelete(NULL); vTaskDelete(NULL);
} }
void vTaskTimerSetup(void *parameter) { void vTaskConfig(void *parameter) {
if (xLCDUpdaterHandle != NULL)
{
vTaskDelete(xLCDUpdaterHandle);
xLCDUpdaterHandle = NULL;
}
LCD_MoveHome(&hlcd); LCD_MoveHome(&hlcd);
LCD_SendString(&hlcd, "Settings"); LCD_SendString(&hlcd, "Settings");
while (1) while (1)
{ {
LCD_MoveCursor(&hlcd, 1, 0); LCD_MoveCursor(&hlcd, 1, 0);
sprintf(lcdBuffer, "Turn time: %1ld:%02ld ",game.turnTime / 60, game.turnTime % 60); sprintf(lcdBuffer, "Count scores: %3s ", game.countScores ? "yes" : "no");
LCD_SendString(&hlcd, lcdBuffer); LCD_SendString(&hlcd, lcdBuffer);
vTaskDelay(1); vTaskDelay(1);
if (xSemaphoreTake(xButtonPressed, portMAX_DELAY) == pdPASS ) {
if (plusButton->pressed)
game.countScores = !game.countScores;
if (minusButton->pressed)
// show round number or change the way it counts
game.countScores = !game.countScores;
if (bigButton->pressed) {
break;
}
vTaskDelay(10);
}
}
xTaskCreate(vTaskTimerSetup, "TaskTimerSetup", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
xTaskCreate(vTaskTurnTimeUpdate, "TimeUpdate", configMINIMAL_STACK_SIZE, NULL, 1, &xLCDUpdaterHandle);
vTaskDelete(NULL);
}
void vTaskTimerSetup(void *parameter) {
if( xSemaphoreTake( xLCD, portMAX_DELAY ) == pdTRUE )
{
LCD_MoveHome(&hlcd);
LCD_MoveCursor(&hlcd, 1, 0);
sprintf(lcdBuffer, "Setup turn time");
LCD_SendString(&hlcd, lcdBuffer);
xSemaphoreGive( xLCD );
}
while (1)
{
xTaskNotifyGive(xLCDUpdaterHandle);
vTaskDelay(1);
if (xSemaphoreTake(xButtonPressed, portMAX_DELAY) == pdPASS ) if (xSemaphoreTake(xButtonPressed, portMAX_DELAY) == pdPASS )
{ {
if (plusButton->pressed) if (plusButton->pressed)
@ -535,104 +568,70 @@ void vTaskTimerSetup(void *parameter) {
pdTRUE, //auto-reload pdTRUE, //auto-reload
NULL, //not assigning ID NULL, //not assigning ID
vTimerCallback // function to call after timer expires vTimerCallback // function to call after timer expires
); );
xTaskCreate(vTaskConfig, "Config", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
vTaskDelete(NULL);
}
void vTaskConfig(void *parameter) {
if (xLCDUpdaterHandle != NULL)
{
vTaskDelete(xLCDUpdaterHandle);
xLCDUpdaterHandle = NULL;
}
LCD_MoveHome(&hlcd);
LCD_SendString(&hlcd, "Settings");
while (1)
{
LCD_MoveCursor(&hlcd, 1, 0);
sprintf(lcdBuffer, "Count scores: %3s ", game.countScores ? "yes" : "no");
LCD_SendString(&hlcd, lcdBuffer);
vTaskDelay(1);
if (xSemaphoreTake(xButtonPressed, portMAX_DELAY) == pdPASS ) {
if (plusButton->pressed)
game.countScores = !game.countScores;
if (minusButton->pressed)
// show round number or change the way it counts
game.countScores = !game.countScores;
if (bigButton->pressed) {
break;
}
vTaskDelay(10);
}
}
xTaskCreate(vTaskTurn, "TaskTurn", configMINIMAL_STACK_SIZE, NULL, 1, NULL); xTaskCreate(vTaskTurn, "TaskTurn", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
vTaskDelete(NULL); vTaskDelete(NULL);
} }
void vTaskTurnTimeUpdate(void *parameter) { void vTaskTurnTimeUpdate(void *parameter) {
TickType_t xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
while (1) while (1)
{ {
ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
PrintTime(); PrintTime();
vTaskDelayUntil(&xLastWakeTime,1000);
} }
} }
void vTaskTurn(void *parameter) { void vTaskTurn(void *parameter) {
if (xLCDUpdaterHandle == NULL)
{
xTaskCreate(vTaskTurnTimeUpdate, "TimeUpdate", configMINIMAL_STACK_SIZE, NULL, 1, &xLCDUpdaterHandle);
vTaskDelay(100);
}
TickType_t xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
xTimerReset(xSecondsTimerHandle, 0); xTimerReset(xSecondsTimerHandle, 0);
LCD_MoveHome(&hlcd); xTaskNotifyGive(xLCDUpdaterHandle);
vTaskDelay(5);
if (game.countScores) if (game.countScores)
{ {
LCD_MoveCursor(&hlcd, 2, 1); if( xSemaphoreTake( xLCD, portMAX_DELAY ) == pdTRUE )
for (int i = 1; i <= game.activePlayers; i++)
{ {
char tmp[8]; LCD_MoveCursor(&hlcd, 2, 0);
sprintf(tmp, "%1d:%3ld|", i, game.scores[i]); memset(&lcdBuffer,'\0', sizeof(lcdBuffer));
strcat(lcdBuffer, tmp); lcdBuffer[0] = ' ';
if (strlen(lcdBuffer) > (LCD_COLS-6)) for (int i = 1; i <= game.activePlayers; i++)
{ {
LCD_SendString(&hlcd, lcdBuffer); char tmp[8];
LCD_MoveCursor(&hlcd, 3, 1); sprintf(tmp, "%1d:%3ld|", i, game.scores[i]);
strcat(lcdBuffer, tmp);
if (strlen(lcdBuffer) > (LCD_COLS-6))
{
LCD_SendString(&hlcd, lcdBuffer);
LCD_MoveCursor(&hlcd, 3, 0);
memset(&lcdBuffer,'\0', sizeof(lcdBuffer));
lcdBuffer[0] = ' ';
}
} }
LCD_SendString(&hlcd, lcdBuffer);
xSemaphoreGive( xLCD );
} }
}
if( xSemaphoreTake( xLCD, portMAX_DELAY ) == pdTRUE )
{
sprintf(lcdBuffer, "Player: %1d Score: %3ld",game.currentPlayer, game.scores[game.currentPlayer]);
LCD_MoveCursor(&hlcd, 1, 0);
LCD_SendString(&hlcd, lcdBuffer); LCD_SendString(&hlcd, lcdBuffer);
xSemaphoreGive( xLCD );
} }
LCD_MoveCursor(&hlcd, 1, 0);
sprintf(lcdBuffer, "Player: %1d Score: %3ld",game.currentPlayer, game.scores[game.currentPlayer]);
LCD_SendString(&hlcd, lcdBuffer);
while (1) while (1)
{ {
if (xSemaphoreTake(xButtonPressed, portMAX_DELAY) == pdPASS ) if (xSemaphoreTake(xButtonPressed, portMAX_DELAY) == pdPASS )
{ {
if (plusButton->pressed) { if (plusButton->pressed || minusButton->pressed) {
xTaskCreate(vTaskTimerSetup, "TaskTimerSetup", configMINIMAL_STACK_SIZE, NULL, 1, NULL); xTaskCreate(vTaskTimerSetup, "TaskTimerSetup", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
break; break;
} }
else if (minusButton->pressed) {
xTaskCreate(vTaskConfig, "Config", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
break;
}
else if (bigButton->pressed) { else if (bigButton->pressed) {
xTaskCreate(vTaskTurnEnd, "TaskTurnEnd", configMINIMAL_STACK_SIZE, NULL, 1, NULL); xTaskCreate(vTaskTurnEnd, "TaskTurnEnd", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
break; break;
} }
} }
vTaskDelayUntil(&xLastWakeTime,100);
// HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); // HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
} }
xTimerStop(xSecondsTimerHandle, 0); xTimerStop(xSecondsTimerHandle, 0);
@ -646,22 +645,25 @@ void vTaskTurn(void *parameter) {
} }
void vTaskTurnEnd(void *parameter) { void vTaskTurnEnd(void *parameter) {
if (xLCDUpdaterHandle != NULL)
{
vTaskDelete(xLCDUpdaterHandle);
xLCDUpdaterHandle = NULL;
}
if (game.countScores) { if (game.countScores) {
int32_t delta = 0; if( xSemaphoreTake( xLCD, portMAX_DELAY ) == pdTRUE )
LCD_MoveHome(&hlcd); {
PrintTime(); LCD_MoveHome(&hlcd);
LCD_MoveCursor(&hlcd, 1, 0); LCD_MoveCursor(&hlcd, 1, 0);
sprintf(lcdBuffer, "Player: %1d Score: %3ld",game.currentPlayer, game.scores[game.currentPlayer]); sprintf(lcdBuffer, "Player: %1d Score: %3ld",game.currentPlayer, game.scores[game.currentPlayer]);
LCD_SendString(&hlcd, lcdBuffer);
while (1) {
LCD_MoveCursor(&hlcd, 2, 0);
sprintf(lcdBuffer, "Result: %+4ld", delta);
LCD_SendString(&hlcd, lcdBuffer); LCD_SendString(&hlcd, lcdBuffer);
xSemaphoreGive( xLCD );
}
xTaskNotifyGive(xLCDUpdaterHandle);
int32_t delta = 0;
while (1) {
if( xSemaphoreTake( xLCD, portMAX_DELAY ) == pdTRUE )
{
sprintf(lcdBuffer, "Result: %+4ld", delta);
LCD_MoveCursor(&hlcd, 2, 0);
LCD_SendString(&hlcd, lcdBuffer);
xSemaphoreGive( xLCD );
}
if (xSemaphoreTake(xButtonPressed, portMAX_DELAY) == pdPASS ) { if (xSemaphoreTake(xButtonPressed, portMAX_DELAY) == pdPASS ) {
if (bigButton->pressed) { if (bigButton->pressed) {
ChangeScore(delta); ChangeScore(delta);
@ -677,11 +679,9 @@ void vTaskTurnEnd(void *parameter) {
minusButton->pressed = false; minusButton->pressed = false;
delta--; delta--;
} }
vTaskDelay(10);
} }
} }
} }
ResetTurnTimer();
NextPlayer(); NextPlayer();
xTaskCreate(vTaskTurn, "TaskTurn", configMINIMAL_STACK_SIZE, NULL, 1, NULL); xTaskCreate(vTaskTurn, "TaskTurn", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
vTaskDelete(NULL); vTaskDelete(NULL);
@ -705,6 +705,7 @@ void vTaskOvertime(void *parameter) {
void vTimerCallback(TimerHandle_t xTimer) { void vTimerCallback(TimerHandle_t xTimer) {
game.timerValue--; game.timerValue--;
xTaskNotifyGive(xLCDUpdaterHandle);
if(game.timerValue == 0 && xMusicHandle == NULL) if(game.timerValue == 0 && xMusicHandle == NULL)
{ {
xTaskCreate(vTaskOvertime, "vTaskOvertime", configMINIMAL_STACK_SIZE, NULL, 1, &xMusicHandle); xTaskCreate(vTaskOvertime, "vTaskOvertime", configMINIMAL_STACK_SIZE, NULL, 1, &xMusicHandle);
@ -712,7 +713,6 @@ void vTimerCallback(TimerHandle_t xTimer) {
} }
void vTaskButtonPoll(void *parameter) { void vTaskButtonPoll(void *parameter) {
xButtonPressed = xSemaphoreCreateBinary();
bool state = false; bool state = false;
while (1) { while (1) {
for(int i = 0; i<BUTTON_COUNT; i++) for(int i = 0; i<BUTTON_COUNT; i++)

Loading…
Cancel
Save