Skip to content

Instantly share code, notes, and snippets.

@jancumps
Created May 2, 2016 16:14
Show Gist options
  • Select an option

  • Save jancumps/7e1bab1cccd4dcbed5efd9478c9cb012 to your computer and use it in GitHub Desktop.

Select an option

Save jancumps/7e1bab1cccd4dcbed5efd9478c9cb012 to your computer and use it in GitHub Desktop.
mini menu system for Educational BoosterPack and Hercules LaunchPad
/*
* menu.c
*
* Created on: 1 mei 2016
* Author: jancu
*/
#include "menu.h"
#include "HX8353E.h"
#include <stdbool.h>
typedef struct {
uint8_t *text;
uint32_t len;
// todo: RTOS function to call upon action
} mnuEntry_t;
#define MNUITEMS_SCREEN (5U)
#define MNUTITLE ("Hercules Safety")
#define MNUITEM00 (" Menu Item 0 ")
#define MNUITEM01 (" Menu Item 1 ")
#define MNUITEM02 (" Menu Item 2 ")
#define MNUITEM03 (" Menu Item 3 ")
#define MNUITEM04 (" Menu Item 4 ")
#define MNUITEM05 (" Menu Item 5 ")
#define MNUITEM06 (" Menu Item 6 ")
#define MNUBLANK (" ")
mnuEntry_t mnuList[] = {
{MNUITEM00, sizeof(MNUITEM00) - 1 },
{MNUITEM01, sizeof(MNUITEM01) - 1 },
{MNUITEM02, sizeof(MNUITEM02) - 1 },
{MNUITEM03, sizeof(MNUITEM03) - 1 },
{MNUITEM04, sizeof(MNUITEM04) - 1 },
{MNUITEM05, sizeof(MNUITEM05) - 1 },
{MNUITEM06, sizeof(MNUITEM06) - 1}
};
uint32_t __mnuActiveItem;
uint32_t __mnuTopItem;
void _mnuDrawItem(uint32_t item, uint32_t pos, bool selected);
void mnuInit() {
// initialize LCD
screenInit();
screenBegin();
clear(blackColour);
__mnuActiveItem = 0U;
__mnuTopItem = 0U;
}
void mnuDraw(uint32_t activePosition) {
// clear(blackColour);
setFontSize(0);
uint32_t u = 0U;
uint32_t uOffset= __mnuTopItem;
__mnuActiveItem = activePosition;
// draw the title somewhere in the middle
gText(20, 0, MNUTITLE, sizeof(MNUTITLE) - 1, whiteColour, blackColour, 1, 1);
// calculate the start position. If our next selection is not on the screen, we have to scroll the menu items up or down
// first: is it beyond the last visible:
if (activePosition >= (__mnuTopItem + MNUITEMS_SCREEN)) {
uOffset = activePosition - MNUITEMS_SCREEN + 1U;
}
if (activePosition < __mnuTopItem) {
uOffset = activePosition;
}
__mnuTopItem = uOffset;
for (u = 0;
(u < (MNUITEMS_SCREEN)) && (u < ( sizeof(mnuList) / sizeof(mnuEntry_t)));
u++) {
_mnuDrawItem(u + uOffset, u, ((u + uOffset) == __mnuActiveItem)); // todo: pos will become dependent on current active position
// gText(4, (u + 1) * 15U, mnuList[u].text, mnuList[u].len, yellowColour, blackColour, 1, 1);
}
// overdraw any items that are left over from scrolling
for(u = u; u < MNUITEMS_SCREEN; u++ ) {
gText(4, (u + 1) * 14U, MNUBLANK, sizeof(MNUBLANK) - 1, blackColour, blackColour, 1, 1);
}
}
void mnuUp() {
if (__mnuActiveItem) {
mnuDraw(__mnuActiveItem - 1);
}
}
void mnuDown() {
if (__mnuActiveItem < ( sizeof(mnuList) / sizeof(mnuEntry_t)) - 1) {
mnuDraw(__mnuActiveItem + 1);
}
}
void _mnuDrawItem(uint32_t item, uint32_t pos, bool selected) {
gText(4, (pos + 1) * 14U, mnuList[item].text, mnuList[item].len, selected ? blackColour : yellowColour, selected? whiteColour : blackColour, 1, 1);
}
/*
* menu.h
*
* Created on: 1 mei 2016
* Author: jancu
*/
#ifndef MENU_MENU_H_
#define MENU_MENU_H_
#include <stdint.h>
void mnuInit();
void mnuDraw(uint32_t activePosition);
void mnuUp();
void mnuDown();
#endif /* MENU_MENU_H_ */
/** @file sys_main.c
* @brief Application main file
* @date 02-Mar-2016
* @version 04.05.02
*
* This file contains an empty main function,
* which can be used for the application.
*/
/*
* Copyright (C) 2009-2016 Texas Instruments Incorporated - www.ti.com
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* USER CODE BEGIN (0) */
/* USER CODE END */
/* Include Files */
#include "sys_common.h"
/* USER CODE BEGIN (1) */
/* Include FreeRTOS scheduler files */
#include "FreeRTOS.h"
#include "os_task.h"
#include "os_queue.h"
#include "gio.h"
#include "het.h"
#include "adc.h"
#include <stdint.h>
#include "menu.h"
/* Define Task Handles */
xTaskHandle xTaskBoosterSwitch1Handle;
xTaskHandle xTaskBoosterSwitch2Handle;
QueueHandle_t menuQ = NULL;
adcData_t adc_data[2]; //ADC Data Structure
void vTaskLedBlue(void *pvParameters);
void vTaskLedRed(void *pvParameters);
/* TaskBoosterSwitch1 */
void vTaskBoosterSwitch1(void *pvParameters) {
static uint32_t uLastState = 1U;
for (;;) {
uint32_t uState = gioGetBit(gioPORTA, 2);
if (!(uState | uLastState)) { // two times the same state for debouncing
// reset button states
uLastState = 1U;
// todo: real task
if (xTaskCreate(vTaskLedBlue,"TaskLedBlue", configMINIMAL_STACK_SIZE, NULL, 1, 0) != pdTRUE)
{
/* Task could not be created */
while(1);
}
} else {
uLastState = uState; // two times the same state for debouncing
}
vTaskDelay(75 * portTICK_RATE_MS);
}
}
/* TaskBoosterSwitch2 */
void vTaskBoosterSwitch2(void *pvParameters) {
static uint32_t uLastState = 1U;
for (;;) {
uint32_t uState = gioGetBit(gioPORTA, 1);
if (!(uState | uLastState)) { // two times the same state for debouncing
// reset button states
uLastState = 1U;
// todo: real task
if (xTaskCreate(vTaskLedRed,"TaskLedRed", configMINIMAL_STACK_SIZE, NULL, 1, 0) != pdTRUE)
{
/* Task could not be created */
while(1);
}
} else {
uLastState = uState; // two times the same state for debouncing
}
vTaskDelay(75 * portTICK_RATE_MS);
}
}
/* TaskJoystick */
void vTaskJoystick(void *pvParameters) {
static uint32_t y = 1; // 0 is down, 1 is mid, 2 is up
uint32_t sample;
for (;;) {
adcStartConversion(adcREG1, adcGROUP1);
while (!adcIsConversionComplete(adcREG1, adcGROUP1))
; //Wait for ADC conversion
adcGetData(adcREG1, adcGROUP1, &adc_data[0]);
adcStopConversion(adcREG1, adcGROUP1);
// x
// not used yet, it's adc_data[0].value
// y
sample = adc_data[1].value;
if (sample < 0x555) { // down
if (y == 1) {// button was in middle before
// menu down
y = 0;
xQueueSend(menuQ , ( void * ) &y, 50 * portTICK_PERIOD_MS);
// // todo real task
// if (xTaskCreate(vTaskLedBlue,"TaskLedBlue", configMINIMAL_STACK_SIZE, NULL, 1, 0) != pdTRUE)
// {
// /* Task could not be created */
// while(1);
// }
}
} else if (sample < 0xaaa) { // mid
y = 1;
} else { // up
if (y == 1) {// button was in middle before
// menu up
y = 2;
xQueueSend(menuQ , ( void * ) &y, 50 * portTICK_PERIOD_MS);
// // todo real task
// if (xTaskCreate(vTaskLedRed,"TaskLedRed", configMINIMAL_STACK_SIZE, NULL, 1, 0) != pdTRUE)
// {
// /* Task could not be created */
// while(1);
// }
}
}
vTaskDelay(75 * portTICK_RATE_MS);
}
}
void vTaskMenuListener(void *pvParameters) {
uint32_t cmd;
for(;;) {
if (xQueueReceive(menuQ, ( void * ) &cmd, 100)) {
switch (cmd) {
case 0:
mnuDown();
// // todo real task
// if (xTaskCreate(vTaskLedBlue,"TaskLedBlue", configMINIMAL_STACK_SIZE, NULL, 1, 0) != pdTRUE)
// {
// /* Task could not be created */
// while(1);
// }
break;
case 2:
mnuUp();
// // todo real task
// if (xTaskCreate(vTaskLedRed,"TaskLedRed", configMINIMAL_STACK_SIZE, NULL, 1, 0) != pdTRUE)
// {
// /* Task could not be created */
// while(1);
// }
break;
}
}
}
}
void vTaskLedBlue(void *pvParameters) {
gioToggleBit(hetPORT1, 30);
vTaskDelete( NULL);
}
void vTaskLedRed(void *pvParameters) {
gioToggleBit(hetPORT1, 18);
vTaskDelete( NULL);
}
/* USER CODE END */
/** @fn void main(void)
* @brief Application main function
* @note This function is empty by default.
*
* This function is called after startup.
* The user can use this function to implement the application.
*/
/* USER CODE BEGIN (2) */
/* USER CODE END */
void main(void)
{
/* USER CODE BEGIN (3) */
// initialisation section
gioInit();
hetInit();
adcInit();
mnuInit();
// task definitions
/* Create TaskBoosterSwitch1 */
if (xTaskCreate(vTaskBoosterSwitch1,"TaskBoosterSwitch1", configMINIMAL_STACK_SIZE, NULL, 1, &xTaskBoosterSwitch1Handle) != pdTRUE)
{
/* Task could not be created */
while(1);
}
/* Create TaskBoosterSwitch2 */
if (xTaskCreate(vTaskBoosterSwitch2,"TaskBoosterSwitch2", configMINIMAL_STACK_SIZE, NULL, 1, &xTaskBoosterSwitch2Handle) != pdTRUE)
{
/* Task could not be created */
while(1);
}
/* Create TaskBoosterJoystick */
if (xTaskCreate(vTaskJoystick,"vTaskJoystick", configMINIMAL_STACK_SIZE, NULL, 1, 0) != pdTRUE)
{
/* Task could not be created */
while(1);
}
if (xTaskCreate(vTaskMenuListener, "vTaskMenuListener", configMINIMAL_STACK_SIZE, NULL, 1, 0) != pdTRUE)
{
/* Task could not be created */
while(1);
}
menuQ = xQueueCreate( 10, sizeof(uint32_t) );
// actions before RTOS scheduling starts
mnuDraw(0U);
// RTOS scheduling
/* Start Scheduler */
vTaskStartScheduler();
/* Run forever */
while(1) {
}
/* USER CODE END */
}
/* USER CODE BEGIN (4) */
/* USER CODE END */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment