diff --git a/sys/raspi_gpio/u8g2_menu/Makefile b/sys/raspi_gpio/u8g2_menu/Makefile new file mode 100644 index 00000000..cbd6591e --- /dev/null +++ b/sys/raspi_gpio/u8g2_menu/Makefile @@ -0,0 +1,15 @@ + +CFLAGS = -O -I../hal -I../../../csrc -DU8X8_USE_PINS -ffunction-sections -fdata-sections +LDFLAGS = -Wl,--gc-sections + +SRC = $(wildcard *.c) $(wildcard ../hal/*.c) $(wildcard ../../../csrc/*.c) + +OBJ = $(SRC:.c=.o) + + +main: $(OBJ) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) -o main + +clean: + -rm $(OBJ) main + diff --git a/sys/raspi_gpio/u8g2_menu/main.c b/sys/raspi_gpio/u8g2_menu/main.c new file mode 100644 index 00000000..f0a1d0a2 --- /dev/null +++ b/sys/raspi_gpio/u8g2_menu/main.c @@ -0,0 +1,267 @@ +/* + + main.c + + raspberry pi zero GPIO read test + + For speedup run this example as root, either wis + sudo ./main + or by setting the superuser bit: + sudo chown root:root ./main + sudo chmod u+s ./main + +*/ + +#include +#include +#include +#include "bcm2835.h" +#include "raspi_gpio_hal.h" +#include "u8g2.h" + + +u8g2_t u8g2; // a structure which will contain all the data for one display + + +void sigtermhandler(int x) +{ + puts("SIGTERM"); + bcm2835_close(); + exit(0); +} + +void siginthandler(int x) +{ + puts("SIGINT"); + bcm2835_close(); + exit(0); +} + + +#define BUTTON_STATE_NOT_PRESSED 0 +#define BUTTON_STATE_HIGH_DETECT 1 +#define BUTTON_STATE_HIGH_WAIT 2 +#define BUTTON_STATE_LOW_DELAY 3 + + +struct button_struct +{ + int state; + int delay; + uint8_t pin; +}; +typedef struct button_struct button_t; +#define BUTTON_DELAY_HIGH 2 +#define BUTTON_DELAY_LOW 2 + +#define BUTTON_CNT 2 +button_t button_list[BUTTON_CNT]; + +int button_init(void) +{ + int i; + for( i = 0; i < BUTTON_CNT; i++ ) + { + bcm2835_gpio_fsel(button_list[i].pin, BCM2835_GPIO_FSEL_INPT); + } +} + +int button_get_event(void) +{ + int button_value = -1; + int i; + for( i = 0; i < BUTTON_CNT; i++ ) + { + switch(button_list[i].state) + { + case BUTTON_STATE_NOT_PRESSED: + button_list[i].delay = 0; + if ( bcm2835_gpio_lev(button_list[i].pin) != 0 ) + button_list[i].state = BUTTON_STATE_HIGH_DETECT; + break; + case BUTTON_STATE_HIGH_DETECT: + if ( bcm2835_gpio_lev(button_list[i].pin) == 0 ) + { + button_list[i].delay = 0; + button_list[i].state = BUTTON_STATE_LOW_DELAY; + } + button_list[i].delay++; + if ( button_list[i].delay >= BUTTON_DELAY_HIGH ) + { + button_value = i; + button_list[i].state = BUTTON_STATE_HIGH_WAIT; + } + break; + case BUTTON_STATE_HIGH_WAIT: + if ( bcm2835_gpio_lev(button_list[i].pin) == 0 ) + { + button_list[i].delay = 0; + button_list[i].state = BUTTON_STATE_LOW_DELAY; + } + break; + case BUTTON_STATE_LOW_DELAY: + button_list[i].delay++; + if ( button_list[i].delay >= BUTTON_DELAY_LOW ) + button_list[i].state = BUTTON_STATE_NOT_PRESSED; + break; + } + } + return button_value; +} + + +/* + title: NULL for no title, valid str for title line. Can contain mutliple lines, separated by '\n' + start_pos: default position for the cursor, first line is 1. + sl: string list (list of strings separated by \n) + returns 0 if user has pressed the home key + returns the selected line if user has pressed the select key + side effects: + u8g2_SetFontDirection(u8g2, 0); + u8g2_SetFontPosBaseline(u8g2); + +*/ + +#define BUTTON_SELECT 0 +#define BUTTON_NEXT 1 + +extern void u8g2_DrawSelectionList(u8g2_t *u8g2, u8sl_t *u8sl, u8g2_uint_t y, const char *s); + +#define MY_BORDER_SIZE 1 +#define MY_RULE_SIZE 2 + +uint8_t u8g2_RaspiUserInterfaceSelectionList(u8g2_t *u8g2, const char *title, uint8_t start_pos, const char *sl) +{ + u8sl_t u8sl; + u8g2_uint_t yy; + + uint8_t event; + + u8g2_uint_t line_height = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2)+MY_BORDER_SIZE; + + uint8_t title_lines = u8x8_GetStringLineCnt(title); + uint8_t display_lines; + + + if ( start_pos > 0 ) /* issue 112 */ + start_pos--; /* issue 112 */ + + + if ( title_lines > 0 ) + { + display_lines = (u8g2_GetDisplayHeight(u8g2)-2-MY_RULE_SIZE) / line_height; + u8sl.visible = display_lines; + u8sl.visible -= title_lines; + } + else + { + display_lines = u8g2_GetDisplayHeight(u8g2) / line_height; + u8sl.visible = display_lines; + } + + u8sl.total = u8x8_GetStringLineCnt(sl); + u8sl.first_pos = 0; + u8sl.current_pos = start_pos; + + if ( u8sl.current_pos >= u8sl.total ) + u8sl.current_pos = u8sl.total-1; + if ( u8sl.first_pos+u8sl.visible <= u8sl.current_pos ) + u8sl.first_pos = u8sl.current_pos-u8sl.visible+1; + + u8g2_SetFontPosBaseline(u8g2); + + for(;;) + { + u8g2_FirstPage(u8g2); + do + { + yy = u8g2_GetAscent(u8g2); + if ( title_lines > 0 ) + { + yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title); + + //u8g2_DrawHLine(u8g2, 0, yy-line_height- u8g2_GetDescent(u8g2) + 1, u8g2_GetDisplayWidth(u8g2)); + u8g2_DrawBox(u8g2, 0, yy-line_height- u8g2_GetDescent(u8g2) + 1, u8g2_GetDisplayWidth(u8g2), MY_RULE_SIZE); + + + yy += 2+MY_RULE_SIZE; + } + u8g2_DrawSelectionList(u8g2, &u8sl, yy, sl); + } while( u8g2_NextPage(u8g2) ); + +#ifdef U8G2_REF_MAN_PIC + return 0; +#endif + + + for(;;) + { + event = button_get_event(); + if ( event == BUTTON_SELECT ) + return u8sl.current_pos+1; /* +1, issue 112 */ + else if ( event == BUTTON_NEXT ) + { + u8sl_Next(&u8sl); + break; + } + /* + else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_UP ) + { + u8sl_Prev(&u8sl); + break; + } + */ + } + } +} + + +int main(void) +{ + int i = 0; + int b = -1; + int pins[4] = { 12, 13, 16, 17 }; + + if (!bcm2835_init()) + exit(1); + + signal(SIGTERM, sigtermhandler); + signal(SIGINT, siginthandler); + + atexit((void (*) (void))bcm2835_close); + + button_list[0].pin = 12; + button_list[1].pin = 16; + + button_init(); + + + u8g2_Setup_sh1107_i2c_seeed_128x128_f(&u8g2, U8G2_R3, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_raspi_gpio_hal); // init u8g2 structure + u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_I2C_CLOCK, 5); + u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_I2C_DATA, 6); + u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this, + u8g2_SetPowerSave(&u8g2, 0); // wake up display + u8g2_ClearBuffer(&u8g2); + u8g2_SendBuffer(&u8g2); + + u8g2_SetFont(&u8g2, u8g2_font_lastapprenticebold_tr); + //u8g2_SetFont(&u8g2, u8g2_font_helvB12_tr); + + //u8g2_DrawStr(&u8g2, 0, 50, "Hello"); + //u8g2_DrawStr(&u8g2, 0, 100, "World!"); + //u8g2_SendBuffer(&u8g2); + + u8g2_RaspiUserInterfaceSelectionList(&u8g2, "Menu", 1, "apple\nbanana\nraspberry\nMango"); + + for( ;; ) + { + b = button_get_event(); + if ( b >= 0 ) + printf("Button %d\n", b); + } + + + //delaynanoseconds(500000000UL); + +} +