diff --git a/common/app/app.c b/common/app/app.c index f333d78..cb7bcf9 100644 --- a/common/app/app.c +++ b/common/app/app.c @@ -2,291 +2,23 @@ #include "tft.h" #include "system.h" #include "touch.h" -#include "button.h" -#include "checkbox.h" -#include "pixy.h" -#include -#include +#include "screen_main.h" -bool pixy_connected = false; - -/*TOUCH_AREA_STRUCT a1; - -void touchCB(void* touchArea, TOUCH_ACTION triggeredAction) { - - switch(triggeredAction) { - case PEN_DOWN: - printf("action PEN_DOWN\n"); - break; - - case PEN_UP: - printf("action PEN_UP\n"); - break; - case PEN_MOVE: - printf("action PEN_MOVE\n"); - break; - case PEN_ENTER: - printf("action PEN_ENTER\n"); - break; - case PEN_LEAVE: - printf("action PEN_LEAVE\n"); - break; - default: - printf("action %s\n",triggeredAction); - break; - } -}*/ - -BUTTON_STRUCT b1; - -void buttonCB(void* button) { - printf("button pressed\n"); -} - -CHECKBOX_STRUCT c1; - -void checkboxCB(void *checkbox, bool checked) { - printf("Checkbox %s\n",(checked?"checked":"unchecked")); -} - void app_init() { system_init(); tft_init(); touch_init(); - pixy_connected = (pixy_init()==0); //try to connect to pixy - - //only testwise - tft_clear(WHITE); - tft_draw_pixel(10,210,BLUE); - tft_draw_pixel(12,210,BLUE); - tft_draw_rectangle(40,210,60,235,BLUE); - tft_fill_rectangle(100,215,200,225,GREEN); - tft_draw_line(10,215,310,225,RGB(0xFF,0,0xFF)); - tft_draw_circle(10,10,100, RED); - - /*a1.hookedActions = PEN_DOWN | PEN_UP | PEN_MOVE | PEN_ENTER | PEN_LEAVE; - a1.x1 = 30; - a1.y1 = 30; - a1.x2 = 100; - a1.y2 = 60; - a1.callback = touchCB; - touch_register_area(&a1); - - tft_draw_rectangle(30,30,100,60,BLUE); - tft_print_line(30, 30, RED, BLUE, 0, "Hallo");*/ - - //button test - b1.base.x1=25; //Start X of Button - b1.base.y1=45; //Start Y of Button - b1.base.x2=AUTO; //b1.base.x1+160; //Auto Calculate X2 with String Width - b1.base.y2=AUTO; //Auto Calculate Y2 with String Height - b1.txtcolor=WHITE; //Set foreground color - b1.bgcolor=HEX(0xDE1010); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible) - b1.font=0; //Select Font - b1.text="Hallo"; //Set Text (For formatted strings take sprintf) - b1.callback=buttonCB; //Call b1_cb as Callback - gui_button_add(&b1); //Register Button (and run the callback from now on) - - //Checkbox test - c1.base.x1=220; - c1.base.y1=45; - c1.base.x2=c1.base.x1+16; - c1.base.y2=c1.base.y1+16; - c1.fgcolor = GREEN; - c1.checked = true; - c1.callback = checkboxCB; - gui_checkbox_add(&c1); - + gui_screen_navigate(get_screen_main()); } - - -int pixy_led_test(); -int pixy_frame_test(); - //app event loop void app_process() { system_process(); //Let the system handle it's pending events - //gui_button_redraw(&b1); - ///gui_checkbox_redraw(&c1); - - //Note: The only way to detect that pixy has been disconnected is if a command fails. There's no pixy_is_connected method yet :'( - - if(!pixy_connected) { //Pixy not connected - pixy_close(); //Ensure that all pixy resources are freed (failsafe) - if(pixy_init()==0) { //try to connect to pixy - pixy_connected=true; - } - } - - if(pixy_connected) { - pixy_service(); //Send/receive event data from/to pixy failed - - //Code for tests see below - if(pixy_led_test()!=0) { - pixy_connected=false; - } - - /*if(pixy_frame_test()!=0) { - pixy_connected=false; - }*/ - system_delay(500); - } + gui_screen_update(); //update the currently active screen } -//----------------------------------------------------------------------------------------------------------------- - -int colorind; -const uint32_t colors [] = {0xFF0000, 0x00FF00,0x0000FF,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF,0x000000}; -const int num_colors = sizeof(colors)/sizeof(uint32_t); - -int pixy_led_test() { - if(colorind==0) { - pixy_led_set_max_current(5); - } - - int32_t response; - int return_value; - return_value = pixy_command("led_set", INT32(colors[colorind++]), END_OUT_ARGS, &response, END_IN_ARGS); - colorind%=num_colors; - - if(return_value!=0) { - colorind=0; //reset color ind, to start at zero when plugging pixy in again - } - - return return_value; -} - -//---------------------------------------------------------------------------------------------------------------------------- - -int renderBA81(uint8_t renderFlags, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame); - - -int pixy_frame_test() { - - uint8_t* videodata; - int32_t response; - int32_t fourccc; - int8_t renderflags; - uint16_t xwidth; - uint16_t ywidth; - uint32_t size; - - - int return_value = pixy_command("cam_getFrame", // String id for remote procedure - INT8(0x21), // mode - INT16(0), // xoffset - INT16(0), // yoffset - INT16(320), // width - INT16(200), // height - END_OUT_ARGS, // separator - &response, // pointer to mem address for return value - &fourccc, - &renderflags, - &xwidth, - &ywidth, - &size, - &videodata, // pointer to mem address for returned frame - END_IN_ARGS); - - if(return_value==0) { - return_value = renderBA81(renderflags,xwidth,ywidth,size,videodata); - } - - return return_value; -} - - - -void interpolateBayer(uint16_t width, uint16_t x, uint16_t y, uint8_t *pixel, uint8_t* r, uint8_t* g, uint8_t* b) -{ - if (y&1) - { - if (x&1) - { - *r = *pixel; - *g = (*(pixel-1)+*(pixel+1)+*(pixel+width)+*(pixel-width))>>2; - *b = (*(pixel-width-1)+*(pixel-width+1)+*(pixel+width-1)+*(pixel+width+1))>>2; - } - else - { - *r = (*(pixel-1)+*(pixel+1))>>1; - *g = *pixel; - *b = (*(pixel-width)+*(pixel+width))>>1; - } - } - else - { - if (x&1) - { - *r = (*(pixel-width)+*(pixel+width))>>1; - *g = *pixel; - *b = (*(pixel-1)+*(pixel+1))>>1; - } - else - { - *r = (*(pixel-width-1)+*(pixel-width+1)+*(pixel+width-1)+*(pixel+width+1))>>2; - *g = (*(pixel-1)+*(pixel+1)+*(pixel+width)+*(pixel-width))>>2; - *b = *pixel; - } - } - -} - - - -int renderBA81(uint8_t renderFlags, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame) -{ - uint16_t x, y; - uint8_t r, g, b; - - - // skip first line - frame += width; - - // don't render top and bottom rows, and left and rightmost columns because of color - // interpolation - //uint32_t decodedimage[(width-2)*(height-2)]; - uint16_t* decodedimage = malloc(sizeof(uint16_t)*(width-2)*(height-2)); - - if(decodedimage==NULL) { //not enough free space to decode image in memory - //decode & render image pixel by pixel - uint16_t* line = decodedimage; - for (y=1; y +#include "system.h" + +static bool pixy_connected = false; + + +static BUTTON_STRUCT b_back; + +static void b_back_cb(void* button) { + gui_screen_back(); +} + + +static void enter(void* screen) { + tft_clear(WHITE); + + //Back button + b_back.base.x1=10; //Start X of Button + b_back.base.y1=210; //Start Y of Button + b_back.base.x2=AUTO; //b_back.base.x1+160; //Auto Calculate X2 with String Width + b_back.base.y2=AUTO; //Auto Calculate Y2 with String Height + b_back.txtcolor=WHITE; //Set foreground color + b_back.bgcolor=HEX(0xAE1010); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible) + b_back.font=0; //Select Font + b_back.text="Back"; //Set Text (For formatted strings take sprintf) + b_back.callback=b_back_cb; //Call b_back_cb as Callback + gui_button_add(&b_back); //Register Button (and run the callback from now on) + + + //Pixy stuff + pixy_connected = (pixy_init()==0); //try to connect to pixy + +} + +static void leave(void* screen) { + gui_button_remove(&b_back); +} + +int pixy_led_test(); +int pixy_frame_test(); + +static void update(void* screen) { + + //Note: The only way to detect that pixy has been disconnected is if a command fails. There's no pixy_is_connected method yet :'( + + if(!pixy_connected) { //Pixy not connected + pixy_close(); //Ensure that all pixy resources are freed (failsafe) + if(pixy_init()==0) { //try to connect to pixy + pixy_connected=true; + printf("pixy reinitialized\n"); + } + } + + if(pixy_connected) { + pixy_service(); //Send/receive event data from/to pixy failed + + //Code for tests see below + if(pixy_led_test()!=0) { + pixy_connected=false; + } + + if(pixy_frame_test()!=0) { + pixy_connected=false; + } + //system_delay(500); + } +} + + +static SCREEN_STRUCT screen = { + enter, + leave, + update +}; + + +SCREEN_STRUCT* get_screen_pixytest() { + return &screen; +} + + + +//----------------------------------------------------------------------------------------------------------------- + +int colorind; +const uint32_t colors [] = {0xFF0000, 0x00FF00,0x0000FF,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF,0x000000}; +const int num_colors = sizeof(colors)/sizeof(uint32_t); + +int pixy_led_test() { + if(colorind==0) { + pixy_led_set_max_current(5); + } + + int32_t response; + int return_value; + return_value = pixy_command("led_set", INT32(colors[colorind++]), END_OUT_ARGS, &response, END_IN_ARGS); + colorind%=num_colors; + + if(return_value!=0) { + colorind=0; //reset color ind, to start at zero when plugging pixy in again + } + + return return_value; +} + +//---------------------------------------------------------------------------------------------------------------------------- + +int renderBA81(uint8_t renderFlags, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame); + + +int pixy_frame_test() { + + uint8_t* videodata; + int32_t response; + int32_t fourccc; + int8_t renderflags; + uint16_t xwidth; + uint16_t ywidth; + uint32_t size; + + + int return_value = pixy_command("cam_getFrame", // String id for remote procedure + INT8(0x21), // mode + INT16(0), // xoffset + INT16(0), // yoffset + INT16(320), // width + INT16(200), // height + END_OUT_ARGS, // separator + &response, // pointer to mem address for return value + &fourccc, + &renderflags, + &xwidth, + &ywidth, + &size, + &videodata, // pointer to mem address for returned frame + END_IN_ARGS); + + if(return_value==0) { + return_value = renderBA81(renderflags,xwidth,ywidth,size,videodata); + } + + return return_value; +} + + + + +void interpolateBayer(uint16_t width, uint16_t x, uint16_t y, uint8_t *pixel, uint8_t* r, uint8_t* g, uint8_t* b) +{ + if (y&1) + { + if (x&1) + { + *r = *pixel; + *g = (*(pixel-1)+*(pixel+1)+*(pixel+width)+*(pixel-width))>>2; + *b = (*(pixel-width-1)+*(pixel-width+1)+*(pixel+width-1)+*(pixel+width+1))>>2; + } + else + { + *r = (*(pixel-1)+*(pixel+1))>>1; + *g = *pixel; + *b = (*(pixel-width)+*(pixel+width))>>1; + } + } + else + { + if (x&1) + { + *r = (*(pixel-width)+*(pixel+width))>>1; + *g = *pixel; + *b = (*(pixel-1)+*(pixel+1))>>1; + } + else + { + *r = (*(pixel-width-1)+*(pixel-width+1)+*(pixel+width-1)+*(pixel+width+1))>>2; + *g = (*(pixel-1)+*(pixel+1)+*(pixel+width)+*(pixel-width))>>2; + *b = *pixel; + } + } + +} + + + + + + +int renderBA81(uint8_t renderFlags, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame) +{ + uint16_t x, y; + uint8_t r, g, b; + + + // skip first line + frame += width; + + // don't render top and bottom rows, and left and rightmost columns because of color + // interpolation + //uint32_t decodedimage[(width-2)*(height-2)]; + uint16_t* decodedimage = malloc(sizeof(uint16_t)*(width-2)*(height-2)); + + if(decodedimage==NULL) { //not enough free space to decode image in memory + //decode & render image pixel by pixel + uint16_t* line = decodedimage; + for (y=1; yon_update(screen_current); + } +} + + + +bool gui_screen_navigate(SCREEN_STRUCT* screen) { + if(screen==NULL) return false; + screen->next = NULL; + if(screen_current!=NULL) { + screen_current->on_leave(screen_current); + screen_current->next = screen; + } else { + screen_list=screen; + } + screen->on_enter(screen); + screen_current = screen; + return true; +} + + + +bool gui_screen_back() { + if(screen_list==NULL) return false; + SCREEN_STRUCT* current = screen_list; + SCREEN_STRUCT* last = NULL; + while(current->next != NULL) { + last = current; + current = current->next; + } + if(last==NULL) return false; //There's only a single screen. + if(current!=screen_current) return false; //List corrupted? + current->on_leave(current); + last->next=NULL; + last->on_enter(last); + screen_current=last; + return true; +} + + + + + + + diff --git a/common/gui/screen.h b/common/gui/screen.h new file mode 100644 index 0000000..3689007 --- /dev/null +++ b/common/gui/screen.h @@ -0,0 +1,25 @@ +#ifndef SCREEN_H +#define SCREEN_H + + +#include +#include + +typedef void (*SCREEN_CALLBACK)(void* screen); //!< Function pointer used... + +typedef struct SCREEN_S{ + SCREEN_CALLBACK on_enter; + SCREEN_CALLBACK on_leave; + SCREEN_CALLBACK on_update; + + + struct SCREEN_S* next; //Used internally. do not modify + +} SCREEN_STRUCT; + +bool gui_screen_navigate(SCREEN_STRUCT* screen); +bool gui_screen_back(); +SCREEN_STRUCT* gui_screen_get_current(); +void gui_screen_update(); + +#endif /* SCREEN_H */ diff --git a/common/touch/touch.h b/common/touch/touch.h index 4fd5c25..329538b 100644 --- a/common/touch/touch.h +++ b/common/touch/touch.h @@ -1,3 +1,7 @@ +#ifndef TOUCH_H +#define TOUCH_H + + #include #include @@ -25,3 +29,4 @@ bool touch_register_area(TOUCH_AREA_STRUCT* area); void touch_unregister_area(TOUCH_AREA_STRUCT* area); +#endif /* TOUCH_H */