diff --git a/Doxyfile b/Doxyfile
index 9ff1371..2d727a1 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -959,13 +959,13 @@ USE_MDFILE_AS_MAINPAGE =
# also VERBATIM_HEADERS is set to NO.
# The default value is: NO.
-SOURCE_BROWSER = NO
+SOURCE_BROWSER = YES
# Setting the INLINE_SOURCES tag to YES will include the body of functions,
# classes and enums directly into the documentation.
# The default value is: NO.
-INLINE_SOURCES = NO
+INLINE_SOURCES = YES
# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
# special comment blocks from generated source code fragments. Normal C, C++ and
@@ -1610,7 +1610,7 @@ EXTRA_SEARCH_MAPPINGS =
# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
# The default value is: YES.
-GENERATE_LATEX = NO
+GENERATE_LATEX = YES
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
@@ -1751,7 +1751,7 @@ LATEX_HIDE_INDICES = NO
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
-LATEX_SOURCE_CODE = NO
+LATEX_SOURCE_CODE = YES
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
diff --git a/README.md b/README.md
index 24d2b6d..3eba51d 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,8 @@ A Project with the Pixy cam and the STM32F4 Discovery. The project can also be r
## Documentation
Take a look at our [docu.pdf](./doc/docu.pdf) (German)
+Also make sure to check out the [doxygen documentation](http://t-moe.github.io/discoverpixy/) for the common folder.
+
## Folder structure
* *common*: device independent code and the "Application" itself
diff --git a/common/app/app.c b/common/app/app.c
index 21da23b..61e81fe 100644
--- a/common/app/app.c
+++ b/common/app/app.c
@@ -1,3 +1,32 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/app.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 51089aa Refactored Project Structure for use with emulator
+* 2015-04-03 timolang@gmail.com 1f2af9f Added more tft functions to common and emulator. Fixed eventloop.
+* 2015-04-03 timolang@gmail.com cab8609 Integrated pixy into emulator. Pixy is no longer in the common/libs folder but in emulator/libs and discovery/libs
+* 2015-04-03 timolang@gmail.com 1aa9194 Fixed Drawing of rects in Emulator. Got frames from pixy to emulator. Slooooow.
+* 2015-04-25 timolang@gmail.com 416883c Pixy&Usb work with the new folder structure now.
+* 2015-04-25 timolang@gmail.com 3d1e4b2 Simplified code a bit. Emulator does not work stable when replugging pixy.
+* 2015-04-25 timolang@gmail.com 0858b0d Fixed some bugs when receiving large data.
+* 2015-04-27 timolang@gmail.com 259d446 Added touch support to emulator. Implemented basic touch function.
+* 2015-04-27 aaron@duckpond.ch aed90ef Drawcircle added (emulator)
+* 2015-04-27 timolang@gmail.com e249fb2 Added font support
+* 2015-04-27 timolang@gmail.com 7c9eabc Added button support.
+* 2015-04-27 timolang@gmail.com b300ac5 Added Checkbox support
+* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
+* 2015-05-10 timolang@gmail.com e2bce8f Added filesystem module, tests and implementation for it in emulator.
+* 2015-05-12 aaron@duckpond.ch aec62d4 Added datasheets, updated touchsupport.
+* 2015-05-28 aaron@duckpond.ch 5bda699 implemented functions to get x and y coordinates and a test function
+* 2015-05-29 aaron@duckpond.ch 7d2d1a1 Implemented basic sampling and averaging of touch coordinates using timer7
+*
+**************************************************************************************************************************************/
+
#include "app.h"
#include "tft.h"
#include "system.h"
@@ -5,20 +34,20 @@
#include "screen_main.h"
#include "filesystem.h"
-void app_init() {
- system_init();
- tft_init();
- touch_init();
- filesystem_init();
+void app_init()
+{
+ system_init();
+ tft_init();
+ touch_init();
+ filesystem_init();
- gui_screen_navigate(get_screen_main());
+ gui_screen_navigate(get_screen_main());
}
//app event loop
-void app_process() {
-
- system_process(); //Let the system handle it's pending events
- gui_screen_update(); //update the currently active screen
+void app_process()
+{
+
+ system_process(); //Let the system handle it's pending events
+ gui_screen_update(); //update the currently active screen
}
-
-
diff --git a/common/app/app.h b/common/app/app.h
index 71d43b8..70053c3 100644
--- a/common/app/app.h
+++ b/common/app/app.h
@@ -1,6 +1,28 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/app.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 51089aa Refactored Project Structure for use with emulator
+* 2015-05-10 timolang@gmail.com 21edc56 Added doxyfile (doxygen) for the common folder. Started with doxygen comments for app and tft module.
+* 2015-05-11 timolang@gmail.com 08d9fe0 More work on doxygen module structure
+* 2015-06-08 timolang@gmail.com 73db8b5 Added doxygen mainpage comment in app.h
+*
+**************************************************************************************************************************************/
+
#ifndef APP_H
#define APP_H
+/*!
+ \mainpage discoverpixy Doxygen Documentation
+ Welcome to the code-documentation for all common (and plattformindependent) code. \n
+ A good point to start is probably the Modules page.
+ */
+
/**
* @defgroup app Application
* The App Module contains the effective, platform independent application.
diff --git a/common/app/pixy_control.c b/common/app/pixy_control.c
index c30418d..41b32ba 100644
--- a/common/app/pixy_control.c
+++ b/common/app/pixy_control.c
@@ -1,3 +1,21 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/pixy_control.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-06-02 aaron@duckpond.ch e018a75 Implemented basic pi and pid controller
+* 2015-06-06 aaron@duckpond.ch 8c264c2 Comment refactoring, updated PID values
+* 2015-06-06 aaron@duckpond.ch a04cda9 Refactured comments and implemented a bugfix for the PID controller
+* 2015-06-07 aaron@duckpond.ch 802d3df Fixed pid controller and refactored code
+* 2015-06-07 aaron@duckpond.ch 3d98ca9 Minor changes
+* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
+*
+**************************************************************************************************************************************/
+
/*
* pixy_control.c
*
@@ -16,10 +34,11 @@
#include
// PID tuning factors
-#define REG_PID_KP (0.5f)
+#define REG_PID_KP (0.41f)
#define REG_PID_KI (0.001f)
-#define REG_PID_KD (0.001f)
-#define REG_PID_TA (0.01f)
+#define REG_PID_KD (0.00025f)
+#define REG_PID_TA (0.001f)
+#define REG_PID_YKOR (0.3f)
// PID controller implementatoin for the y-axis
@@ -35,7 +54,7 @@ int16_t pixy_PID_Y(int16_t x, int16_t w)
//----PID-control-------------------------------------------------------------------------
esum = esum + e; // add e to the current sum
- y += REG_PID_KP * e; // add the proportional part to the output
+ y += (REG_PID_KP + REG_PID_YKOR) * e; // add the proportional part to the output
y += REG_PID_KI * REG_PID_TA * esum; // add the integral part to the output
y += REG_PID_KD * (e - eold) / REG_PID_TA; // add the differential part to the output
//----------------------------------------------------------------------------------------
diff --git a/common/app/pixy_control.h b/common/app/pixy_control.h
index 708cac4..083a8ed 100644
--- a/common/app/pixy_control.h
+++ b/common/app/pixy_control.h
@@ -1,3 +1,20 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/pixy_control.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-06-02 aaron@duckpond.ch e018a75 Implemented basic pi and pid controller
+* 2015-06-06 aaron@duckpond.ch 8c264c2 Comment refactoring, updated PID values
+* 2015-06-06 aaron@duckpond.ch a04cda9 Refactured comments and implemented a bugfix for the PID controller
+* 2015-06-07 aaron@duckpond.ch 802d3df Fixed pid controller and refactored code
+* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
+*
+**************************************************************************************************************************************/
+
#ifndef PIXY_CONTROL_H_
#define PIXY_CONTROL_H_
diff --git a/common/app/pixy_frame.c b/common/app/pixy_frame.c
index 8c7dc0d..ea82f59 100644
--- a/common/app/pixy_frame.c
+++ b/common/app/pixy_frame.c
@@ -1,3 +1,16 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/pixy_frame.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
+*
+**************************************************************************************************************************************/
+
#include "pixy_frame.h"
#include "pixy.h"
#include "tft.h"
@@ -5,118 +18,113 @@
-static int renderBA81(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame);
-static int saveBA81(FILE_HANDLE* handle, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame);
+static int renderBA81(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t* frame);
+static int saveBA81(FILE_HANDLE* handle, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t* frame);
-int pixy_render_full_frame(uint16_t x, uint16_t y) {
- return pixy_render_cropped_frame(x,y,0,0,320,200);
-}
-
-
-int pixy_render_cropped_frame(uint16_t x, uint16_t y, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height) {
- 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(xoffset), // xoffset
- INT16(yoffset), // yoffset
- INT16(width), // width
- INT16(height), // 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(x,y,xwidth,ywidth,size,videodata);
- }
-
- return return_value;
-}
-
-int pixy_save_full_frame(FILE_HANDLE* handle) {
- return pixy_save_cropped_frame(handle,0,0,320,200);
-}
-
-int pixy_save_cropped_frame(FILE_HANDLE* handle, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height) {
- 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(xoffset), // xoffset
- INT16(yoffset), // yoffset
- INT16(width), // width
- INT16(height), // 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 = saveBA81(handle,xwidth,ywidth,size,videodata);
- }
-
- return return_value;
-}
-
-
-
-
-
-static void interpolateBayer(uint16_t width, uint16_t x, uint16_t y, uint8_t *pixel, uint8_t* r, uint8_t* g, uint8_t* b)
+int pixy_render_full_frame(uint16_t x, uint16_t y)
{
- 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;
- }
+ return pixy_render_cropped_frame(x, y, 0, 0, 320, 200);
+}
+
+
+int pixy_render_cropped_frame(uint16_t x, uint16_t y, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height)
+{
+ 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(xoffset), // xoffset
+ INT16(yoffset), // yoffset
+ INT16(width), // width
+ INT16(height), // 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(x, y, xwidth, ywidth, size, videodata);
}
- else
- {
- if (x&1)
- {
- *r = (*(pixel-width)+*(pixel+width))>>1;
+
+ return return_value;
+}
+
+int pixy_save_full_frame(FILE_HANDLE* handle)
+{
+ return pixy_save_cropped_frame(handle, 0, 0, 320, 200);
+}
+
+int pixy_save_cropped_frame(FILE_HANDLE* handle, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height)
+{
+ 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(xoffset), // xoffset
+ INT16(yoffset), // yoffset
+ INT16(width), // width
+ INT16(height), // 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 = saveBA81(handle, xwidth, ywidth, size, videodata);
+ }
+
+ return return_value;
+}
+
+
+
+
+
+static 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-1)+*(pixel+1))>>1;
+ *b = (*(pixel - width) + * (pixel + width)) >> 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;
+ } 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;
}
}
@@ -128,7 +136,7 @@ static void interpolateBayer(uint16_t width, uint16_t x, uint16_t y, uint8_t *pi
-static int renderBA81(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame)
+static int renderBA81(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t* frame)
{
uint16_t x, y;
uint8_t r, g, b;
@@ -140,102 +148,101 @@ static int renderBA81(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t hei
// 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));
+ uint16_t* decodedimage = malloc(sizeof(uint16_t) * (width - 2) * (height - 2));
- if(decodedimage==NULL) { //not enough free space to decode image in memory
+ if (decodedimage == NULL) { //not enough free space to decode image in memory
//decode & render image pixel by pixel
- for (y=1; yfpos;
- uint32_t row_size_padded = ((width-2)*3 + 3) & (~3); //row size aligned to 4 bytes
- uint32_t fpos_end = fpos + row_size_padded* (height-2);
+ uint32_t row_size_padded = ((width - 2) * 3 + 3) & (~3); //row size aligned to 4 bytes
+ uint32_t fpos_end = fpos + row_size_padded * (height - 2);
// skip first line
frame += width;
// don't render top and bottom rows, and left and rightmost columns because of color
- // interpolation
+ // interpolation
- for (y=1; ynum_files; i++) {
- FILE_STRUCT* file = &(dir->files[i]);
- tft_print_formatted(10,y,
- (file->fattrib&F_DIR)?GREEN:RED,
- TRANSPARENT,0,"%-13s%c %c %s %02u%02u%02u %02u:%02u:%02u %u",
- file->fname,
- (file->fattrib&F_DIR)?'D':' ',
- (file->fattrib&F_HID)?'H':' ',
- (file->fattrib&F_RDO)?"R ":"RW",
- file->fdate.day,
- file->fdate.month,
- (file->fdate.year+1980)%100,
- file->ftime.hour,
- file->ftime.min,
- file->ftime.sec*2,
- file->fsize);
- y+=14;
- }
+ DIRECTORY_STRUCT* dir = filesystem_dir_open(".");
- filesystem_dir_close(dir);
+ if (dir == NULL) {
+ return;
+ }
- y+=14;
+ for (int i = 0; i < dir->num_files; i++) {
+ FILE_STRUCT* file = &(dir->files[i]);
+ tft_print_formatted(10, y,
+ (file->fattrib & F_DIR) ? GREEN : RED,
+ TRANSPARENT, 0, "%-13s%c %c %s %02u%02u%02u %02u:%02u:%02u %u",
+ file->fname,
+ (file->fattrib & F_DIR) ? 'D' : ' ',
+ (file->fattrib & F_HID) ? 'H' : ' ',
+ (file->fattrib & F_RDO) ? "R " : "RW",
+ file->fdate.day,
+ file->fdate.month,
+ (file->fdate.year + 1980) % 100,
+ file->ftime.hour,
+ file->ftime.min,
+ file->ftime.sec * 2,
+ file->fsize);
+ y += 14;
+ }
- FILE_HANDLE* file = filesystem_file_open("test.txt");
- if(file==NULL) {
- tft_print_line(10,y,BLUE,TRANSPARENT,0,"Could not open test.txt");
- } else {
- char buf [30];
- int size = (file->fsize>30)?29:file->fsize-1;
- FILE_STATUS st = filesystem_file_read(file,buf,size);
-
- if(st==F_OK) {
- buf[file->fpos]='\0';
- tft_print_formatted(10,y,BLUE,TRANSPARENT,0,"test.txt contains \"%s\"",buf);
- long num = strtol(&(buf[file->fpos-4]),NULL,0);
- num++;
-
- y+=14;
-
- if(filesystem_file_seek(file,file->fpos-4)!=F_OK) {
- tft_print_formatted(10,y,BLUE,TRANSPARENT,0,"Could not seek to %d",file->fpos-4);
- } else {
- sprintf(buf,"%04d",num);
- if(filesystem_file_write(file,buf,4) != F_OK) {
- tft_print_formatted(10,y,BLUE,TRANSPARENT,0,"Could not write new number %d",num);
- } else {
- tft_print_formatted(10,y,BLUE,TRANSPARENT,0,"New number written %d",num);
- }
- }
- } else {
- tft_print_line(10,y,BLUE,TRANSPARENT,0,"Could not read from test.txt");
- }
+ filesystem_dir_close(dir);
- }
- filesystem_file_close(file);
+ y += 14;
- image_test();
+ FILE_HANDLE* file = filesystem_file_open("test.txt");
+
+ if (file == NULL) {
+ tft_print_line(10, y, BLUE, TRANSPARENT, 0, "Could not open test.txt");
+ } else {
+ char buf [30];
+ int size = (file->fsize > 30) ? 29 : file->fsize - 1;
+ FILE_STATUS st = filesystem_file_read(file, buf, size);
+
+ if (st == F_OK) {
+ buf[file->fpos] = '\0';
+ tft_print_formatted(10, y, BLUE, TRANSPARENT, 0, "test.txt contains \"%s\"", buf);
+ long num = strtol(&(buf[file->fpos - 4]), NULL, 0);
+ num++;
+
+ y += 14;
+
+ if (filesystem_file_seek(file, file->fpos - 4) != F_OK) {
+ tft_print_formatted(10, y, BLUE, TRANSPARENT, 0, "Could not seek to %d", file->fpos - 4);
+ } else {
+ sprintf(buf, "%04d", num);
+
+ if (filesystem_file_write(file, buf, 4) != F_OK) {
+ tft_print_formatted(10, y, BLUE, TRANSPARENT, 0, "Could not write new number %d", num);
+ } else {
+ tft_print_formatted(10, y, BLUE, TRANSPARENT, 0, "New number written %d", num);
+ }
+ }
+ } else {
+ tft_print_line(10, y, BLUE, TRANSPARENT, 0, "Could not read from test.txt");
+ }
+
+ }
+
+ filesystem_file_close(file);
+
+ image_test();
}
-static void leave(void* screen) {
- gui_button_remove(&b_back);
+static void leave(void* screen)
+{
+ gui_button_remove(&b_back);
}
-static void update(void* screen) {
+static void update(void* screen)
+{
}
static SCREEN_STRUCT screen = {
- enter,
- leave,
- update
+ enter,
+ leave,
+ update
};
-SCREEN_STRUCT* get_screen_filetest() {
- return &screen;
+SCREEN_STRUCT* get_screen_filetest()
+{
+ return &screen;
}
-static void image_test() {
+static void image_test()
+{
- if(!tft_draw_bitmap_file_unscaled(250,170,"cpu.bmp")) {
- tft_print_line(10,180,BLUE,TRANSPARENT,0,"Could not open cpu.bmp");
- }
- tft_draw_rectangle(250-1,170-1,250-1+64,170-1+64,BLACK);
+ if (!tft_draw_bitmap_file_unscaled(250, 170, "cpu.bmp")) {
+ tft_print_line(10, 180, BLUE, TRANSPARENT, 0, "Could not open cpu.bmp");
+ }
+
+ tft_draw_rectangle(250 - 1, 170 - 1, 250 - 1 + 64, 170 - 1 + 64, BLACK);
}
diff --git a/common/app/screen_filetest.h b/common/app/screen_filetest.h
index eec7dbf..6829d2a 100644
--- a/common/app/screen_filetest.h
+++ b/common/app/screen_filetest.h
@@ -1,3 +1,18 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/screen_filetest.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-05-10 timolang@gmail.com e2bce8f Added filesystem module, tests and implementation for it in emulator.
+* 2015-05-10 timolang@gmail.com 21edc56 Added doxyfile (doxygen) for the common folder. Started with doxygen comments for app and tft module.
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+*
+**************************************************************************************************************************************/
+
#include "screen.h"
/**
diff --git a/common/app/screen_guitest.c b/common/app/screen_guitest.c
index 282636e..eeee1d9 100644
--- a/common/app/screen_guitest.c
+++ b/common/app/screen_guitest.c
@@ -1,3 +1,21 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/screen_guitest.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
+* 2015-04-30 timolang@gmail.com 76ea9d8 Added num up down support.
+* 2015-05-09 timolang@gmail.com c652b6b Improved Emulator Gui
+* 2015-05-29 aaron@duckpond.ch 7d2d1a1 Implemented basic sampling and averaging of touch coordinates using timer7
+* 2015-06-01 timolang@gmail.com eb573bc Finalized calibration. Fixed a bug in screen module.
+* 2015-06-02 timolang@gmail.com da34bce Fixed all printf related problems on discovery using workarounds and newlib nano-instead of newlib
+*
+**************************************************************************************************************************************/
+
#include "screen_guitest.h"
#include "button.h"
#include "tft.h"
@@ -9,127 +27,138 @@ static TOUCH_AREA_STRUCT a_area;
static CHECKBOX_STRUCT c_cbox;
static NUMUPDOWN_STRUCT n_updown;
-static void checkboxCB(void *checkbox, bool checked) {
- printf("Checkbox %s\n",(checked?"checked":"unchecked"));
+static void checkboxCB(void* checkbox, bool checked)
+{
+ printf("Checkbox %s\n", (checked ? "checked" : "unchecked"));
}
-static void b_back_cb(void* button) {
- gui_screen_back();
+static void b_back_cb(void* button)
+{
+ gui_screen_back();
}
-static void n_updown_cb(void* numupdown, int16_t value) {
- printf("New NumUpDown Value %d\n",value);
+static void n_updown_cb(void* numupdown, int16_t value)
+{
+ printf("New NumUpDown Value %d\n", value);
}
-static 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;
- }
+static 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;
+ }
}
-static void enter(void* screen) {
- tft_clear(HEX(0xA6FD9A));
-
- //Back button
- b_back.base.x1=10; //Start X of Button
- b_back.base.y1=10; //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)
+static void enter(void* screen)
+{
+ tft_clear(HEX(0xA6FD9A));
+
+ //Back button
+ b_back.base.x1 = 10; //Start X of Button
+ b_back.base.y1 = 10; //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)
- //tft test
- tft_draw_pixel(0,0,BLACK);
- tft_draw_pixel(319,239,BLACK);
- tft_draw_pixel(10,210,BLUE);
- tft_draw_pixel(12,210,BLUE);
- tft_draw_rectangle(40,100,60,235,BLUE);
- tft_fill_rectangle(100,215,200,225,GREEN);
- tft_draw_line(10,50,310,225,RGB(0xFF,0,0xFF));
- tft_draw_circle(10,10,100, RED);
- tft_print_line(30, 130, RED, BLUE, 0, "Hallo");
-
-
-
- //Area test
- a_area.hookedActions = PEN_DOWN | PEN_UP | PEN_MOVE | PEN_ENTER | PEN_LEAVE;
- a_area.x1 = 130;
- a_area.y1 = 30;
- a_area.x2 = 200;
- a_area.y2 = 60;
- a_area.callback = touchCB;
- touch_register_area(&a_area);
+ //tft test
+ tft_draw_pixel(0, 0, BLACK);
+ tft_draw_pixel(319, 239, BLACK);
+ tft_draw_pixel(10, 210, BLUE);
+ tft_draw_pixel(12, 210, BLUE);
+ tft_draw_rectangle(40, 100, 60, 235, BLUE);
+ tft_fill_rectangle(100, 215, 200, 225, GREEN);
+ tft_draw_line(10, 50, 310, 225, RGB(0xFF, 0, 0xFF));
+ tft_draw_circle(10, 10, 100, RED);
+ tft_print_line(30, 130, RED, BLUE, 0, "Hallo");
- //Checkbox test
- c_cbox.base.x1=220;
- c_cbox.base.y1=45;
- c_cbox.base.x2=c_cbox.base.x1+16;
- c_cbox.base.y2=c_cbox.base.y1+16;
- c_cbox.fgcolor = GREEN;
- c_cbox.checked = true;
- c_cbox.callback = checkboxCB;
- gui_checkbox_add(&c_cbox);
-
+ //Area test
+ a_area.hookedActions = PEN_DOWN | PEN_UP | PEN_MOVE | PEN_ENTER | PEN_LEAVE;
+ a_area.x1 = 130;
+ a_area.y1 = 30;
+ a_area.x2 = 200;
+ a_area.y2 = 60;
+ a_area.callback = touchCB;
+ touch_register_area(&a_area);
- //Num up down test
- n_updown.x=200;
- n_updown.y=120;
- n_updown.fgcolor=RED;
- n_updown.value = -3;
- n_updown.max=11;
- n_updown.min =-5;
- n_updown.callback=n_updown_cb;
- gui_numupdown_add(&n_updown);
+
+
+ //Checkbox test
+ c_cbox.base.x1 = 220;
+ c_cbox.base.y1 = 45;
+ c_cbox.base.x2 = c_cbox.base.x1 + 16;
+ c_cbox.base.y2 = c_cbox.base.y1 + 16;
+ c_cbox.fgcolor = GREEN;
+ c_cbox.checked = true;
+ c_cbox.callback = checkboxCB;
+ gui_checkbox_add(&c_cbox);
+
+
+ //Num up down test
+ n_updown.x = 200;
+ n_updown.y = 120;
+ n_updown.fgcolor = RED;
+ n_updown.value = -3;
+ n_updown.max = 11;
+ n_updown.min = -5;
+ n_updown.callback = n_updown_cb;
+ gui_numupdown_add(&n_updown);
}
-static void leave(void* screen) {
- gui_button_remove(&b_back);
- gui_checkbox_remove(&c_cbox);
- gui_numupdown_remove(&n_updown);
- touch_unregister_area(&a_area);
+static void leave(void* screen)
+{
+ gui_button_remove(&b_back);
+ gui_checkbox_remove(&c_cbox);
+ gui_numupdown_remove(&n_updown);
+ touch_unregister_area(&a_area);
}
-static void update(void* screen) {
- //gui_button_redraw(&b_back); //only needed if button is overdrawn by others
- //.... for the other elements as well
+static void update(void* screen)
+{
+ //gui_button_redraw(&b_back); //only needed if button is overdrawn by others
+ //.... for the other elements as well
}
static SCREEN_STRUCT screen = {
- enter,
- leave,
- update
+ enter,
+ leave,
+ update
};
-SCREEN_STRUCT* get_screen_guitest() {
- return &screen;
+SCREEN_STRUCT* get_screen_guitest()
+{
+ return &screen;
}
-
-
diff --git a/common/app/screen_guitest.h b/common/app/screen_guitest.h
index 82a9d49..8a06117 100644
--- a/common/app/screen_guitest.h
+++ b/common/app/screen_guitest.h
@@ -1,3 +1,18 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/screen_guitest.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
+* 2015-05-10 timolang@gmail.com 21edc56 Added doxyfile (doxygen) for the common folder. Started with doxygen comments for app and tft module.
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+*
+**************************************************************************************************************************************/
+
#include "screen.h"
diff --git a/common/app/screen_main.c b/common/app/screen_main.c
index 24cfd68..d099ea9 100644
--- a/common/app/screen_main.c
+++ b/common/app/screen_main.c
@@ -1,3 +1,21 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/screen_main.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
+* 2015-05-10 timolang@gmail.com e2bce8f Added filesystem module, tests and implementation for it in emulator.
+* 2015-05-15 timolang@gmail.com 27c09ba Redesigned main menu. Moved stuff from pixytest to a new helper file and to the new "photo mode"-screen.
+* 2015-05-16 timolang@gmail.com e46314b Added Tracking Screen and implemented "Reference Tracking" and "Color Region Selection"
+* 2015-06-01 aaron@duckpond.ch caa7b5c Added IRQ for user button, fixed some touchproblems.
+* 2015-06-01 timolang@gmail.com 3155f42 Fixed mainscreen layout.
+*
+**************************************************************************************************************************************/
+
#include "screen_main.h"
#include "screen_guitest.h"
#include "screen_pixytest.h"
@@ -17,157 +35,165 @@ BUTTON_STRUCT b_ref_tracking;
BUTTON_STRUCT b_photo_mode;
-static void b_our_tracking_cb(void* button) {
- tracking_set_mode(OUR_TRACKING);
- gui_screen_navigate(get_screen_tracking());
+static void b_our_tracking_cb(void* button)
+{
+ tracking_set_mode(OUR_TRACKING);
+ gui_screen_navigate(get_screen_tracking());
}
-static void b_ref_tracking_cb(void* button) {
- tracking_set_mode(REFERENCE_TRACKING);
- gui_screen_navigate(get_screen_tracking());
+static void b_ref_tracking_cb(void* button)
+{
+ tracking_set_mode(REFERENCE_TRACKING);
+ gui_screen_navigate(get_screen_tracking());
}
-static void b_photo_mode_cb(void* button) {
- gui_screen_navigate(get_screen_photomode());
+static void b_photo_mode_cb(void* button)
+{
+ gui_screen_navigate(get_screen_photomode());
}
-static void b_guitest_cb(void* button) {
- gui_screen_navigate(get_screen_guitest());
+static void b_guitest_cb(void* button)
+{
+ gui_screen_navigate(get_screen_guitest());
}
-static void b_filetest_cb(void* button) {
- gui_screen_navigate(get_screen_filetest());
+static void b_filetest_cb(void* button)
+{
+ gui_screen_navigate(get_screen_filetest());
}
-static void b_pixytest_cb(void* button) {
- gui_screen_navigate(get_screen_pixytest());
+static void b_pixytest_cb(void* button)
+{
+ gui_screen_navigate(get_screen_pixytest());
}
-static void enter(void* screen) {
- tft_clear(WHITE);
+static void enter(void* screen)
+{
+ tft_clear(WHITE);
- //Heading
- tft_print_line(10,10,BLUE,TRANSPARENT,1,"Discoverpixy");
- tft_draw_line(0,40,319,40,BLACK);
+ //Heading
+ tft_print_line(10, 10, BLUE, TRANSPARENT, 1, "Discoverpixy");
+ tft_draw_line(0, 40, 319, 40, BLACK);
- #define X_TAB 97
- #define BUTTON_SPACING 7
+#define X_TAB 97
+#define BUTTON_SPACING 7
- //First line of buttons
- #define Y_FIRST 60
- tft_print_line(10,Y_FIRST,BLACK,TRANSPARENT,0,"Tracking:");
+ //First line of buttons
+#define Y_FIRST 60
+ tft_print_line(10, Y_FIRST, BLACK, TRANSPARENT, 0, "Tracking:");
- b_our_tracking.base.x1=X_TAB; //Start X of Button
- b_our_tracking.base.y1=Y_FIRST-3; //Start Y of Button
- b_our_tracking.base.x2=AUTO; //Auto Calculate X2 with String Width
- b_our_tracking.base.y2=AUTO; //Auto Calculate Y2 with String Height
- b_our_tracking.txtcolor=WHITE; //Set foreground color
- b_our_tracking.bgcolor=HEX(0xE30535); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
- b_our_tracking.font=0; //Select Font
- b_our_tracking.text="Our Tracking"; //Set Text (For formatted strings take sprintf)
- b_our_tracking.callback=b_our_tracking_cb; //Call b_our_tracking when the button get's pressed
- gui_button_add(&b_our_tracking); //Register Button (and run the callback from now on)
+ b_our_tracking.base.x1 = X_TAB; //Start X of Button
+ b_our_tracking.base.y1 = Y_FIRST - 3; //Start Y of Button
+ b_our_tracking.base.x2 = AUTO; //Auto Calculate X2 with String Width
+ b_our_tracking.base.y2 = AUTO; //Auto Calculate Y2 with String Height
+ b_our_tracking.txtcolor = WHITE; //Set foreground color
+ b_our_tracking.bgcolor = HEX(0xE30535); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
+ b_our_tracking.font = 0; //Select Font
+ b_our_tracking.text = "Our Tracking"; //Set Text (For formatted strings take sprintf)
+ b_our_tracking.callback = b_our_tracking_cb; //Call b_our_tracking when the button get's pressed
+ gui_button_add(&b_our_tracking); //Register Button (and run the callback from now on)
- b_ref_tracking.base.x1=b_our_tracking.base.x2+BUTTON_SPACING;
- b_ref_tracking.base.y1=Y_FIRST-3;
- b_ref_tracking.base.x2=AUTO;
- b_ref_tracking.base.y2=AUTO;
- b_ref_tracking.txtcolor=WHITE;
- b_ref_tracking.bgcolor=HEX(0xFF2151);
- b_ref_tracking.font=0;
- b_ref_tracking.text="Ref Tracking";
- b_ref_tracking.callback=b_ref_tracking_cb;
- gui_button_add(&b_ref_tracking);
+ b_ref_tracking.base.x1 = b_our_tracking.base.x2 + BUTTON_SPACING;
+ b_ref_tracking.base.y1 = Y_FIRST - 3;
+ b_ref_tracking.base.x2 = AUTO;
+ b_ref_tracking.base.y2 = AUTO;
+ b_ref_tracking.txtcolor = WHITE;
+ b_ref_tracking.bgcolor = HEX(0xFF2151);
+ b_ref_tracking.font = 0;
+ b_ref_tracking.text = "Ref Tracking";
+ b_ref_tracking.callback = b_ref_tracking_cb;
+ gui_button_add(&b_ref_tracking);
- //Second line of buttons
- #define Y_SECOND Y_FIRST+25
- tft_print_line(10,Y_SECOND,BLACK,TRANSPARENT,0,"Photo mode:");
+ //Second line of buttons
+#define Y_SECOND Y_FIRST+25
+ tft_print_line(10, Y_SECOND, BLACK, TRANSPARENT, 0, "Photo mode:");
- b_photo_mode.base.x1=X_TAB;
- b_photo_mode.base.y1=Y_SECOND-3;
- b_photo_mode.base.x2=AUTO;
- b_photo_mode.base.y2=AUTO;
- b_photo_mode.txtcolor=WHITE;
- b_photo_mode.bgcolor=HEX(0x21B1FF);
- b_photo_mode.font=0;
- b_photo_mode.text="Photo Mode";
- b_photo_mode.callback=b_photo_mode_cb;
- gui_button_add(&b_photo_mode);
+ b_photo_mode.base.x1 = X_TAB;
+ b_photo_mode.base.y1 = Y_SECOND - 3;
+ b_photo_mode.base.x2 = AUTO;
+ b_photo_mode.base.y2 = AUTO;
+ b_photo_mode.txtcolor = WHITE;
+ b_photo_mode.bgcolor = HEX(0x21B1FF);
+ b_photo_mode.font = 0;
+ b_photo_mode.text = "Photo Mode";
+ b_photo_mode.callback = b_photo_mode_cb;
+ gui_button_add(&b_photo_mode);
- //Third line of buttons
- #define Y_THIRD Y_SECOND+25
- tft_print_line(10,Y_THIRD,BLACK,TRANSPARENT,0,"Tests:");
+ //Third line of buttons
+#define Y_THIRD Y_SECOND+25
+ tft_print_line(10, Y_THIRD, BLACK, TRANSPARENT, 0, "Tests:");
- b_guitest.base.x1=X_TAB;
- b_guitest.base.y1=Y_THIRD-3;
- b_guitest.base.x2=AUTO;
- b_guitest.base.y2=AUTO;
- b_guitest.txtcolor=BLACK;
- b_guitest.bgcolor=HEX(0x00FA21);
- b_guitest.font=0;
- b_guitest.text="Gui & Tft";
- b_guitest.callback=b_guitest_cb;
- gui_button_add(&b_guitest);
+ b_guitest.base.x1 = X_TAB;
+ b_guitest.base.y1 = Y_THIRD - 3;
+ b_guitest.base.x2 = AUTO;
+ b_guitest.base.y2 = AUTO;
+ b_guitest.txtcolor = BLACK;
+ b_guitest.bgcolor = HEX(0x00FA21);
+ b_guitest.font = 0;
+ b_guitest.text = "Gui & Tft";
+ b_guitest.callback = b_guitest_cb;
+ gui_button_add(&b_guitest);
- b_pixytest.base.x1=b_guitest.base.x2+BUTTON_SPACING;
- b_pixytest.base.y1=Y_THIRD-3;
- b_pixytest.base.x2=AUTO;
- b_pixytest.base.y2=AUTO;
- b_pixytest.txtcolor=BLACK;
- b_pixytest.bgcolor=HEX(0x00FA96);
- b_pixytest.font=0;
- b_pixytest.text="Pixy";
- b_pixytest.callback=b_pixytest_cb;
- gui_button_add(&b_pixytest);
+ b_pixytest.base.x1 = b_guitest.base.x2 + BUTTON_SPACING;
+ b_pixytest.base.y1 = Y_THIRD - 3;
+ b_pixytest.base.x2 = AUTO;
+ b_pixytest.base.y2 = AUTO;
+ b_pixytest.txtcolor = BLACK;
+ b_pixytest.bgcolor = HEX(0x00FA96);
+ b_pixytest.font = 0;
+ b_pixytest.text = "Pixy";
+ b_pixytest.callback = b_pixytest_cb;
+ gui_button_add(&b_pixytest);
- b_filetest.base.x1=b_pixytest.base.x2+BUTTON_SPACING;
- b_filetest.base.y1=Y_THIRD-3;
- b_filetest.base.x2=AUTO;
- b_filetest.base.y2=AUTO;
- b_filetest.txtcolor=BLACK;
- b_filetest.bgcolor=HEX(0x00FAC4);
- b_filetest.font=0;
- b_filetest.text="File";
- b_filetest.callback=b_filetest_cb;
- gui_button_add(&b_filetest);
+ b_filetest.base.x1 = b_pixytest.base.x2 + BUTTON_SPACING;
+ b_filetest.base.y1 = Y_THIRD - 3;
+ b_filetest.base.x2 = AUTO;
+ b_filetest.base.y2 = AUTO;
+ b_filetest.txtcolor = BLACK;
+ b_filetest.bgcolor = HEX(0x00FAC4);
+ b_filetest.font = 0;
+ b_filetest.text = "File";
+ b_filetest.callback = b_filetest_cb;
+ gui_button_add(&b_filetest);
- //Bottom line
- tft_draw_line(0,145,319,145,BLACK);
- tft_print_line(10,150,BLUE,TRANSPARENT,0,"Powered by");
- tft_draw_bitmap_file_unscaled(10,165,"pixy_small.bmp");
- tft_draw_bitmap_file_unscaled(165,165,"stm_small.bmp");
+ //Bottom line
+ tft_draw_line(0, 145, 319, 145, BLACK);
+ tft_print_line(10, 150, BLUE, TRANSPARENT, 0, "Powered by");
+ tft_draw_bitmap_file_unscaled(10, 165, "pixy_small.bmp");
+ tft_draw_bitmap_file_unscaled(165, 165, "stm_small.bmp");
}
-static void leave(void* screen) {
- gui_button_remove(&b_our_tracking);
- gui_button_remove(&b_ref_tracking);
- gui_button_remove(&b_photo_mode);
- gui_button_remove(&b_guitest);
- gui_button_remove(&b_pixytest);
- gui_button_remove(&b_filetest);
+static void leave(void* screen)
+{
+ gui_button_remove(&b_our_tracking);
+ gui_button_remove(&b_ref_tracking);
+ gui_button_remove(&b_photo_mode);
+ gui_button_remove(&b_guitest);
+ gui_button_remove(&b_pixytest);
+ gui_button_remove(&b_filetest);
}
-static void update(void* screen) {
- //gui_button_redraw(&b_guitest); //only needed if button is overdrawn by others
+static void update(void* screen)
+{
+ //gui_button_redraw(&b_guitest); //only needed if button is overdrawn by others
}
static SCREEN_STRUCT screen = {
- enter,
- leave,
- update
+ enter,
+ leave,
+ update
};
-SCREEN_STRUCT* get_screen_main() {
- return &screen;
+SCREEN_STRUCT* get_screen_main()
+{
+ return &screen;
}
-
-
diff --git a/common/app/screen_main.h b/common/app/screen_main.h
index 8cc9bff..f166187 100644
--- a/common/app/screen_main.h
+++ b/common/app/screen_main.h
@@ -1,3 +1,20 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/screen_main.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
+* 2015-05-10 timolang@gmail.com 21edc56 Added doxyfile (doxygen) for the common folder. Started with doxygen comments for app and tft module.
+* 2015-05-11 timolang@gmail.com 08d9fe0 More work on doxygen module structure
+* 2015-05-12 timolang@gmail.com 1402598 Added doxygen stuff for button module and some minor changes to touch, screen_main and tft module.
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+*
+**************************************************************************************************************************************/
+
#include "screen.h"
/**
diff --git a/common/app/screen_photomode.c b/common/app/screen_photomode.c
index 01232f4..872e354 100644
--- a/common/app/screen_photomode.c
+++ b/common/app/screen_photomode.c
@@ -1,3 +1,18 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/screen_photomode.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-05-15 timolang@gmail.com 27c09ba Redesigned main menu. Moved stuff from pixytest to a new helper file and to the new "photo mode"-screen.
+* 2015-05-16 timolang@gmail.com 62006e0 Documented pixy_helper and implemented/finished photo-mode screens! Snap some shots!
+* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
+*
+**************************************************************************************************************************************/
+
#include "screen_photomode.h"
#include "screen_photomode_save.h"
#include "button.h"
@@ -12,155 +27,182 @@ static bool pixy_connected = false; //Whether or not the pixy cam is currently c
static BUTTON_STRUCT b_back; //Button to navigate back
static BUTTON_STRUCT b_save; //Button to save the current image
static TOUCH_AREA_STRUCT a_area; //Touch Area, where the frame is drawn. Used to drag the image around
-static bool subMenu=false; //Whether or not we left the current screen for a submenu
+static bool subMenu = false; //Whether or not we left the current screen for a submenu
//Callback for when the user presses the "back" button
-static void b_back_cb(void* button) {
- subMenu = false; //we're not entering a submenu
- gui_screen_back(); //navigate back to the previous screen
+static void b_back_cb(void* button)
+{
+ subMenu = false; //we're not entering a submenu
+ gui_screen_back(); //navigate back to the previous screen
}
//Callback for when the user presses the "save" button
-static void b_save_cb(void* button) {
- subMenu = true; //we're entering a submenu
- gui_screen_navigate(get_screen_photomodesave()); //navigate to the save screen
+static void b_save_cb(void* button)
+{
+ subMenu = true; //we're entering a submenu
+ gui_screen_navigate(get_screen_photomodesave()); //navigate to the save screen
}
static POINT_STRUCT pixy_pos; //The current position of pixy's servos
static POINT_STRUCT old_pos; //The last touch position on the screen
//Callback for when the user drags the image around
-static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction) {
- POINT_STRUCT p = touch_get_last_point(); //get the last touched point
- switch(triggeredAction) {
- case PEN_ENTER:
- case PEN_DOWN:
- old_pos = p; //If the user "newly" enters the touch area, we set the "last" position to the current
- break;
- case PEN_MOVE: //the user is moving around, he entered the screen a while ago (old_pos is set)
- {
- int16_t deltaX = p.x - old_pos.x; //Calculate x difference between last and current touch
- int16_t deltaY = p.y - old_pos.y; //Calculate y difference between last and current touch
- old_pos=p; //store the current touch point for the next time
- //printf("%d %d\n",deltaX,deltaY);
- if(pixy_connected) {
- //Calculate new servo coordinates. 2 is just a proportional factor
- int16_t new_x = pixy_pos.x+deltaX*2;
- int16_t new_y = pixy_pos.y-deltaY*2;
+static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction)
+{
+ POINT_STRUCT p = touch_get_last_point(); //get the last touched point
- //check limits
- if(new_x<0) new_x=0;
- if(new_x>1000) new_x=1000;
- if(new_y<0) new_y=0;
- if(new_y>1000) new_y=1000;
-
- //set pixy_pos so that the main routine can send it to the servos
- pixy_pos.x = new_x;
- pixy_pos.y= new_y;
- }
- }
+ switch (triggeredAction) {
+ case PEN_ENTER:
+ case PEN_DOWN:
+ old_pos = p; //If the user "newly" enters the touch area, we set the "last" position to the current
break;
- case PEN_UP:
- case PEN_LEAVE:
- //printf("Leave/up\n");
- break;
- default: break;
- }
-
+
+ case PEN_MOVE: { //the user is moving around, he entered the screen a while ago (old_pos is set)
+ int16_t deltaX = p.x - old_pos.x; //Calculate x difference between last and current touch
+ int16_t deltaY = p.y - old_pos.y; //Calculate y difference between last and current touch
+ old_pos = p; //store the current touch point for the next time
+
+ //printf("%d %d\n",deltaX,deltaY);
+ if (pixy_connected) {
+ //Calculate new servo coordinates. 2 is just a proportional factor
+ int16_t new_x = pixy_pos.x + deltaX * 2;
+ int16_t new_y = pixy_pos.y - deltaY * 2;
+
+ //check limits
+ if (new_x < 0) {
+ new_x = 0;
+ }
+
+ if (new_x > 1000) {
+ new_x = 1000;
+ }
+
+ if (new_y < 0) {
+ new_y = 0;
+ }
+
+ if (new_y > 1000) {
+ new_y = 1000;
+ }
+
+ //set pixy_pos so that the main routine can send it to the servos
+ pixy_pos.x = new_x;
+ pixy_pos.y = new_y;
+ }
+ }
+ break;
+
+ case PEN_UP:
+ case PEN_LEAVE:
+ //printf("Leave/up\n");
+ break;
+
+ default:
+ break;
+ }
+
}
//Callback for when the screen is entered/loaded
-static void enter(void* screen) {
- tft_clear(WHITE);
-
- tft_print_line(5,5,BLACK,TRANSPARENT,0,"Drag the image around and ");
+static void enter(void* screen)
+{
+ tft_clear(WHITE);
- //Back button
- b_back.base.x1=5; //Start X of Button
- b_back.base.y1=19; //Start Y of Button
- b_back.base.x2=AUTO; //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)
+ tft_print_line(5, 5, BLACK, TRANSPARENT, 0, "Drag the image around and ");
- //Save button
- b_save.base.x1=190;
- b_save.base.y1=3;
- b_save.base.x2=AUTO;
- b_save.base.y2=AUTO;
- b_save.txtcolor=WHITE;
- b_save.bgcolor=HEX(0x1010AE);
- b_save.font=0;
- b_save.text="Save it!";
- b_save.callback=b_save_cb;
- gui_button_add(&b_save);
+ //Back button
+ b_back.base.x1 = 5; //Start X of Button
+ b_back.base.y1 = 19; //Start Y of Button
+ b_back.base.x2 = AUTO; //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)
- //Frame Coordinates: topleft = (1,40); bottomright = (318,238)
- //Leave a 10px border for the area
+ //Save button
+ b_save.base.x1 = 190;
+ b_save.base.y1 = 3;
+ b_save.base.x2 = AUTO;
+ b_save.base.y2 = AUTO;
+ b_save.txtcolor = WHITE;
+ b_save.bgcolor = HEX(0x1010AE);
+ b_save.font = 0;
+ b_save.text = "Save it!";
+ b_save.callback = b_save_cb;
+ gui_button_add(&b_save);
- //Area to drag the image around
- a_area.hookedActions = PEN_DOWN | PEN_MOVE | PEN_ENTER | PEN_UP | PEN_LEAVE;
- a_area.x1 = 11;
- a_area.y1 = 50;
- a_area.x2 = 308;
- a_area.y2 = 228;
- a_area.callback = touchCB;
- touch_register_area(&a_area);
+ //Frame Coordinates: topleft = (1,40); bottomright = (318,238)
+ //Leave a 10px border for the area
- //Pixy stuff
- pixy_connected = (pixy_init()==0); //try to connect to pixy
- if(pixy_connected && !subMenu) { //pixy is connected, but we are not coming from a submenu
- pixy_pos.x=pixy_pos.y=500; //reset servo positions to center
- }
+ //Area to drag the image around
+ a_area.hookedActions = PEN_DOWN | PEN_MOVE | PEN_ENTER | PEN_UP | PEN_LEAVE;
+ a_area.x1 = 11;
+ a_area.y1 = 50;
+ a_area.x2 = 308;
+ a_area.y2 = 228;
+ a_area.callback = touchCB;
+ touch_register_area(&a_area);
+
+ //Pixy stuff
+ pixy_connected = (pixy_init() == 0); //try to connect to pixy
+
+ if (pixy_connected && !subMenu) { //pixy is connected, but we are not coming from a submenu
+ pixy_pos.x = pixy_pos.y = 500; //reset servo positions to center
+ }
}
//Callback for when the screen is left/unloaded
-static void leave(void* screen) {
- //remove buttons and touch area.
- gui_button_remove(&b_back);
- gui_button_remove(&b_save);
- touch_unregister_area(&a_area);
+static void leave(void* screen)
+{
+ //remove buttons and touch area.
+ gui_button_remove(&b_back);
+ gui_button_remove(&b_save);
+ touch_unregister_area(&a_area);
}
//Callback for when the screen should be updated
//This is the main loop of the screen. This method will be called repeatedly
-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 :'(
+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;
- if(!subMenu) { //we're not coming from a submenu
- pixy_pos.x=pixy_pos.y=500; //reset servo positions to center
- }
- printf("pixy (re)initialized\n");
- }
- }
+ if (!pixy_connected) { //Pixy not connected
+ pixy_close(); //Ensure that all pixy resources are freed (failsafe)
- if(pixy_connected) { //If we are connected (now)
- pixy_service(); //Handle pending pixy events (e.g. color info retrival)
+ if (pixy_init() == 0) { //try to connect to pixy
+ pixy_connected = true;
- pixy_render_full_frame(1,40); //render the pixy video at point (1,40)
-
- //set the servo positions to the coordinates form the touch interrupt
- pixy_rcs_set_position(0,pixy_pos.x);
- pixy_rcs_set_position(1,pixy_pos.y);
- }
+ if (!subMenu) { //we're not coming from a submenu
+ pixy_pos.x = pixy_pos.y = 500; //reset servo positions to center
+ }
+
+ printf("pixy (re)initialized\n");
+ }
+ }
+
+ if (pixy_connected) { //If we are connected (now)
+ pixy_service(); //Handle pending pixy events (e.g. color info retrival)
+
+ pixy_render_full_frame(1, 40); //render the pixy video at point (1,40)
+
+ //set the servo positions to the coordinates form the touch interrupt
+ pixy_rcs_set_position(0, pixy_pos.x);
+ pixy_rcs_set_position(1, pixy_pos.y);
+ }
}
//Declare screen callbacks
static SCREEN_STRUCT screen = {
- enter,
- leave,
- update
+ enter,
+ leave,
+ update
};
-SCREEN_STRUCT* get_screen_photomode() {
- return &screen;
+SCREEN_STRUCT* get_screen_photomode()
+{
+ return &screen;
}
diff --git a/common/app/screen_photomode.h b/common/app/screen_photomode.h
index 19545ac..bdccb4f 100644
--- a/common/app/screen_photomode.h
+++ b/common/app/screen_photomode.h
@@ -1,3 +1,16 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/screen_photomode.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-05-15 timolang@gmail.com 27c09ba Redesigned main menu. Moved stuff from pixytest to a new helper file and to the new "photo mode"-screen.
+*
+**************************************************************************************************************************************/
+
#include "screen.h"
/**
diff --git a/common/app/screen_photomode_save.c b/common/app/screen_photomode_save.c
index e00f8dd..6add4f3 100644
--- a/common/app/screen_photomode_save.c
+++ b/common/app/screen_photomode_save.c
@@ -1,3 +1,17 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/screen_photomode_save.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-05-16 timolang@gmail.com 62006e0 Documented pixy_helper and implemented/finished photo-mode screens! Snap some shots!
+* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
+*
+**************************************************************************************************************************************/
+
#include "screen_photomode_save.h"
#include "filesystem.h"
#include "button.h"
@@ -13,8 +27,9 @@ static BUTTON_STRUCT b_back; //Button to navigate back
static TOUCH_AREA_STRUCT a_area; //Touch area to select the save-file
//Callback for when the user presses the "back" button
-static void b_back_cb(void* button) {
- gui_screen_back();
+static void b_back_cb(void* button)
+{
+ gui_screen_back();
}
static int num_files_ok; //number of files into which we can write the image (size, flags ok)
@@ -24,46 +39,51 @@ static int liststart; //The y-Coordinate of the Start of the File-List
static const char* picked_file; //The filename picked by the user, to save the image to
//Linked list structure to save all files which are suitable for saving.
-typedef struct FILE_LIST_ENTRY_S{
- char* filename; //Name of the file
- struct FILE_LIST_ENTRY_S* next; //Pointer to the next entry in the list or NULL
+typedef struct FILE_LIST_ENTRY_S {
+ char* filename; //Name of the file
+ struct FILE_LIST_ENTRY_S* next; //Pointer to the next entry in the list or NULL
} FILE_LIST_ENTRY;
static FILE_LIST_ENTRY* files_ok; //Pointer to the head of the list
//Callback for when the user selects a file to save the image into
-static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction) {
+static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction)
+{
- int y = touch_get_last_point().y-liststart; //Calculate the y-Coordinate of the touch point relative to the start of the file-list
- int elem = y/fontheight; //Calculate the file index
- if(elem<0 | elem>= num_files_ok) return; //Check if the file index is valid (0,1,..,num_files_ok-1)
+ int y = touch_get_last_point().y - liststart; //Calculate the y-Coordinate of the touch point relative to the start of the file-list
+ int elem = y / fontheight; //Calculate the file index
- //Search for the corresponding entry in the linked list
- FILE_LIST_ENTRY* current_entry = files_ok; //Start walking through the list, starting by the head of the list
- for(int i=0; inext; //traverse to the next file
- }
+ if (elem < 0 | elem >= num_files_ok) {
+ return; //Check if the file index is valid (0,1,..,num_files_ok-1)
+ }
- picked_file = current_entry->filename; //save the picked filename. It will be used by the statemachine in the main loop
- touch_unregister_area(&a_area); //unregister the touch area, we no longer need it. No more interrupts will be fired.
- state=saving; //Change the state of the statemachine
+ //Search for the corresponding entry in the linked list
+ FILE_LIST_ENTRY* current_entry = files_ok; //Start walking through the list, starting by the head of the list
+
+ for (int i = 0; i < elem; i++) { //Until we have reached the file (index)
+ current_entry = current_entry->next; //traverse to the next file
+ }
+
+ picked_file = current_entry->filename; //save the picked filename. It will be used by the statemachine in the main loop
+ touch_unregister_area(&a_area); //unregister the touch area, we no longer need it. No more interrupts will be fired.
+ state = saving; //Change the state of the statemachine
}
//Text-Lines to show if we have no matching files (num_files_ok==0)
static const char* nomatch_text [] = {
- "Due to limitations of the filesystem",
- "implementation you can only write to",
- "existing files.",
- "",
- "The files need to have a .bmp",
- "extension and must be at least",
- "189410 bytes (185kb) large.",
- "Unfortunately there were no such",
- "files found in the root directory.",
- "",
- "Please create some files and come",
- "back again.",
- NULL
+ "Due to limitations of the filesystem",
+ "implementation you can only write to",
+ "existing files.",
+ "",
+ "The files need to have a .bmp",
+ "extension and must be at least",
+ "189410 bytes (185kb) large.",
+ "Unfortunately there were no such",
+ "files found in the root directory.",
+ "",
+ "Please create some files and come",
+ "back again.",
+ NULL
};
@@ -71,231 +91,251 @@ static const char* nomatch_text [] = {
//This header has been taken from a white bitmap saved with gimp.
//Wikipedia has a pretty good description on the header: http://de.wikipedia.org/wiki/Windows_Bitmap
static unsigned char bmpheader_data[0x7A] = {
- 0x42, 0x4d, 0xe2, 0xe3, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x00,
- 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00, 0xc6, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xe3,
- 0x02, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00
+ 0x42, 0x4d, 0xe2, 0xe3, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x00,
+ 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00, 0xc6, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xe3,
+ 0x02, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00
};
//Callback for when the screen is entered/loaded
-static void enter(void* screen) {
- tft_clear(WHITE);
+static void enter(void* screen)
+{
+ tft_clear(WHITE);
- #define X_OFS 5
+#define X_OFS 5
- //Back button
- b_back.base.x1=X_OFS; //Start X of Button
- b_back.base.y1=210; //Start Y of Button
- b_back.base.x2=AUTO; //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)
+ //Back button
+ b_back.base.x1 = X_OFS; //Start X of Button
+ b_back.base.y1 = 210; //Start Y of Button
+ b_back.base.x2 = AUTO; //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)
- state =init; //Start with the init state
- fontheight = tft_font_height(0)+2; //Save the height of the used font, for fast access
- files_ok = NULL; //initialize the linked list with 0 elements
- num_files_ok = 0; //we have zero! elements
+ state = init; //Start with the init state
+ fontheight = tft_font_height(0) + 2; //Save the height of the used font, for fast access
+ files_ok = NULL; //initialize the linked list with 0 elements
+ num_files_ok = 0; //we have zero! elements
}
//Callback for when the screen should be updated
//This is the main loop of the screen. This method will be called repeatedly
-static void update(void* screen) {
- switch(state) {
- case init: //Init State: The user just entered the screen
- {
- DIRECTORY_STRUCT* dir = filesystem_dir_open("."); //open root directory
- if(dir==NULL) { //error while opening root directory
- tft_print_line(X_OFS,5,BLACK,TRANSPARENT,0,"Error accessing Filesystem");
- state=error;
- break;
- }
+static void update(void* screen)
+{
+ switch (state) {
+ case init: { //Init State: The user just entered the screen
+ DIRECTORY_STRUCT* dir = filesystem_dir_open("."); //open root directory
- bool nomatch= true; //whether or not we have zero files which are suitable for saving
+ if (dir == NULL) { //error while opening root directory
+ tft_print_line(X_OFS, 5, BLACK, TRANSPARENT, 0, "Error accessing Filesystem");
+ state = error;
+ break;
+ }
- for(int i=0; inum_files; i++) { //walk through all files in the directory
- FILE_STRUCT* file = &(dir->files[i]); //Pointer to the current file/subdirectory
+ bool nomatch = true; //whether or not we have zero files which are suitable for saving
- //Ignore directories, archives, hidden files, system files and files we cannot write to
- if(file->fattrib&(F_SYS|F_HID|F_ARC|F_DIR|F_RDO)) continue;
+ for (int i = 0; i < dir->num_files; i++) { //walk through all files in the directory
+ FILE_STRUCT* file = &(dir->files[i]); //Pointer to the current file/subdirectory
- //ignore files which are not large enough
- if(file->fsize<189410) continue; //size taken from an example bitmap (318x198x24)
+ //Ignore directories, archives, hidden files, system files and files we cannot write to
+ if (file->fattrib & (F_SYS | F_HID | F_ARC | F_DIR | F_RDO)) {
+ continue;
+ }
- nomatch=false; //at least one file matches
- break;
- }
+ //ignore files which are not large enough
+ if (file->fsize < 189410) {
+ continue; //size taken from an example bitmap (318x198x24)
+ }
- if(nomatch) { //not one file is suitable for writing
- int y=5; //y-Coordinate where to start writing the error text
- int i=0;
- while(nomatch_text[i]!=NULL) { //for every line in the big error array
- //Write the line's text and go to the next line
- tft_print_line(X_OFS,y+i*fontheight,BLACK,TRANSPARENT,0,nomatch_text[i]);
- i++;
- }
- state = error;
- } else { //we have a least one suitable file
- state = showlist;
- }
+ nomatch = false; //at least one file matches
+ break;
+ }
- filesystem_dir_close(dir); //free directory struct
- }
- break;
+ if (nomatch) { //not one file is suitable for writing
+ int y = 5; //y-Coordinate where to start writing the error text
+ int i = 0;
- case showlist: //Show List State: Where we load and present the suitable file's to the user in a list
- {
- DIRECTORY_STRUCT* dir2 = filesystem_dir_open("."); //Open the directory again
- if(dir2==NULL) return; //Error on opening? This should never happen, since it's handled in the previous state
+ while (nomatch_text[i] != NULL) { //for every line in the big error array
+ //Write the line's text and go to the next line
+ tft_print_line(X_OFS, y + i * fontheight, BLACK, TRANSPARENT, 0, nomatch_text[i]);
+ i++;
+ }
- int y = 5; //y-Coordinate where to start drawing/writing text/list-elements
+ state = error;
+ } else { //we have a least one suitable file
+ state = showlist;
+ }
- tft_print_line(X_OFS,y,BLACK,TRANSPARENT,0,"Pick a file to save the image to");
- y+=fontheight+5;
+ filesystem_dir_close(dir); //free directory struct
+ }
+ break;
- tft_print_line(X_OFS,y,BLUE,TRANSPARENT,0,"Name Modified Size");
- y+=fontheight;
+ case showlist: { //Show List State: Where we load and present the suitable file's to the user in a list
+ DIRECTORY_STRUCT* dir2 = filesystem_dir_open("."); //Open the directory again
- liststart = y; //store the y coordinate of the start of the list away (used in toucharea callback)
- num_files_ok = 0; //we start with 0 matching files
+ if (dir2 == NULL) {
+ return; //Error on opening? This should never happen, since it's handled in the previous state
+ }
- FILE_LIST_ENTRY* current_entry = NULL; //We start with an empty list
- for(int i=0; inum_files && num_files_ok<10; i++) { //go through all the files of the directory, abort if we have 10 matches
- FILE_STRUCT* file = &(dir2->files[i]);
+ int y = 5; //y-Coordinate where to start drawing/writing text/list-elements
- //Ignore directories, archives, hidden files, system files and files we cannot write to
- if(file->fattrib&(F_SYS|F_HID|F_ARC|F_DIR|F_RDO)) continue;
+ tft_print_line(X_OFS, y, BLACK, TRANSPARENT, 0, "Pick a file to save the image to");
+ y += fontheight + 5;
- //ignore files which are not large enough
- if(file->fsize<189410) continue; //size taken from an example bitmap (318x198x24)
+ tft_print_line(X_OFS, y, BLUE, TRANSPARENT, 0, "Name Modified Size");
+ y += fontheight;
- //Print out filename, modified date,time and file size
- tft_print_formatted(X_OFS,y,BLACK,
- TRANSPARENT,0,"%-16s %02u.%02u.%02u %02u:%02u:%02u %u",
- file->fname,
- file->fdate.day,
- file->fdate.month,
- (file->fdate.year+1980)%100,
- file->ftime.hour,
- file->ftime.min,
- file->ftime.sec*2,
- file->fsize);
+ liststart = y; //store the y coordinate of the start of the list away (used in toucharea callback)
+ num_files_ok = 0; //we start with 0 matching files
- if(current_entry==NULL) { //The list is empty
- current_entry = malloc(sizeof(FILE_LIST_ENTRY)); //create new entry
- files_ok = current_entry; //assign it to the list head
- } else { //there's a least one entry in the list
- current_entry->next = malloc(sizeof(FILE_LIST_ENTRY)); //append entry to previous entry
- current_entry = current_entry->next; //newly created entry is the current now.
- }
- current_entry->next = NULL; //we're at the end of the list (for now)
- current_entry->filename = malloc(strlen(file->fname)+1); //allocate space for the filename + zero-termination
- strcpy(current_entry->filename,file->fname); //copy filename (so that we can close the directory after scanning)
+ FILE_LIST_ENTRY* current_entry = NULL; //We start with an empty list
- //since we have found a suitable file we need to increment the position in the list
- num_files_ok++;
- y+=fontheight;
- }
+ for (int i = 0; i < dir2->num_files && num_files_ok < 10; i++) { //go through all the files of the directory, abort if we have 10 matches
+ FILE_STRUCT* file = &(dir2->files[i]);
- //Touch area for file-selection (in the list)
- a_area.hookedActions = PEN_UP; //we're only interested in PEN_UP events
- a_area.x1 = X_OFS; //Left border
- a_area.y1 = liststart; //Start where the list started
- a_area.x2 = 320-X_OFS; //Right border
- a_area.y2 = liststart+fontheight*num_files_ok; //stop at the end of the list
- a_area.callback = touchCB; //execute our callback when PEN_UP occurs
- touch_register_area(&a_area); //register the touch area and receive events from now on
+ //Ignore directories, archives, hidden files, system files and files we cannot write to
+ if (file->fattrib & (F_SYS | F_HID | F_ARC | F_DIR | F_RDO)) {
+ continue;
+ }
- filesystem_dir_close(dir2); //we no longer need the directory struct, since we have our own linked list now
+ //ignore files which are not large enough
+ if (file->fsize < 189410) {
+ continue; //size taken from an example bitmap (318x198x24)
+ }
- state=picking;
- }
- break;
+ //Print out filename, modified date,time and file size
+ tft_print_formatted(X_OFS, y, BLACK,
+ TRANSPARENT, 0, "%-16s %02u.%02u.%02u %02u:%02u:%02u %u",
+ file->fname,
+ file->fdate.day,
+ file->fdate.month,
+ (file->fdate.year + 1980) % 100,
+ file->ftime.hour,
+ file->ftime.min,
+ file->ftime.sec * 2,
+ file->fsize);
- case picking: //Picking State: Where we wait on the users file choice
- pixy_service(); //Handle pending pixy events
- //do nothing and wait on user to pick a file
- break;
+ if (current_entry == NULL) { //The list is empty
+ current_entry = malloc(sizeof(FILE_LIST_ENTRY)); //create new entry
+ files_ok = current_entry; //assign it to the list head
+ } else { //there's a least one entry in the list
+ current_entry->next = malloc(sizeof(FILE_LIST_ENTRY)); //append entry to previous entry
+ current_entry = current_entry->next; //newly created entry is the current now.
+ }
- case saving: //Saving State: Where we save the image to the selected file
- {
- FILE_HANDLE* file = filesystem_file_open(picked_file); //try to open the selected file
- if(file==NULL) { //opening the file failed
- tft_print_formatted(X_OFS,190,BLUE,TRANSPARENT,0,"Could not open %s",picked_file);
- state=error;
- break;
- }
+ current_entry->next = NULL; //we're at the end of the list (for now)
+ current_entry->filename = malloc(strlen(file->fname) + 1); //allocate space for the filename + zero-termination
+ strcpy(current_entry->filename, file->fname); //copy filename (so that we can close the directory after scanning)
- filesystem_file_seek(file,0); //seek to the start of the file (optional?)
- if(filesystem_file_write(file,bmpheader_data,0x7A)!=F_OK) { //Writing the header failed
- tft_print_formatted(X_OFS,190,BLUE,TRANSPARENT,0,"Error while writing to %s",picked_file);
- filesystem_file_close(file);
- state=error;
- break;
- }
+ //since we have found a suitable file we need to increment the position in the list
+ num_files_ok++;
+ y += fontheight;
+ }
- if(pixy_save_full_frame(file)!=0) { //Writing the imagedata failed
- tft_print_formatted(X_OFS,190,BLUE,TRANSPARENT,0,"Error while writing to %s",picked_file);
- filesystem_file_close(file);
- state=error;
- break;
- }
+ //Touch area for file-selection (in the list)
+ a_area.hookedActions = PEN_UP; //we're only interested in PEN_UP events
+ a_area.x1 = X_OFS; //Left border
+ a_area.y1 = liststart; //Start where the list started
+ a_area.x2 = 320 - X_OFS; //Right border
+ a_area.y2 = liststart + fontheight * num_files_ok; //stop at the end of the list
+ a_area.callback = touchCB; //execute our callback when PEN_UP occurs
+ touch_register_area(&a_area); //register the touch area and receive events from now on
- //if we reach this point, we have written all data out successfully
+ filesystem_dir_close(dir2); //we no longer need the directory struct, since we have our own linked list now
- filesystem_file_close(file); //close/finalize the file
- tft_print_formatted(X_OFS,190,BLUE,TRANSPARENT,0,"Image saved to %s",picked_file);
- state = done;
- }
- break;
+ state = picking;
+ }
+ break;
- case error: //Error State: Where we show an error message and leave the user no other choice than to click the backbutton
- case done: //Done State: When saving the file was successful
- pixy_service(); //Handle pending pixy events
- //wait on user to click the back button
- break;
+ case picking: //Picking State: Where we wait on the users file choice
+ pixy_service(); //Handle pending pixy events
+ //do nothing and wait on user to pick a file
+ break;
- }
+ case saving: { //Saving State: Where we save the image to the selected file
+ FILE_HANDLE* file = filesystem_file_open(picked_file); //try to open the selected file
+
+ if (file == NULL) { //opening the file failed
+ tft_print_formatted(X_OFS, 190, BLUE, TRANSPARENT, 0, "Could not open %s", picked_file);
+ state = error;
+ break;
+ }
+
+ filesystem_file_seek(file, 0); //seek to the start of the file (optional?)
+
+ if (filesystem_file_write(file, bmpheader_data, 0x7A) != F_OK) { //Writing the header failed
+ tft_print_formatted(X_OFS, 190, BLUE, TRANSPARENT, 0, "Error while writing to %s", picked_file);
+ filesystem_file_close(file);
+ state = error;
+ break;
+ }
+
+ if (pixy_save_full_frame(file) != 0) { //Writing the imagedata failed
+ tft_print_formatted(X_OFS, 190, BLUE, TRANSPARENT, 0, "Error while writing to %s", picked_file);
+ filesystem_file_close(file);
+ state = error;
+ break;
+ }
+
+ //if we reach this point, we have written all data out successfully
+
+ filesystem_file_close(file); //close/finalize the file
+ tft_print_formatted(X_OFS, 190, BLUE, TRANSPARENT, 0, "Image saved to %s", picked_file);
+ state = done;
+ }
+ break;
+
+ case error: //Error State: Where we show an error message and leave the user no other choice than to click the backbutton
+ case done: //Done State: When saving the file was successful
+ pixy_service(); //Handle pending pixy events
+ //wait on user to click the back button
+ break;
+
+ }
}
//Callback for when the screen is left/unloaded
-static void leave(void* screen) {
- gui_button_remove(&b_back); //Remove/Free the back button
+static void leave(void* screen)
+{
+ gui_button_remove(&b_back); //Remove/Free the back button
- if(state==picking){ //The user left the screen in the "picking"-phase
- touch_unregister_area(&a_area); //remove the touch area (for the list)
- }
+ if (state == picking) { //The user left the screen in the "picking"-phase
+ touch_unregister_area(&a_area); //remove the touch area (for the list)
+ }
- if(state==picking|| state==saving || state==done) { //the user left the screen after we created the linked list
- //Iterate through the linked list and free all resources
- FILE_LIST_ENTRY* current_entry = files_ok; //start with the list head
- while(current_entry!=NULL) { //while we're not at the end
- FILE_LIST_ENTRY* temp = current_entry->next; //save the next pointer because we free the current element on the next line
- free((void*)(current_entry->filename)); //free filename
- free(current_entry); //free element itself
- current_entry= temp; //advance
- }
- }
+ if (state == picking || state == saving || state == done) { //the user left the screen after we created the linked list
+ //Iterate through the linked list and free all resources
+ FILE_LIST_ENTRY* current_entry = files_ok; //start with the list head
+
+ while (current_entry != NULL) { //while we're not at the end
+ FILE_LIST_ENTRY* temp = current_entry->next; //save the next pointer because we free the current element on the next line
+ free((void*)(current_entry->filename)); //free filename
+ free(current_entry); //free element itself
+ current_entry = temp; //advance
+ }
+ }
}
//Declare screen callbacks
static SCREEN_STRUCT screen = {
- enter,
- leave,
- update
+ enter,
+ leave,
+ update
};
-SCREEN_STRUCT* get_screen_photomodesave() {
- return &screen;
+SCREEN_STRUCT* get_screen_photomodesave()
+{
+ return &screen;
}
diff --git a/common/app/screen_photomode_save.h b/common/app/screen_photomode_save.h
index 6f71fa0..5b7814e 100644
--- a/common/app/screen_photomode_save.h
+++ b/common/app/screen_photomode_save.h
@@ -1,3 +1,16 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/screen_photomode_save.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-05-16 timolang@gmail.com 62006e0 Documented pixy_helper and implemented/finished photo-mode screens! Snap some shots!
+*
+**************************************************************************************************************************************/
+
#include "screen.h"
/**
@@ -20,4 +33,3 @@ SCREEN_STRUCT* get_screen_photomodesave();
/*@}*/
/*@}*/
-
diff --git a/common/app/screen_pixytest.c b/common/app/screen_pixytest.c
index 8b7b4cd..b39e718 100644
--- a/common/app/screen_pixytest.c
+++ b/common/app/screen_pixytest.c
@@ -1,3 +1,23 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/screen_pixytest.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
+* 2015-05-02 timolang@gmail.com 3281616 Added some more touch functions. Improved pixy test. Drag the Image around!
+* 2015-05-09 timolang@gmail.com 0b5173e Added reference tracking.
+* 2015-05-15 timolang@gmail.com 27c09ba Redesigned main menu. Moved stuff from pixytest to a new helper file and to the new "photo mode"-screen.
+* 2015-05-25 timolang@gmail.com 6a61769 Reimplemented pixytest screen. Added a lot of Test-Buttons.
+* 2015-06-01 aaron@duckpond.ch caa7b5c Added IRQ for user button, fixed some touchproblems.
+* 2015-06-03 timolang@gmail.com 74aa186 Made pixy_test screen working again. Had to disable pixy_service. Recalibrated initial touch values.
+* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
+*
+**************************************************************************************************************************************/
+
#include "screen_pixytest.h"
#include "button.h"
#include "numupdown.h"
@@ -7,7 +27,7 @@
#include "system.h"
#include "pixy_frame.h"
-static volatile enum {detecting, idle,update_servos, update_ledcolor, update_ledcurrent} state; //Current state of the screen state machine
+static volatile enum {detecting, idle, update_servos, update_ledcolor, update_ledcurrent} state; //Current state of the screen state machine
static BUTTON_STRUCT b_back;
@@ -30,313 +50,328 @@ static uint32_t led_maxcurrent;
static NUMUPDOWN_STRUCT n_led_powerlimit;
-static void b_back_cb(void* button) {
- gui_screen_back();
+static void b_back_cb(void* button)
+{
+ gui_screen_back();
}
-static void b_servos_center_cb(void* button) {
- if(state==idle) {
- servo_x=500;
- servo_y=500;
- state=update_servos;
- }
+static void b_servos_center_cb(void* button)
+{
+ if (state == idle) {
+ servo_x = 500;
+ servo_y = 500;
+ state = update_servos;
+ }
}
-static void b_servos_topleft_cb(void* button) {
- if(state==idle) {
- servo_x=0;
- servo_y=0;
- state=update_servos;
- }
+static void b_servos_topleft_cb(void* button)
+{
+ if (state == idle) {
+ servo_x = 0;
+ servo_y = 0;
+ state = update_servos;
+ }
}
-static void b_servos_topright_cb(void* button) {
- if(state==idle) {
- servo_x=1000;
- servo_y=0;
- state=update_servos;
- }
+static void b_servos_topright_cb(void* button)
+{
+ if (state == idle) {
+ servo_x = 1000;
+ servo_y = 0;
+ state = update_servos;
+ }
}
-static void b_servos_bottomleft_cb(void* button) {
- if(state==idle) {
- servo_x=0;
- servo_y=1000;
- state=update_servos;
- }
+static void b_servos_bottomleft_cb(void* button)
+{
+ if (state == idle) {
+ servo_x = 0;
+ servo_y = 1000;
+ state = update_servos;
+ }
}
-static void b_servos_bottomright_cb(void* button) {
- if(state==idle) {
- servo_x=1000;
- servo_y=1000;
- state=update_servos;
- }
+static void b_servos_bottomright_cb(void* button)
+{
+ if (state == idle) {
+ servo_x = 1000;
+ servo_y = 1000;
+ state = update_servos;
+ }
}
-static void b_led_off_cb(void* button) {
- if(state==idle) {
- led_color=0x000000;
- state=update_ledcolor;
- }
+static void b_led_off_cb(void* button)
+{
+ if (state == idle) {
+ led_color = 0x000000;
+ state = update_ledcolor;
+ }
}
-static void b_led_white_cb(void* button) {
- if(state==idle) {
- led_color=0xFFFFFF;
- state=update_ledcolor;
- }
+static void b_led_white_cb(void* button)
+{
+ if (state == idle) {
+ led_color = 0xFFFFFF;
+ state = update_ledcolor;
+ }
}
-static void b_led_red_cb(void* button) {
- if(state==idle) {
- led_color=0xFF0000;
- state=update_ledcolor;
- }
+static void b_led_red_cb(void* button)
+{
+ if (state == idle) {
+ led_color = 0xFF0000;
+ state = update_ledcolor;
+ }
}
-static void b_led_green_cb(void* button) {
- if(state==idle) {
- led_color=0x00FF00;
- state=update_ledcolor;
- }
+static void b_led_green_cb(void* button)
+{
+ if (state == idle) {
+ led_color = 0x00FF00;
+ state = update_ledcolor;
+ }
}
-static void b_led_blue_cb(void* button) {
- if(state==idle) {
- led_color=0x0000FF;
- state=update_ledcolor;
- }
+static void b_led_blue_cb(void* button)
+{
+ if (state == idle) {
+ led_color = 0x0000FF;
+ state = update_ledcolor;
+ }
}
-static void n_led_powerlimit_cb(void* numupdown, int16_t value) {
- if(state==idle) {
- led_maxcurrent=value;
- state=update_ledcurrent;
- }
+static void n_led_powerlimit_cb(void* numupdown, int16_t value)
+{
+ if (state == idle) {
+ led_maxcurrent = value;
+ state = update_ledcurrent;
+ }
}
-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; //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)
+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; //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)
- //Servo stuff
- #define SERVO_BUTTON_Y 10
- #define SERVO_BUTTON_SPACING 5
- tft_print_line(5,SERVO_BUTTON_Y,BLACK,TRANSPARENT,0,"Servos:");
+ //Servo stuff
+#define SERVO_BUTTON_Y 10
+#define SERVO_BUTTON_SPACING 5
+ tft_print_line(5, SERVO_BUTTON_Y, BLACK, TRANSPARENT, 0, "Servos:");
- b_servos_center.base.x1=55;
- b_servos_center.base.y1=SERVO_BUTTON_Y-3;
- b_servos_center.base.x2=AUTO;
- b_servos_center.base.y2=AUTO;
- b_servos_center.txtcolor=WHITE;
- b_servos_center.bgcolor=HEX(0xAE1010);
- b_servos_center.font=0;
- b_servos_center.text="Center";
- b_servos_center.callback=b_servos_center_cb;
- gui_button_add(&b_servos_center);
+ b_servos_center.base.x1 = 55;
+ b_servos_center.base.y1 = SERVO_BUTTON_Y - 3;
+ b_servos_center.base.x2 = AUTO;
+ b_servos_center.base.y2 = AUTO;
+ b_servos_center.txtcolor = WHITE;
+ b_servos_center.bgcolor = HEX(0xAE1010);
+ b_servos_center.font = 0;
+ b_servos_center.text = "Center";
+ b_servos_center.callback = b_servos_center_cb;
+ gui_button_add(&b_servos_center);
- b_servos_topleft.base.x1=b_servos_center.base.x2+SERVO_BUTTON_SPACING;
- b_servos_topleft.base.y1=SERVO_BUTTON_Y-3;
- b_servos_topleft.base.x2=AUTO;
- b_servos_topleft.base.y2=AUTO;
- b_servos_topleft.txtcolor=WHITE;
- b_servos_topleft.bgcolor=HEX(0xAE1010);
- b_servos_topleft.font=0;
- b_servos_topleft.text="ToLe";
- b_servos_topleft.callback=b_servos_topleft_cb;
- gui_button_add(&b_servos_topleft);
+ b_servos_topleft.base.x1 = b_servos_center.base.x2 + SERVO_BUTTON_SPACING;
+ b_servos_topleft.base.y1 = SERVO_BUTTON_Y - 3;
+ b_servos_topleft.base.x2 = AUTO;
+ b_servos_topleft.base.y2 = AUTO;
+ b_servos_topleft.txtcolor = WHITE;
+ b_servos_topleft.bgcolor = HEX(0xAE1010);
+ b_servos_topleft.font = 0;
+ b_servos_topleft.text = "ToLe";
+ b_servos_topleft.callback = b_servos_topleft_cb;
+ gui_button_add(&b_servos_topleft);
- b_servos_topright.base.x1=b_servos_topleft.base.x2+SERVO_BUTTON_SPACING;
- b_servos_topright.base.y1=SERVO_BUTTON_Y-3;
- b_servos_topright.base.x2=AUTO;
- b_servos_topright.base.y2=AUTO;
- b_servos_topright.txtcolor=WHITE;
- b_servos_topright.bgcolor=HEX(0xAE1010);
- b_servos_topright.font=0;
- b_servos_topright.text="ToRi";
- b_servos_topright.callback=b_servos_topright_cb;
- gui_button_add(&b_servos_topright);
+ b_servos_topright.base.x1 = b_servos_topleft.base.x2 + SERVO_BUTTON_SPACING;
+ b_servos_topright.base.y1 = SERVO_BUTTON_Y - 3;
+ b_servos_topright.base.x2 = AUTO;
+ b_servos_topright.base.y2 = AUTO;
+ b_servos_topright.txtcolor = WHITE;
+ b_servos_topright.bgcolor = HEX(0xAE1010);
+ b_servos_topright.font = 0;
+ b_servos_topright.text = "ToRi";
+ b_servos_topright.callback = b_servos_topright_cb;
+ gui_button_add(&b_servos_topright);
- b_servos_bottomleft.base.x1=b_servos_topright.base.x2+SERVO_BUTTON_SPACING;
- b_servos_bottomleft.base.y1=SERVO_BUTTON_Y-3;
- b_servos_bottomleft.base.x2=AUTO;
- b_servos_bottomleft.base.y2=AUTO;
- b_servos_bottomleft.txtcolor=WHITE;
- b_servos_bottomleft.bgcolor=HEX(0xAE1010);
- b_servos_bottomleft.font=0;
- b_servos_bottomleft.text="BoLe";
- b_servos_bottomleft.callback=b_servos_bottomleft_cb;
- gui_button_add(&b_servos_bottomleft);
+ b_servos_bottomleft.base.x1 = b_servos_topright.base.x2 + SERVO_BUTTON_SPACING;
+ b_servos_bottomleft.base.y1 = SERVO_BUTTON_Y - 3;
+ b_servos_bottomleft.base.x2 = AUTO;
+ b_servos_bottomleft.base.y2 = AUTO;
+ b_servos_bottomleft.txtcolor = WHITE;
+ b_servos_bottomleft.bgcolor = HEX(0xAE1010);
+ b_servos_bottomleft.font = 0;
+ b_servos_bottomleft.text = "BoLe";
+ b_servos_bottomleft.callback = b_servos_bottomleft_cb;
+ gui_button_add(&b_servos_bottomleft);
- b_servos_bottomright.base.x1=b_servos_bottomleft.base.x2+SERVO_BUTTON_SPACING;
- b_servos_bottomright.base.y1=SERVO_BUTTON_Y-3;
- b_servos_bottomright.base.x2=AUTO;
- b_servos_bottomright.base.y2=AUTO;
- b_servos_bottomright.txtcolor=WHITE;
- b_servos_bottomright.bgcolor=HEX(0xAE1010);
- b_servos_bottomright.font=0;
- b_servos_bottomright.text="BoRi";
- b_servos_bottomright.callback=b_servos_bottomright_cb;
- gui_button_add(&b_servos_bottomright);
+ b_servos_bottomright.base.x1 = b_servos_bottomleft.base.x2 + SERVO_BUTTON_SPACING;
+ b_servos_bottomright.base.y1 = SERVO_BUTTON_Y - 3;
+ b_servos_bottomright.base.x2 = AUTO;
+ b_servos_bottomright.base.y2 = AUTO;
+ b_servos_bottomright.txtcolor = WHITE;
+ b_servos_bottomright.bgcolor = HEX(0xAE1010);
+ b_servos_bottomright.font = 0;
+ b_servos_bottomright.text = "BoRi";
+ b_servos_bottomright.callback = b_servos_bottomright_cb;
+ gui_button_add(&b_servos_bottomright);
- //Led Color stuff
- #define LED_COLOR_BUTTON_Y 35
- #define LED_COLOR_BUTTON_SPACING 5
- tft_print_line(5,LED_COLOR_BUTTON_Y,BLACK,TRANSPARENT,0,"Led Color:");
+ //Led Color stuff
+#define LED_COLOR_BUTTON_Y 35
+#define LED_COLOR_BUTTON_SPACING 5
+ tft_print_line(5, LED_COLOR_BUTTON_Y, BLACK, TRANSPARENT, 0, "Led Color:");
- b_led_off.base.x1=85;
- b_led_off.base.y1=LED_COLOR_BUTTON_Y-3;
- b_led_off.base.x2=AUTO;
- b_led_off.base.y2=AUTO;
- b_led_off.txtcolor=WHITE;
- b_led_off.bgcolor=BLACK;
- b_led_off.font=0;
- b_led_off.text="Off";
- b_led_off.callback=b_led_off_cb;
- gui_button_add(&b_led_off);
+ b_led_off.base.x1 = 85;
+ b_led_off.base.y1 = LED_COLOR_BUTTON_Y - 3;
+ b_led_off.base.x2 = AUTO;
+ b_led_off.base.y2 = AUTO;
+ b_led_off.txtcolor = WHITE;
+ b_led_off.bgcolor = BLACK;
+ b_led_off.font = 0;
+ b_led_off.text = "Off";
+ b_led_off.callback = b_led_off_cb;
+ gui_button_add(&b_led_off);
- b_led_white.base.x1=b_led_off.base.x2+LED_COLOR_BUTTON_SPACING;
- b_led_white.base.y1=LED_COLOR_BUTTON_Y-3;
- b_led_white.base.x2=AUTO;
- b_led_white.base.y2=AUTO;
- b_led_white.txtcolor=BLACK;
- b_led_white.bgcolor=HEX(0xEEEEEE);
- b_led_white.font=0;
- b_led_white.text="White";
- b_led_white.callback=b_led_white_cb;
- gui_button_add(&b_led_white);
+ b_led_white.base.x1 = b_led_off.base.x2 + LED_COLOR_BUTTON_SPACING;
+ b_led_white.base.y1 = LED_COLOR_BUTTON_Y - 3;
+ b_led_white.base.x2 = AUTO;
+ b_led_white.base.y2 = AUTO;
+ b_led_white.txtcolor = BLACK;
+ b_led_white.bgcolor = HEX(0xEEEEEE);
+ b_led_white.font = 0;
+ b_led_white.text = "White";
+ b_led_white.callback = b_led_white_cb;
+ gui_button_add(&b_led_white);
- b_led_red.base.x1=b_led_white.base.x2+LED_COLOR_BUTTON_SPACING;
- b_led_red.base.y1=LED_COLOR_BUTTON_Y-3;
- b_led_red.base.x2=AUTO;
- b_led_red.base.y2=AUTO;
- b_led_red.txtcolor=WHITE;
- b_led_red.bgcolor=HEX(0xEE0000);
- b_led_red.font=0;
- b_led_red.text="Red";
- b_led_red.callback=b_led_red_cb;
- gui_button_add(&b_led_red);
+ b_led_red.base.x1 = b_led_white.base.x2 + LED_COLOR_BUTTON_SPACING;
+ b_led_red.base.y1 = LED_COLOR_BUTTON_Y - 3;
+ b_led_red.base.x2 = AUTO;
+ b_led_red.base.y2 = AUTO;
+ b_led_red.txtcolor = WHITE;
+ b_led_red.bgcolor = HEX(0xEE0000);
+ b_led_red.font = 0;
+ b_led_red.text = "Red";
+ b_led_red.callback = b_led_red_cb;
+ gui_button_add(&b_led_red);
- b_led_green.base.x1=b_led_red.base.x2+LED_COLOR_BUTTON_SPACING;
- b_led_green.base.y1=LED_COLOR_BUTTON_Y-3;
- b_led_green.base.x2=AUTO;
- b_led_green.base.y2=AUTO;
- b_led_green.txtcolor=WHITE;
- b_led_green.bgcolor=HEX(0x00EE00);
- b_led_green.font=0;
- b_led_green.text="Green";
- b_led_green.callback=b_led_green_cb;
- gui_button_add(&b_led_green);
+ b_led_green.base.x1 = b_led_red.base.x2 + LED_COLOR_BUTTON_SPACING;
+ b_led_green.base.y1 = LED_COLOR_BUTTON_Y - 3;
+ b_led_green.base.x2 = AUTO;
+ b_led_green.base.y2 = AUTO;
+ b_led_green.txtcolor = WHITE;
+ b_led_green.bgcolor = HEX(0x00EE00);
+ b_led_green.font = 0;
+ b_led_green.text = "Green";
+ b_led_green.callback = b_led_green_cb;
+ gui_button_add(&b_led_green);
- b_led_blue.base.x1=b_led_green.base.x2+LED_COLOR_BUTTON_SPACING;
- b_led_blue.base.y1=LED_COLOR_BUTTON_Y-3;
- b_led_blue.base.x2=AUTO;
- b_led_blue.base.y2=AUTO;
- b_led_blue.txtcolor=WHITE;
- b_led_blue.bgcolor=HEX(0x0000EE);
- b_led_blue.font=0;
- b_led_blue.text="Blue";
- b_led_blue.callback=b_led_blue_cb;
- gui_button_add(&b_led_blue);
+ b_led_blue.base.x1 = b_led_green.base.x2 + LED_COLOR_BUTTON_SPACING;
+ b_led_blue.base.y1 = LED_COLOR_BUTTON_Y - 3;
+ b_led_blue.base.x2 = AUTO;
+ b_led_blue.base.y2 = AUTO;
+ b_led_blue.txtcolor = WHITE;
+ b_led_blue.bgcolor = HEX(0x0000EE);
+ b_led_blue.font = 0;
+ b_led_blue.text = "Blue";
+ b_led_blue.callback = b_led_blue_cb;
+ gui_button_add(&b_led_blue);
- //Led MaxPower stuff
- #define LED_POWER_BUTTON_Y 70
- tft_print_line(5,LED_POWER_BUTTON_Y,BLACK,TRANSPARENT,0,"Led Maximum Current:");
+ //Led MaxPower stuff
+#define LED_POWER_BUTTON_Y 70
+ tft_print_line(5, LED_POWER_BUTTON_Y, BLACK, TRANSPARENT, 0, "Led Maximum Current:");
- //Num up down test
- n_led_powerlimit.x=160;
- n_led_powerlimit.y=LED_POWER_BUTTON_Y-7;
- n_led_powerlimit.fgcolor=WHITE;
- n_led_powerlimit.value = 10;
- n_led_powerlimit.max=40;
- n_led_powerlimit.min =0;
- n_led_powerlimit.callback=n_led_powerlimit_cb;
- gui_numupdown_add(&n_led_powerlimit);
+ //Num up down test
+ n_led_powerlimit.x = 160;
+ n_led_powerlimit.y = LED_POWER_BUTTON_Y - 7;
+ n_led_powerlimit.fgcolor = WHITE;
+ n_led_powerlimit.value = 10;
+ n_led_powerlimit.max = 40;
+ n_led_powerlimit.min = 0;
+ n_led_powerlimit.callback = n_led_powerlimit_cb;
+ gui_numupdown_add(&n_led_powerlimit);
- state=detecting;
+ state = detecting;
}
-static void leave(void* screen) {
- gui_button_remove(&b_back);
- gui_button_remove(&b_servos_center);
- gui_button_remove(&b_servos_topleft);
- gui_button_remove(&b_servos_topright);
- gui_button_remove(&b_servos_bottomleft);
- gui_button_remove(&b_servos_bottomright);
- gui_button_remove(&b_led_off);
- gui_button_remove(&b_led_white);
- gui_button_remove(&b_led_red);
- gui_button_remove(&b_led_green);
- gui_button_remove(&b_led_blue);
- gui_numupdown_remove(&n_led_powerlimit);
+static void leave(void* screen)
+{
+ gui_button_remove(&b_back);
+ gui_button_remove(&b_servos_center);
+ gui_button_remove(&b_servos_topleft);
+ gui_button_remove(&b_servos_topright);
+ gui_button_remove(&b_servos_bottomleft);
+ gui_button_remove(&b_servos_bottomright);
+ gui_button_remove(&b_led_off);
+ gui_button_remove(&b_led_white);
+ gui_button_remove(&b_led_red);
+ gui_button_remove(&b_led_green);
+ gui_button_remove(&b_led_blue);
+ gui_numupdown_remove(&n_led_powerlimit);
}
-static void update(void* screen) {
- switch(state) {
- case detecting: //Detecting State: Where we try to connect to the pixy
- if(pixy_init()==0) { //Pixy connection ok
- int32_t response;
- int return_value;
- return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);
- pixy_led_set_max_current(10);
+static void update(void* screen)
+{
+ switch (state) {
+ case detecting: //Detecting State: Where we try to connect to the pixy
+ if (pixy_init() == 0) { //Pixy connection ok
+ int32_t response;
+ int return_value;
+ return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);
+ pixy_led_set_max_current(10);
- state = idle; //Go to next state
- }
- break;
- case idle:
- pixy_service();
- break;
- case update_servos:
- pixy_rcs_set_position(0,servo_x);
- pixy_rcs_set_position(1,servo_y);
- state = idle;
- break;
+ state = idle; //Go to next state
+ }
- case update_ledcolor:
- {
- int32_t response;
- int return_value;
- return_value = pixy_command("led_set", INT32(led_color), END_OUT_ARGS, &response, END_IN_ARGS);
- state = idle;
- }
- break;
+ break;
- case update_ledcurrent:
- pixy_led_set_max_current(led_maxcurrent);
- state = idle;
- break;
- }
+ case idle:
+ pixy_service();
+ break;
+
+ case update_servos:
+ pixy_rcs_set_position(0, servo_x);
+ pixy_rcs_set_position(1, servo_y);
+ state = idle;
+ break;
+
+ case update_ledcolor: {
+ int32_t response;
+ int return_value;
+ return_value = pixy_command("led_set", INT32(led_color), END_OUT_ARGS, &response, END_IN_ARGS);
+ state = idle;
+ }
+ break;
+
+ case update_ledcurrent:
+ pixy_led_set_max_current(led_maxcurrent);
+ state = idle;
+ break;
+ }
}
static SCREEN_STRUCT screen = {
- enter,
- leave,
- update
+ enter,
+ leave,
+ update
};
-SCREEN_STRUCT* get_screen_pixytest() {
- return &screen;
+SCREEN_STRUCT* get_screen_pixytest()
+{
+ return &screen;
}
-
-
-
diff --git a/common/app/screen_pixytest.h b/common/app/screen_pixytest.h
index b92df49..b711d0b 100644
--- a/common/app/screen_pixytest.h
+++ b/common/app/screen_pixytest.h
@@ -1,3 +1,18 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/screen_pixytest.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
+* 2015-05-10 timolang@gmail.com 21edc56 Added doxyfile (doxygen) for the common folder. Started with doxygen comments for app and tft module.
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+*
+**************************************************************************************************************************************/
+
#include "screen.h"
/**
diff --git a/common/app/screen_tracking.c b/common/app/screen_tracking.c
index cf6af59..974d4e7 100644
--- a/common/app/screen_tracking.c
+++ b/common/app/screen_tracking.c
@@ -1,3 +1,22 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/screen_tracking.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-05-16 timolang@gmail.com e46314b Added Tracking Screen and implemented "Reference Tracking" and "Color Region Selection"
+* 2015-05-25 timolang@gmail.com 8088014 Updated Tracking Screen so that the implementations are separated into different method groups.
+* 2015-06-06 aaron@duckpond.ch 8c264c2 Comment refactoring, updated PID values
+* 2015-06-06 aaron@duckpond.ch a04cda9 Refactured comments and implemented a bugfix for the PID controller
+* 2015-06-07 aaron@duckpond.ch 802d3df Fixed pid controller and refactored code
+* 2015-06-07 aaron@duckpond.ch 3d98ca9 Minor changes
+* 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
+*
+**************************************************************************************************************************************/
+
#include "screen_tracking.h"
#include "pixy_control.h"
#include "button.h"
@@ -14,14 +33,16 @@ static CHECKBOX_STRUCT c_frame_toggle; //Checkbox to toggle video data on/off
static TOUCH_AREA_STRUCT a_area; //Touch area for the color region selection
//Callback for when the user presses the "back" button
-static void b_back_cb(void* button) {
- gui_screen_back(); //navigate back to the previous screen
+static void b_back_cb(void* button)
+{
+ gui_screen_back(); //navigate back to the previous screen
}
static volatile bool frame_visible = false; //Whether or not the video data should be displayed
-static void c_frame_toggle_cb(void *checkbox, bool checked) {
- frame_visible=checked; //Set the visibility of the frame to the checked state of the checkbox
- //Frame will be drawn in the main loop below
+static void c_frame_toggle_cb(void* checkbox, bool checked)
+{
+ frame_visible = checked; //Set the visibility of the frame to the checked state of the checkbox
+ //Frame will be drawn in the main loop below
}
static enum {detecting, init, tracking, preselecting, abortselecting, selecting, selected, error} state; //Current state of the screen state machine
@@ -31,12 +52,13 @@ static POINT_STRUCT point2; //End point of the rectangle selected by the user (c
static bool point1_valid; //Whether or not we have a valid first point
//Callback for when the user presses the "select color" button
-static void b_select_cb(void* button) {
- if(state==selecting) { //we're currently selecting a color region
- state = abortselecting; //Abort selecting!!
- } else if (state==tracking) { //we're currently watching the tracking
- state = preselecting; //start selecting
- }
+static void b_select_cb(void* button)
+{
+ if (state == selecting) { //we're currently selecting a color region
+ state = abortselecting; //Abort selecting!!
+ } else if (state == tracking) { //we're currently watching the tracking
+ state = preselecting; //start selecting
+ }
}
//Video Region properties
@@ -50,34 +72,38 @@ static void b_select_cb(void* button) {
//Callback for when the user touches the frame area to select a color region.
//Note: It doesn't matter in which direction the user draws the rectangle, we'll normalize the coordinates later
-static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction) {
- POINT_STRUCT p = touch_get_last_point();
- switch(triggeredAction) {
- case PEN_DOWN: //The user just put down the pen
- point1.x = p.x-FRAME_START_X; //Calculate x-Coordinate relative to frame start
- point1.y = p.y-FRAME_START_Y; //Calculate y-Coordinate relative to frame start
- point1_valid= true; //The point1 is now valid
- break;
- case PEN_UP: //The user took the pen away
- if(point1_valid) { //only execute if point1 is valid
- point2.x = p.x-FRAME_START_X; //Calculate x-Coordinate relative to frame start
- point2.y = p.y-FRAME_START_Y; //Calculate y-Coordinate relative to frame start
- state = selected;
- }
- break;
- }
+static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction)
+{
+ POINT_STRUCT p = touch_get_last_point();
+
+ switch (triggeredAction) {
+ case PEN_DOWN: //The user just put down the pen
+ point1.x = p.x - FRAME_START_X; //Calculate x-Coordinate relative to frame start
+ point1.y = p.y - FRAME_START_Y; //Calculate y-Coordinate relative to frame start
+ point1_valid = true; //The point1 is now valid
+ break;
+
+ case PEN_UP: //The user took the pen away
+ if (point1_valid) { //only execute if point1 is valid
+ point2.x = p.x - FRAME_START_X; //Calculate x-Coordinate relative to frame start
+ point2.y = p.y - FRAME_START_Y; //Calculate y-Coordinate relative to frame start
+ state = selected;
+ }
+
+ break;
+ }
}
//Prototype for tracking start/stop methods
typedef void (*TRACKING_VOID_CALLBACK)(void* tracking_config);
//Prototype for tracking update method
-typedef void (*TRACKING_BLOCK_CALLBACK)(void* tracking_config, struct Block* blocks, int num_blocks );
+typedef void (*TRACKING_BLOCK_CALLBACK)(void* tracking_config, struct Block* blocks, int num_blocks);
//Structure to save callbacks and settings of a tracking implementation
typedef struct {
- TRACKING_VOID_CALLBACK start;
- TRACKING_VOID_CALLBACK stop;
- TRACKING_BLOCK_CALLBACK update;
+ TRACKING_VOID_CALLBACK start;
+ TRACKING_VOID_CALLBACK stop;
+ TRACKING_BLOCK_CALLBACK update;
} TRACKING_CONFIG_STRUCT;
//Methods for our tracking implementation ahead
@@ -85,45 +111,48 @@ static int16_t servo_x = 0;
static int16_t servo_y = 0;
//Method/Callback to start our tracking
-void tracking_our_start(void* tracking_config) {
- //Activate pixy's data send program
- int32_t response;
- int return_value;
+void tracking_our_start(void* tracking_config)
+{
+ //Activate pixy's data send program
+ int32_t response;
+ int return_value;
servo_x = servo_y = 500; // set a default value of 500
- pixy_rcs_set_position(0, servo_x); // set default
+ pixy_rcs_set_position(0, servo_x); // set default
pixy_rcs_set_position(1, servo_y); // set default
- return_value = pixy_command("runprog", INT8(0), END_OUT_ARGS, &response, END_IN_ARGS);
+ return_value = pixy_command("runprog", INT8(0), END_OUT_ARGS, &response, END_IN_ARGS);
}
//Method/Callback to stop our tracking
-void tracking_our_stop(void* tracking_config) {
- //Stop pixy's data send programm
- int32_t response;
- int return_value;
- return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);
+void tracking_our_stop(void* tracking_config)
+{
+ //Stop pixy's data send programm
+ int32_t response;
+ int return_value;
+ return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);
}
//Method/Callback to calculate one step of our tracking
-void tracking_our_update(void* tracking_config, struct Block* blocks, int num_blocks) {
+void tracking_our_update(void* tracking_config, struct Block* blocks, int num_blocks)
+{
- if(num_blocks <= 0){ // Check if there are blocks available
+ if (num_blocks <= 0) { // Check if there are blocks available
return; // When there are none, do nothing
}
-
+
uint16_t x = blocks[0].x; // Get x coordinate of the biggest object
uint16_t y = blocks[0].y; // Get y coordinate of the biggest object
- int16_t xset = 0;
+ int16_t xset = 0;
int16_t yset = 0;
xset = (servo_x + pixy_PID_X((FRAME_WIDTH / 2), x)); // calculate the PID output for x
yset = (servo_y - pixy_PID_Y((FRAME_HEIGHT / 2), y)); // calculate the PID output for y
-
+
xset = (xset < 0) ? 0 : xset; // x lower boundary check
xset = (xset > 1000) ? 1000 : xset; // x upper boundary check
-
+
yset = (yset < 0) ? 0 : yset; // y lower boundary check
yset = (yset > 1000) ? 1000 : yset; // y upper boundary check
@@ -136,245 +165,257 @@ void tracking_our_update(void* tracking_config, struct Block* blocks, int num_bl
//Variable which stores all the callbacks and settings for our tracking implementation
static TRACKING_CONFIG_STRUCT tracking_our = {
- tracking_our_start,
- tracking_our_stop,
- tracking_our_update
+ tracking_our_start,
+ tracking_our_stop,
+ tracking_our_update
};
//Methods for reference tracking implementation ahead
//Method/Callback to start reference tracking
-void tracking_reference_start(void* tracking_config) {
- //Run reference tracking
- int32_t response;
- int return_value;
- return_value = pixy_command("runprog", INT8(2), END_OUT_ARGS, &response, END_IN_ARGS);
+void tracking_reference_start(void* tracking_config)
+{
+ //Run reference tracking
+ int32_t response;
+ int return_value;
+ return_value = pixy_command("runprog", INT8(2), END_OUT_ARGS, &response, END_IN_ARGS);
}
//Method/Callback to stop reference tracking
-void tracking_reference_stop(void* tracking_config) {
- //Stop reference tracking
- int32_t response;
- int return_value;
- return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);
+void tracking_reference_stop(void* tracking_config)
+{
+ //Stop reference tracking
+ int32_t response;
+ int return_value;
+ return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);
}
//Method/Callback to calculate one step of the reference tracking
-void tracking_reference_update(void* tracking_config, struct Block* blocks, int num_blocks) {
- //Nothing to do here. Pixy does it all.
+void tracking_reference_update(void* tracking_config, struct Block* blocks, int num_blocks)
+{
+ //Nothing to do here. Pixy does it all.
}
//Variable which stores all the callbacks and settings for the reference tracking implementation
static TRACKING_CONFIG_STRUCT tracking_reference = {
- tracking_reference_start,
- tracking_reference_stop,
- tracking_reference_update
+ tracking_reference_start,
+ tracking_reference_stop,
+ tracking_reference_update
};
//Pointer to the currently active tracking implementation. See also tracking_set_mode
static TRACKING_CONFIG_STRUCT* tracking_current;
//Method to set the current tracking implementation. This function is exported and should be called before getting the screen
-void tracking_set_mode(enum Tracking_Implementation impl) {
- //Depending on the enum value let tracking_current point to a different setting/callback structure
- switch(impl) {
- case OUR_TRACKING:
- tracking_current = &tracking_our;
- break;
- case REFERENCE_TRACKING:
- tracking_current = &tracking_reference;
- break;
- default:
- tracking_current=NULL;
- break;
- }
+void tracking_set_mode(enum Tracking_Implementation impl)
+{
+ //Depending on the enum value let tracking_current point to a different setting/callback structure
+ switch (impl) {
+ case OUR_TRACKING:
+ tracking_current = &tracking_our;
+ break;
+
+ case REFERENCE_TRACKING:
+ tracking_current = &tracking_reference;
+ break;
+
+ default:
+ tracking_current = NULL;
+ break;
+ }
}
//Callback for when the screen is entered/loaded
-static void enter(void* screen) {
- tft_clear(WHITE);
-
- //"Back" button
- b_back.base.x1=5; //Start X of Button
- b_back.base.y1=5; //Start Y of Button
- b_back.base.x2=AUTO; //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)
+static void enter(void* screen)
+{
+ tft_clear(WHITE);
+
+ //"Back" button
+ b_back.base.x1 = 5; //Start X of Button
+ b_back.base.y1 = 5; //Start Y of Button
+ b_back.base.x2 = AUTO; //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)
- //"Select color" button
- b_select.base.x1=150;
- b_select.base.y1=5;
- b_select.base.x2=AUTO;
- b_select.base.y2=AUTO;
- b_select.txtcolor=WHITE;
- b_select.bgcolor=HEX(0xAE1010);
- b_select.font=0;
- b_select.text="Select Color";
- b_select.callback=b_select_cb;
- gui_button_add(&b_select);
+ //"Select color" button
+ b_select.base.x1 = 150;
+ b_select.base.y1 = 5;
+ b_select.base.x2 = AUTO;
+ b_select.base.y2 = AUTO;
+ b_select.txtcolor = WHITE;
+ b_select.bgcolor = HEX(0xAE1010);
+ b_select.font = 0;
+ b_select.text = "Select Color";
+ b_select.callback = b_select_cb;
+ gui_button_add(&b_select);
- //"Frame visible" checkbox
- c_frame_toggle.base.x1 = 50;
- c_frame_toggle.base.x2 = 50+16;
- c_frame_toggle.base.y1 = 5;
- c_frame_toggle.base.y2 = 5+16;
- c_frame_toggle.checked = frame_visible;
- c_frame_toggle.fgcolor = CHECKBOX_WIN_FG_COLOR;
- c_frame_toggle.callback = c_frame_toggle_cb;
- gui_checkbox_add(&c_frame_toggle);
- tft_print_line(73,8,BLACK,TRANSPARENT,0,"Show Video");
+ //"Frame visible" checkbox
+ c_frame_toggle.base.x1 = 50;
+ c_frame_toggle.base.x2 = 50 + 16;
+ c_frame_toggle.base.y1 = 5;
+ c_frame_toggle.base.y2 = 5 + 16;
+ c_frame_toggle.checked = frame_visible;
+ c_frame_toggle.fgcolor = CHECKBOX_WIN_FG_COLOR;
+ c_frame_toggle.callback = c_frame_toggle_cb;
+ gui_checkbox_add(&c_frame_toggle);
+ tft_print_line(73, 8, BLACK, TRANSPARENT, 0, "Show Video");
- //Area to select a "color region"
- a_area.hookedActions = PEN_DOWN | PEN_UP;
- a_area.x1 = FRAME_START_X;
- a_area.y1 = FRAME_START_Y;
- a_area.x2 = FRAME_END_X;
- a_area.y2 = FRAME_END_Y;
- a_area.callback = touchCB;
+ //Area to select a "color region"
+ a_area.hookedActions = PEN_DOWN | PEN_UP;
+ a_area.x1 = FRAME_START_X;
+ a_area.y1 = FRAME_START_Y;
+ a_area.x2 = FRAME_END_X;
+ a_area.y2 = FRAME_END_Y;
+ a_area.callback = touchCB;
//Do not register it here, we do that later
- if(tracking_current==NULL) {
- state = error;
- } else {
- state = detecting; //Start with the detecting state
- }
+ if (tracking_current == NULL) {
+ state = error;
+ } else {
+ state = detecting; //Start with the detecting state
+ }
}
//Callback for when the screen is left/unloaded
-static void leave(void* screen) {
- //Remove buttons and checkbox
- gui_button_remove(&b_back);
- gui_button_remove(&b_select);
- gui_checkbox_remove(&c_frame_toggle);
+static void leave(void* screen)
+{
+ //Remove buttons and checkbox
+ gui_button_remove(&b_back);
+ gui_button_remove(&b_select);
+ gui_checkbox_remove(&c_frame_toggle);
- if(state==selecting) { //the user left the screen in the "selecting" phase
- touch_unregister_area(&a_area); //remove the touch area
- }
+ if (state == selecting) { //the user left the screen in the "selecting" phase
+ touch_unregister_area(&a_area); //remove the touch area
+ }
- if(state==tracking) { //the user left the screen in the "tracking" phase
- tracking_current->stop(tracking_current); //stop tracking
- pixy_led_set_RGB(0,0,0);
- }
+ if (state == tracking) { //the user left the screen in the "tracking" phase
+ tracking_current->stop(tracking_current); //stop tracking
+ pixy_led_set_RGB(0, 0, 0);
+ }
}
//Callback for when the screen should be updated
//This is the main loop of the screen. This method will be called repeatedly
-static void update(void* screen) {
- switch(state) {
- case detecting: //Detecting State: Where we try to connect to the pixy
- if(pixy_init()==0) { //Pixy connection ok
- state = init; //Go to next state
- }
- break;
+static void update(void* screen)
+{
+ switch (state) {
+ case detecting: //Detecting State: Where we try to connect to the pixy
+ if (pixy_init() == 0) { //Pixy connection ok
+ state = init; //Go to next state
+ }
- case init: //Init State: Where we start the tracking
- tracking_current->start(tracking_current);
- state=tracking;
- break;
+ break;
- case tracking: //Tracking state: Where we render the frame and the tracked objects
- pixy_service(); //Receive events (e.g. block-data) from pixy
+ case init: //Init State: Where we start the tracking
+ tracking_current->start(tracking_current);
+ state = tracking;
+ break;
- if(pixy_blocks_are_new()) { //There are new blocks available
- if(frame_visible) { //If the user want's us to draw the video data
- pixy_render_full_frame(FRAME_START_X,FRAME_START_Y);
- } else { //the user want's a colored background
- tft_fill_rectangle(FRAME_START_X,FRAME_START_Y,FRAME_END_X,FRAME_END_Y,RGB(200,200,200));
- }
+ case tracking: //Tracking state: Where we render the frame and the tracked objects
+ pixy_service(); //Receive events (e.g. block-data) from pixy
- #define BLOCK_BUFFER_SIZE 5 //The maximum amount of blocks that we want to receive
- struct Block blocks[BLOCK_BUFFER_SIZE]; //Storage to receive blocks from pixy
- int blocks_received= pixy_get_blocks(BLOCK_BUFFER_SIZE,blocks); //Try to receive up to BLOCK_BUFFER_SIZE Blocks from pixy
+ if (pixy_blocks_are_new()) { //There are new blocks available
+ if (frame_visible) { //If the user want's us to draw the video data
+ pixy_render_full_frame(FRAME_START_X, FRAME_START_Y);
+ } else { //the user want's a colored background
+ tft_fill_rectangle(FRAME_START_X, FRAME_START_Y, FRAME_END_X, FRAME_END_Y, RGB(200, 200, 200));
+ }
- if(blocks_received>=0) { //block receiving ok
- tracking_current->update(tracking_current,blocks,blocks_received); //apply tracking
+#define BLOCK_BUFFER_SIZE 5 //The maximum amount of blocks that we want to receive
+ struct Block blocks[BLOCK_BUFFER_SIZE]; //Storage to receive blocks from pixy
+ int blocks_received = pixy_get_blocks(BLOCK_BUFFER_SIZE, blocks); //Try to receive up to BLOCK_BUFFER_SIZE Blocks from pixy
- //Draw blocks
- for(int i=0; ix-1+FRAME_START_X -block->width/2; //Calculate x-Coordinate on the display
- uint16_t y = block->y-1+FRAME_START_Y -block->height/2; //Calculate y-Coordinate on the display
- tft_draw_rectangle(x,y,x+block->width-1, y+block->height-1,WHITE); //Draw a white rectangle
- }
- }
- }
- break;
+ if (blocks_received >= 0) { //block receiving ok
+ tracking_current->update(tracking_current, blocks, blocks_received); //apply tracking
- case preselecting: //Pre-Selecting State: Where we set up the color region selection
- {
- tracking_current->stop(tracking_current); //Stop tracking
+ //Draw blocks
+ for (int i = 0; i < blocks_received; i++) { //for each received block
+ struct Block* block = &(blocks[i]);
+ //block.x and block.y are the center coordinates of the object relative to the camera origin.
+ uint16_t x = block->x - 1 + FRAME_START_X - block->width / 2; //Calculate x-Coordinate on the display
+ uint16_t y = block->y - 1 + FRAME_START_Y - block->height / 2; //Calculate y-Coordinate on the display
+ tft_draw_rectangle(x, y, x + block->width - 1, y + block->height - 1, WHITE); //Draw a white rectangle
+ }
+ }
+ }
- pixy_render_full_frame(FRAME_START_X,FRAME_START_Y); //Render one frame
+ break;
- touch_register_area(&a_area); //Register touch area and receive events from now on
- point1_valid=false; //we start with an invalid point1
+ case preselecting: { //Pre-Selecting State: Where we set up the color region selection
+ tracking_current->stop(tracking_current); //Stop tracking
- b_select.text="Abort"; //Change the button text to "Abort"
- gui_button_redraw(&b_select); //redraw button
+ pixy_render_full_frame(FRAME_START_X, FRAME_START_Y); //Render one frame
- state = selecting; //The user can now select a region
- }
- break;
+ touch_register_area(&a_area); //Register touch area and receive events from now on
+ point1_valid = false; //we start with an invalid point1
- case selected: //Selected State: Where we send the users selection to pixy
- {
- //Ensure that (x1,y1) represent the top-left point and (x2,y2) the bottom-right.
- unsigned int tmp;
- if(point1.x > point2.x){
- tmp = point1.x;
- point1.x = point2.x;
- point2.x = tmp;
- }
+ b_select.text = "Abort"; //Change the button text to "Abort"
+ gui_button_redraw(&b_select); //redraw button
- if(point1.y > point2.y){
- tmp = point1.y;
- point1.y = point2.y;
- point2.y = tmp;
- }
- //Send pixy the selected region
- pixy_cc_set_region(1,point1.x,point1.y,point2.x-point1.x,point2.y-point1.y);
- }
- //no break here: We want the following code to be executed as well
+ state = selecting; //The user can now select a region
+ }
+ break;
- case abortselecting: //Abort-Selecting State: Where we deinitialize the stuff we used for region selection
- {
- touch_unregister_area(&a_area); //Remove the touch area. We'll no longer receive touch events
+ case selected: { //Selected State: Where we send the users selection to pixy
+ //Ensure that (x1,y1) represent the top-left point and (x2,y2) the bottom-right.
+ unsigned int tmp;
- b_select.text="Select Color"; //Change the button text back to "Select Color"
- gui_button_redraw(&b_select); //redraw button
+ if (point1.x > point2.x) {
+ tmp = point1.x;
+ point1.x = point2.x;
+ point2.x = tmp;
+ }
- tracking_current->start(tracking_current); //Start tracking again
- state=tracking;
- }
- break;
+ if (point1.y > point2.y) {
+ tmp = point1.y;
+ point1.y = point2.y;
+ point2.y = tmp;
+ }
- case selecting: //Selecting State: Where we wait on the user to select a color region
- pixy_service(); //receive pixy events
- //wait on user to select the image area
- break;
+ //Send pixy the selected region
+ pixy_cc_set_region(1, point1.x, point1.y, point2.x - point1.x, point2.y - point1.y);
+ }
- case error: //Error State: Where we show an error message and leave the user no other choice than to click the backbutton
- //wait on user to click the back button
- break;
- }
+ //no break here: We want the following code to be executed as well
+
+ case abortselecting: { //Abort-Selecting State: Where we deinitialize the stuff we used for region selection
+ touch_unregister_area(&a_area); //Remove the touch area. We'll no longer receive touch events
+
+ b_select.text = "Select Color"; //Change the button text back to "Select Color"
+ gui_button_redraw(&b_select); //redraw button
+
+ tracking_current->start(tracking_current); //Start tracking again
+ state = tracking;
+ }
+ break;
+
+ case selecting: //Selecting State: Where we wait on the user to select a color region
+ pixy_service(); //receive pixy events
+ //wait on user to select the image area
+ break;
+
+ case error: //Error State: Where we show an error message and leave the user no other choice than to click the backbutton
+ //wait on user to click the back button
+ break;
+ }
}
//Declare screen callbacks
static SCREEN_STRUCT screen = {
- enter,
- leave,
- update
+ enter,
+ leave,
+ update
};
-SCREEN_STRUCT* get_screen_tracking() {
- return &screen;
+SCREEN_STRUCT* get_screen_tracking()
+{
+ return &screen;
}
diff --git a/common/app/screen_tracking.h b/common/app/screen_tracking.h
index 5a2dbde..77b3d87 100644
--- a/common/app/screen_tracking.h
+++ b/common/app/screen_tracking.h
@@ -1,3 +1,16 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/app/screen_tracking.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-05-16 timolang@gmail.com e46314b Added Tracking Screen and implemented "Reference Tracking" and "Color Region Selection"
+*
+**************************************************************************************************************************************/
+
#include "screen.h"
/**
@@ -16,8 +29,8 @@
* Enum which contains the available tracking implementations
*/
enum Tracking_Implementation {
- OUR_TRACKING, //!< Our own tracking PID implementation
- REFERENCE_TRACKING//!< Pixy's internal tracking implementation
+ OUR_TRACKING, //!< Our own tracking PID implementation
+ REFERENCE_TRACKING//!< Pixy's internal tracking implementation
};
/**
diff --git a/common/filesystem/filesystem.c b/common/filesystem/filesystem.c
index 9d88b3b..555c667 100644
--- a/common/filesystem/filesystem.c
+++ b/common/filesystem/filesystem.c
@@ -1,38 +1,56 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/filesystem/filesystem.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-05-10 timolang@gmail.com e2bce8f Added filesystem module, tests and implementation for it in emulator.
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+*
+**************************************************************************************************************************************/
+
#include "filesystem.h"
#include "ll_filesystem.h"
-bool filesystem_init() {
- return ll_filesystem_init();
+bool filesystem_init()
+{
+ return ll_filesystem_init();
}
-DIRECTORY_STRUCT* filesystem_dir_open(const char* path) {
- return ll_filesystem_dir_open(path);
+DIRECTORY_STRUCT* filesystem_dir_open(const char* path)
+{
+ return ll_filesystem_dir_open(path);
}
-void filesystem_dir_close(DIRECTORY_STRUCT* dir) {
- ll_filesystem_dir_close(dir);
+void filesystem_dir_close(DIRECTORY_STRUCT* dir)
+{
+ ll_filesystem_dir_close(dir);
}
-FILE_HANDLE* filesystem_file_open(const char* filename) {
- return ll_filesystem_file_open(filename);
+FILE_HANDLE* filesystem_file_open(const char* filename)
+{
+ return ll_filesystem_file_open(filename);
}
-void filesystem_file_close(FILE_HANDLE* handle) {
- ll_filesystem_file_close(handle);
+void filesystem_file_close(FILE_HANDLE* handle)
+{
+ ll_filesystem_file_close(handle);
}
-FILE_STATUS filesystem_file_seek(FILE_HANDLE* handle, uint32_t offset) {
- return ll_filesystem_file_seek(handle,offset);
+FILE_STATUS filesystem_file_seek(FILE_HANDLE* handle, uint32_t offset)
+{
+ return ll_filesystem_file_seek(handle, offset);
}
-FILE_STATUS filesystem_file_read(FILE_HANDLE* handle, uint8_t* buf, uint32_t size) {
- return ll_filesystem_file_read(handle,buf,size);
+FILE_STATUS filesystem_file_read(FILE_HANDLE* handle, uint8_t* buf, uint32_t size)
+{
+ return ll_filesystem_file_read(handle, buf, size);
}
-FILE_STATUS filesystem_file_write(FILE_HANDLE* handle, uint8_t* buf, uint32_t size) {
- return ll_filesystem_file_write(handle,buf,size);
+FILE_STATUS filesystem_file_write(FILE_HANDLE* handle, uint8_t* buf, uint32_t size)
+{
+ return ll_filesystem_file_write(handle, buf, size);
}
-
-
-
-
diff --git a/common/filesystem/filesystem.h b/common/filesystem/filesystem.h
index bb7b413..3a63f68 100644
--- a/common/filesystem/filesystem.h
+++ b/common/filesystem/filesystem.h
@@ -1,3 +1,18 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/filesystem/filesystem.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 51089aa Refactored Project Structure for use with emulator
+* 2015-05-10 timolang@gmail.com e2bce8f Added filesystem module, tests and implementation for it in emulator.
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+*
+**************************************************************************************************************************************/
+
#ifndef FILESYSTEM_H
#define FILESYSTEM_H
@@ -15,57 +30,57 @@
* See http://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#attributes for detailed description
*/
typedef enum {
- F_RDO=0x01,//!< File is readonly. You cannot write to it
- F_HID=0x02,//!< File is hidden
- F_SYS=0x04,//!< File is a system file
- F_DIR=0x10,//!< It's a directory and not a file
- F_ARC=0x20 //!< File has the archive flag set (probably unused)
+ F_RDO = 0x01, //!< File is readonly. You cannot write to it
+ F_HID = 0x02, //!< File is hidden
+ F_SYS = 0x04, //!< File is a system file
+ F_DIR = 0x10, //!< It's a directory and not a file
+ F_ARC = 0x20 //!< File has the archive flag set (probably unused)
} FILE_ATTRIBUTES;
/**
* Structure which represents last modified date of a file / directory
*/
typedef struct {
- unsigned year : 7; //!< year from 1980 (0..127)
- unsigned month: 4; //!< month (1..12)
- unsigned day: 5; //!< day (1..31)
+ unsigned year : 7; //!< year from 1980 (0..127)
+ unsigned month: 4; //!< month (1..12)
+ unsigned day: 5; //!< day (1..31)
} FILE_DATE_STRUCT;
/**
* Structure which represents last modified time of a file / directory
*/
typedef struct {
- unsigned hour : 5; //!< hour (0..23)
- unsigned min: 6; //!< minute (0..59
- unsigned sec: 5; //!< second/2 (0..29)
+ unsigned hour : 5; //!< hour (0..23)
+ unsigned min: 6; //!< minute (0..59
+ unsigned sec: 5; //!< second/2 (0..29)
} FILE_TIME_STRUCT;
/**
* Structure which represents a file/directory entry. \sa DIRECTORY_STRUCT
*/
typedef struct {
- uint32_t fsize; //!< File size in bytes. 0 for directories
- FILE_DATE_STRUCT fdate; //!< Last modified date
- FILE_TIME_STRUCT ftime; //!< Last modified time
- uint8_t fattrib; //!< File/Directory Attributes
- char* fname; //!< File/Directory name
+ uint32_t fsize; //!< File size in bytes. 0 for directories
+ FILE_DATE_STRUCT fdate; //!< Last modified date
+ FILE_TIME_STRUCT ftime; //!< Last modified time
+ uint8_t fattrib; //!< File/Directory Attributes
+ char* fname; //!< File/Directory name
} FILE_STRUCT;
/**
* Structure which represents an open directory with all it's entries. \sa filesystem_dir_open
*/
typedef struct {
- const char* path; //!< Directory path (absolute)
- uint16_t num_files; //!< Number of files/directories in this directory
- FILE_STRUCT* files; //!< An array with \ref num_files FILE_STRUCT entries
+ const char* path; //!< Directory path (absolute)
+ uint16_t num_files; //!< Number of files/directories in this directory
+ FILE_STRUCT* files; //!< An array with \ref num_files FILE_STRUCT entries
} DIRECTORY_STRUCT;
/**
* Structure which represents an open file. \sa filesystem_file_open
*/
typedef struct {
- const char* fname; //!< The absolute file name
- uint32_t fpos; //!< The current byte-position in the file. \sa filesystem_file_seek
+ const char* fname; //!< The absolute file name
+ uint32_t fpos; //!< The current byte-position in the file. \sa filesystem_file_seek
uint32_t fsize; //!< The total file size in bytes
} FILE_HANDLE;
@@ -73,11 +88,11 @@ typedef struct {
* Enum to represent the success or error-code of the filesystem_file_* functions
*/
typedef enum {
- F_OK, //!< Everything ok
- F_EOF, //!< The write/read operation tried to write/read past the end of the file. This is not a fatal error.
- F_EACCESS, //!< The file can not be read/written due to access problems. This is a fatal error.
- F_INVALIDPARAM,//!< You passed invalid parameters to the function
- F_DISKERROR //!< A lowlevel disk-error occoured. This is a fatal error.
+ F_OK, //!< Everything ok
+ F_EOF, //!< The write/read operation tried to write/read past the end of the file. This is not a fatal error.
+ F_EACCESS, //!< The file can not be read/written due to access problems. This is a fatal error.
+ F_INVALIDPARAM,//!< You passed invalid parameters to the function
+ F_DISKERROR //!< A lowlevel disk-error occoured. This is a fatal error.
} FILE_STATUS;
/**
@@ -144,4 +159,3 @@ FILE_STATUS filesystem_file_write(FILE_HANDLE* handle, uint8_t* buf, uint32_t si
/*@}*/
#endif /* FILESYSTEM_H */
-
diff --git a/common/gui/button.c b/common/gui/button.c
index 8abffcb..07a5d53 100644
--- a/common/gui/button.c
+++ b/common/gui/button.c
@@ -1,154 +1,188 @@
-#include "tft.h"
-#include "touch.h"
-#include "button.h"
-#include
-
-/* The Idea is as follows:
- * When the user add's a button we create a touch area for that region and wait for PEN_DOWN events.
- * Once the user puts the pen down in this area we'll redraw the button with different shadows (feedback)
- * and we'll now wait on PEN_UP or PEN_LEAVE events.
- * If the user takes the pen away while in the area (PEN_UP), we call the provided user callback
- * Otherwise (PEN_LEAVE) we only restore the initial shadows
- */
-
-/* Possible improvements:
- * Move the button by 1 pixel while he is pressed, to create a "full 3d" experience
- * Add events for the case when the button is pressed for a long time, without release
- */
-
-//Method to calculate the shadow colors used to create the "3d" effect
-void calculate_shadows(uint16_t bgcolor, uint16_t* light_shadow, uint16_t* dark_shadow) {
- #define BRIGHTNESS_VAL 3 //How much the Brightness is in/decreased for button shadows (3 -> Add/Subtract 1/3 off Full Value)
-
- uint16_t c_light,c_dark; //c_light and c_dark will be filled with a lighter and a darker color as the background color (for the shadows)
- uint8_t r,g,b;
-
- //separate the channels of the 16-bit rgb565 color
- r=(bgcolor&0xF800)>>11;
- g=(bgcolor&0x07E0)>>5;
- b=(bgcolor&0x001F)>>0;
-
- //For the light shadow color:
- if((r + 0x1F/BRIGHTNESS_VAL) > 0x1F) //Adding one third would exceed the maximum of the red channel
- c_light=0xF800; //Use full red
- else //adding one third to the red channel is fine
- c_light=(r+0x1F/BRIGHTNESS_VAL)<<11; //Use same red as in the background, but add one third
- if((g + 0x3F/BRIGHTNESS_VAL) > 0x3F) //same for the green channel
- c_light|=0x07E0;
- else
- c_light|=(g+0x3F/BRIGHTNESS_VAL)<<5;
- if((b + 0x1F/BRIGHTNESS_VAL) > 0x1F) //and the blue channel
- c_light|=0x0018;
- else
- c_light|=(b+0x1F/BRIGHTNESS_VAL)<<0;
-
- //For the dark shadow color
- if(r > (0x1F/BRIGHTNESS_VAL)) //Subtracting one third would NOT exceed the minimum of the red channel
- c_dark=(r-0x1F/BRIGHTNESS_VAL)<<11; //Use same red as in the background, but subtract one third
- else //Subtracting one third would give us a number below zero
- c_dark=0x0000; //use no red channel
- if(g > (0x3F/BRIGHTNESS_VAL)) //Same for the green channel
- c_dark|=(g-0x3F/BRIGHTNESS_VAL)<<5;
- if(b > (0x1F/BRIGHTNESS_VAL)) //and the blue channel
- c_dark|=(b-0x1F/BRIGHTNESS_VAL)<<0;
-
- //Assign the calculated shadows to out parameters
- if(light_shadow!=NULL) *light_shadow = c_light;
- if(dark_shadow!=NULL) *dark_shadow = c_dark;
-
-}
-
-//Callback which is called when the user touches the touch-area we created for the button
-void buttons_cb(void* touchArea, TOUCH_ACTION triggeredAction)
-{
- TOUCH_AREA_STRUCT * area = (TOUCH_AREA_STRUCT*)touchArea;
- BUTTON_STRUCT* button = (BUTTON_STRUCT*)touchArea;
-
- uint16_t c_light,c_dark; //c_light and c_dark will be filled with a lighter and a darker color as the background color (for the shadows)
- calculate_shadows(button->bgcolor,&c_light,&c_dark);
-
- switch(triggeredAction)
- {
- case PEN_DOWN: //If the user touches the area for the "first time"
- area->hookedActions=PEN_UP|PEN_LEAVE; //for the future we only want PEN_UP and PEN_LEAVE events
-
- //Draw shadows
- tft_draw_line(button->base.x1+1,button->base.y1,button->base.x2-1,button->base.y1,c_dark); //North
- tft_draw_line(button->base.x1,button->base.y1+1,button->base.x1,button->base.y2-1,c_dark);//West
- tft_draw_line(button->base.x1+1,button->base.y2,button->base.x2-1,button->base.y2,c_light); //South
- tft_draw_line(button->base.x2,button->base.y1+1,button->base.x2,button->base.y2-1,c_light); //East
- break;
- case PEN_UP: //If the user took the pen away, while in the area (=button pressed!)
- case PEN_LEAVE: //or the user "slided out" of the area
- area->hookedActions=PEN_DOWN; //for the future we only want PEN_DOWN events
-
- //Draw inverse shadows
- tft_draw_line(button->base.x1+1,button->base.y1,button->base.x2-1,button->base.y1,c_light); //North
- tft_draw_line(button->base.x1,button->base.y1+1,button->base.x1,button->base.y2-1,c_light);//West
- tft_draw_line(button->base.x1+1,button->base.y2,button->base.x2-1,button->base.y2,c_dark); //South
- tft_draw_line(button->base.x2,button->base.y1+1,button->base.x2,button->base.y2-1,c_dark); //East
-
- if(triggeredAction==PEN_UP && button->callback!=NULL) //If the button got "pressed" instead of left, and the user provided a callback
- button->callback(button); //execute the user callback
- break;
- default:break;
- }
-}
-
-
-bool gui_button_add(BUTTON_STRUCT* button)
-{
- if(touch_have_empty(1)) //Check if the touch module can handle one additional area
- {
- //Calculate width and height of the button text
- unsigned int strwidth=tft_font_width(button->font)*strlen(button->text);
- unsigned char strheight=tft_font_height(button->font);
-
- button->base.hookedActions=PEN_DOWN; //At first we are interested in PEN_DOWN events
- button->base.callback = buttons_cb; //Use our own callback for the touch area events
-
- if(button->base.x2==AUTO) { //The user wants us to calculate the button width automatically
- //Use string width + half of a character width as button width
- button->base.x2= button->base.x1 -1 + strwidth+(tft_font_width(button->font)/2);
- } else if((button->base.x2-button->base.x1+1)<(strwidth+2)) { //the provided width is too small to fit the entire text
- return false; //report error
- }
-
- if(button->base.y2==AUTO) { //The user wants us to calculate the button height automatically
- //Use one and a half character heights as button height
- button->base.y2=button->base.y1 -1 +strheight+(strheight/2);
- } else if((button->base.y2-button->base.y1+1)<(strheight+2)) { //the provided height is too small to fit the text
- return false;
- }
- gui_button_redraw(button); //call the redraw method, which will take care of drawing the entire button
- return touch_register_area(&button->base); //Register the touch area and receive events for this button, from now on
- }
-
- return false; //no more touch areas left
-}
-
-void gui_button_redraw(BUTTON_STRUCT* button)
-{
- //Calculate text dimensions and shadow colors
- unsigned int strwidth=tft_font_width(button->font)*strlen(button->text);
- unsigned char strheight=tft_font_height(button->font);
- uint16_t c_light,c_dark;
- calculate_shadows(button->bgcolor,&c_light,&c_dark);
-
- //Draw the background and the 4 lines (shadow colors)
- tft_fill_rectangle(button->base.x1+1,button->base.y1+1,button->base.x2-1,button->base.y2-1,button->bgcolor);
- tft_draw_line(button->base.x1+1,button->base.y1,button->base.x2-1,button->base.y1,c_light); //North
- tft_draw_line(button->base.x1,button->base.y1+1,button->base.x1,button->base.y2-1,c_light);//West
- tft_draw_line(button->base.x1+1,button->base.y2,button->base.x2-1,button->base.y2,c_dark); //South
- tft_draw_line(button->base.x2,button->base.y1+1,button->base.x2,button->base.y2-1,c_dark); //East
-
- //Draw the text
- tft_print_line(button->base.x1+(button->base.x2-button->base.x1+1-strwidth)/2,button->base.y1+(button->base.y2-button->base.y1+1-strheight)/2,button->txtcolor,button->bgcolor,button->font,button->text);
-
-}
-
-void gui_button_remove(BUTTON_STRUCT* button)
-{
- //We only need to unregister the touch area, as we have not allocated anything else
- touch_unregister_area((TOUCH_AREA_STRUCT*)button);
-}
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/gui/button.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com 7c9eabc Added button support.
+* 2015-05-17 timolang@gmail.com 2d46336 Improved comments in implementation of button, checkbox, numupdown, tft, touch and screen modules/submodules.
+*
+**************************************************************************************************************************************/
+
+#include "tft.h"
+#include "touch.h"
+#include "button.h"
+#include
+
+/* The Idea is as follows:
+ * When the user add's a button we create a touch area for that region and wait for PEN_DOWN events.
+ * Once the user puts the pen down in this area we'll redraw the button with different shadows (feedback)
+ * and we'll now wait on PEN_UP or PEN_LEAVE events.
+ * If the user takes the pen away while in the area (PEN_UP), we call the provided user callback
+ * Otherwise (PEN_LEAVE) we only restore the initial shadows
+ */
+
+/* Possible improvements:
+ * Move the button by 1 pixel while he is pressed, to create a "full 3d" experience
+ * Add events for the case when the button is pressed for a long time, without release
+ */
+
+//Method to calculate the shadow colors used to create the "3d" effect
+void calculate_shadows(uint16_t bgcolor, uint16_t* light_shadow, uint16_t* dark_shadow)
+{
+#define BRIGHTNESS_VAL 3 //How much the Brightness is in/decreased for button shadows (3 -> Add/Subtract 1/3 off Full Value)
+
+ uint16_t c_light, c_dark; //c_light and c_dark will be filled with a lighter and a darker color as the background color (for the shadows)
+ uint8_t r, g, b;
+
+ //separate the channels of the 16-bit rgb565 color
+ r = (bgcolor & 0xF800) >> 11;
+ g = (bgcolor & 0x07E0) >> 5;
+ b = (bgcolor & 0x001F) >> 0;
+
+ //For the light shadow color:
+ if ((r + 0x1F / BRIGHTNESS_VAL) > 0x1F) { //Adding one third would exceed the maximum of the red channel
+ c_light = 0xF800; //Use full red
+ } else { //adding one third to the red channel is fine
+ c_light = (r + 0x1F / BRIGHTNESS_VAL) << 11; //Use same red as in the background, but add one third
+ }
+
+ if ((g + 0x3F / BRIGHTNESS_VAL) > 0x3F) { //same for the green channel
+ c_light |= 0x07E0;
+ } else {
+ c_light |= (g + 0x3F / BRIGHTNESS_VAL) << 5;
+ }
+
+ if ((b + 0x1F / BRIGHTNESS_VAL) > 0x1F) { //and the blue channel
+ c_light |= 0x0018;
+ } else {
+ c_light |= (b + 0x1F / BRIGHTNESS_VAL) << 0;
+ }
+
+ //For the dark shadow color
+ if (r > (0x1F / BRIGHTNESS_VAL)) { //Subtracting one third would NOT exceed the minimum of the red channel
+ c_dark = (r - 0x1F / BRIGHTNESS_VAL) << 11; //Use same red as in the background, but subtract one third
+ } else { //Subtracting one third would give us a number below zero
+ c_dark = 0x0000; //use no red channel
+ }
+
+ if (g > (0x3F / BRIGHTNESS_VAL)) { //Same for the green channel
+ c_dark |= (g - 0x3F / BRIGHTNESS_VAL) << 5;
+ }
+
+ if (b > (0x1F / BRIGHTNESS_VAL)) { //and the blue channel
+ c_dark |= (b - 0x1F / BRIGHTNESS_VAL) << 0;
+ }
+
+ //Assign the calculated shadows to out parameters
+ if (light_shadow != NULL) {
+ *light_shadow = c_light;
+ }
+
+ if (dark_shadow != NULL) {
+ *dark_shadow = c_dark;
+ }
+
+}
+
+//Callback which is called when the user touches the touch-area we created for the button
+void buttons_cb(void* touchArea, TOUCH_ACTION triggeredAction)
+{
+ TOUCH_AREA_STRUCT* area = (TOUCH_AREA_STRUCT*)touchArea;
+ BUTTON_STRUCT* button = (BUTTON_STRUCT*)touchArea;
+
+ uint16_t c_light, c_dark; //c_light and c_dark will be filled with a lighter and a darker color as the background color (for the shadows)
+ calculate_shadows(button->bgcolor, &c_light, &c_dark);
+
+ switch (triggeredAction) {
+ case PEN_DOWN: //If the user touches the area for the "first time"
+ area->hookedActions = PEN_UP | PEN_LEAVE; //for the future we only want PEN_UP and PEN_LEAVE events
+
+ //Draw shadows
+ tft_draw_line(button->base.x1 + 1, button->base.y1, button->base.x2 - 1, button->base.y1, c_dark); //North
+ tft_draw_line(button->base.x1, button->base.y1 + 1, button->base.x1, button->base.y2 - 1, c_dark); //West
+ tft_draw_line(button->base.x1 + 1, button->base.y2, button->base.x2 - 1, button->base.y2, c_light); //South
+ tft_draw_line(button->base.x2, button->base.y1 + 1, button->base.x2, button->base.y2 - 1, c_light); //East
+ break;
+
+ case PEN_UP: //If the user took the pen away, while in the area (=button pressed!)
+ case PEN_LEAVE: //or the user "slided out" of the area
+ area->hookedActions = PEN_DOWN; //for the future we only want PEN_DOWN events
+
+ //Draw inverse shadows
+ tft_draw_line(button->base.x1 + 1, button->base.y1, button->base.x2 - 1, button->base.y1, c_light); //North
+ tft_draw_line(button->base.x1, button->base.y1 + 1, button->base.x1, button->base.y2 - 1, c_light); //West
+ tft_draw_line(button->base.x1 + 1, button->base.y2, button->base.x2 - 1, button->base.y2, c_dark); //South
+ tft_draw_line(button->base.x2, button->base.y1 + 1, button->base.x2, button->base.y2 - 1, c_dark); //East
+
+ if (triggeredAction == PEN_UP && button->callback != NULL) { //If the button got "pressed" instead of left, and the user provided a callback
+ button->callback(button); //execute the user callback
+ }
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+bool gui_button_add(BUTTON_STRUCT* button)
+{
+ if (touch_have_empty(1)) { //Check if the touch module can handle one additional area
+ //Calculate width and height of the button text
+ unsigned int strwidth = tft_font_width(button->font) * strlen(button->text);
+ unsigned char strheight = tft_font_height(button->font);
+
+ button->base.hookedActions = PEN_DOWN; //At first we are interested in PEN_DOWN events
+ button->base.callback = buttons_cb; //Use our own callback for the touch area events
+
+ if (button->base.x2 == AUTO) { //The user wants us to calculate the button width automatically
+ //Use string width + half of a character width as button width
+ button->base.x2 = button->base.x1 - 1 + strwidth + (tft_font_width(button->font) / 2);
+ } else if ((button->base.x2 - button->base.x1 + 1) < (strwidth + 2)) { //the provided width is too small to fit the entire text
+ return false; //report error
+ }
+
+ if (button->base.y2 == AUTO) { //The user wants us to calculate the button height automatically
+ //Use one and a half character heights as button height
+ button->base.y2 = button->base.y1 - 1 + strheight + (strheight / 2);
+ } else if ((button->base.y2 - button->base.y1 + 1) < (strheight + 2)) { //the provided height is too small to fit the text
+ return false;
+ }
+
+ gui_button_redraw(button); //call the redraw method, which will take care of drawing the entire button
+ return touch_register_area(&button->base); //Register the touch area and receive events for this button, from now on
+ }
+
+ return false; //no more touch areas left
+}
+
+void gui_button_redraw(BUTTON_STRUCT* button)
+{
+ //Calculate text dimensions and shadow colors
+ unsigned int strwidth = tft_font_width(button->font) * strlen(button->text);
+ unsigned char strheight = tft_font_height(button->font);
+ uint16_t c_light, c_dark;
+ calculate_shadows(button->bgcolor, &c_light, &c_dark);
+
+ //Draw the background and the 4 lines (shadow colors)
+ tft_fill_rectangle(button->base.x1 + 1, button->base.y1 + 1, button->base.x2 - 1, button->base.y2 - 1, button->bgcolor);
+ tft_draw_line(button->base.x1 + 1, button->base.y1, button->base.x2 - 1, button->base.y1, c_light); //North
+ tft_draw_line(button->base.x1, button->base.y1 + 1, button->base.x1, button->base.y2 - 1, c_light); //West
+ tft_draw_line(button->base.x1 + 1, button->base.y2, button->base.x2 - 1, button->base.y2, c_dark); //South
+ tft_draw_line(button->base.x2, button->base.y1 + 1, button->base.x2, button->base.y2 - 1, c_dark); //East
+
+ //Draw the text
+ tft_print_line(button->base.x1 + (button->base.x2 - button->base.x1 + 1 - strwidth) / 2, button->base.y1 + (button->base.y2 - button->base.y1 + 1 - strheight) / 2, button->txtcolor, button->bgcolor, button->font, button->text);
+
+}
+
+void gui_button_remove(BUTTON_STRUCT* button)
+{
+ //We only need to unregister the touch area, as we have not allocated anything else
+ touch_unregister_area((TOUCH_AREA_STRUCT*)button);
+}
diff --git a/common/gui/button.h b/common/gui/button.h
index 14aff59..2a8d3a1 100644
--- a/common/gui/button.h
+++ b/common/gui/button.h
@@ -1,71 +1,89 @@
-#ifndef BUTTON_H
-#define BUTTON_H
-
-#include "touch.h"
-
-/**
- * @defgroup gui Gui
- * The Gui Module
- */
-/*@{*/
-
-/**
- * @defgroup button Button
- * The Button Gui-Element is a clickable, rectangular box with a label inside.
- * When it is pressed and released you will be notified via the provided callback.
- */
-
-/*@}*/
-
-/**
- * @addtogroup button
- */
-/*@{*/
-
-
-/**
- * Prototype for Event Listeners (called when the button is pressed)
- * \note You should NOT execute long running things in this callback nor should you update the gui. But you can call gui_screen_navigate() for instance.
- * @param button The pointer to the BUTTON_STRUCT where to corresponding Button was pressed
- */
-typedef void (*BUTTON_CALLBACK)(void *button);
-
-
-/**
- * Structure to configure the Button
- */
-typedef struct {
- TOUCH_AREA_STRUCT base; //!< Basic geometry of the button. You only need to set the x1, y1, x2, y2 members of this struct.
- uint16_t bgcolor; //!< The 16-bit background color of the button
- BUTTON_CALLBACK callback; //!< Callback which is executed when the button is pressed
- uint16_t txtcolor; //!< The 16-bit text color
- uint8_t font; //!< The number of the font to use
- const char *text; //!< The label of the button
-} BUTTON_STRUCT;
-
-
-#define AUTO 0 //!< Use this value instead of x2, y2 in the BUTTON_STRUCT to autocalculate the button width/height
-
-/**
- * Adds a button. Your Callback will be called from now on, if the button was pressed
- * @param button A Pointer to the preinitialized BUTTON_STRUCT
- * @return true on success
- */
-bool gui_button_add(BUTTON_STRUCT* button);
-
-/**
- * Removes the button. You will no longer receive events for this button. This function will not overdraw the region where the button was located.
- * @param button A Pointer to the BUTTON_STRUCT
- */
-void gui_button_remove(BUTTON_STRUCT* button);
-
-/**
- * Redraws the button. Call this method if you have to redraw the entire screen or if you want to draw a button on top of an image.
- * @param button A Pointer to the BUTTON_STRUCT
- */
-void gui_button_redraw(BUTTON_STRUCT* button);
-
-
-/*@}*/
-
-#endif /* BUTTON_H */
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/gui/button.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com 7c9eabc Added button support.
+* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
+* 2015-05-11 timolang@gmail.com 08d9fe0 More work on doxygen module structure
+* 2015-05-12 timolang@gmail.com 1402598 Added doxygen stuff for button module and some minor changes to touch, screen_main and tft module.
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+* 2015-05-17 timolang@gmail.com 2d46336 Improved comments in implementation of button, checkbox, numupdown, tft, touch and screen modules/submodules.
+*
+**************************************************************************************************************************************/
+
+#ifndef BUTTON_H
+#define BUTTON_H
+
+#include "touch.h"
+
+/**
+ * @defgroup gui Gui
+ * The Gui Module
+ */
+/*@{*/
+
+/**
+ * @defgroup button Button
+ * The Button Gui-Element is a clickable, rectangular box with a label inside.
+ * When it is pressed and released you will be notified via the provided callback.
+ */
+
+/*@}*/
+
+/**
+ * @addtogroup button
+ */
+/*@{*/
+
+
+/**
+ * Prototype for Event Listeners (called when the button is pressed)
+ * \note You should NOT execute long running things in this callback nor should you update the gui. But you can call gui_screen_navigate() for instance.
+ * @param button The pointer to the BUTTON_STRUCT where to corresponding Button was pressed
+ */
+typedef void (*BUTTON_CALLBACK)(void* button);
+
+
+/**
+ * Structure to configure the Button
+ */
+typedef struct {
+ TOUCH_AREA_STRUCT base; //!< Basic geometry of the button. You only need to set the x1, y1, x2, y2 members of this struct.
+ uint16_t bgcolor; //!< The 16-bit background color of the button
+ BUTTON_CALLBACK callback; //!< Callback which is executed when the button is pressed
+ uint16_t txtcolor; //!< The 16-bit text color
+ uint8_t font; //!< The number of the font to use
+ const char* text; //!< The label of the button
+} BUTTON_STRUCT;
+
+
+#define AUTO 0 //!< Use this value instead of x2, y2 in the BUTTON_STRUCT to autocalculate the button width/height
+
+/**
+ * Adds a button. Your Callback will be called from now on, if the button was pressed
+ * @param button A Pointer to the preinitialized BUTTON_STRUCT
+ * @return true on success
+ */
+bool gui_button_add(BUTTON_STRUCT* button);
+
+/**
+ * Removes the button. You will no longer receive events for this button. This function will not overdraw the region where the button was located.
+ * @param button A Pointer to the BUTTON_STRUCT
+ */
+void gui_button_remove(BUTTON_STRUCT* button);
+
+/**
+ * Redraws the button. Call this method if you have to redraw the entire screen or if you want to draw a button on top of an image.
+ * @param button A Pointer to the BUTTON_STRUCT
+ */
+void gui_button_redraw(BUTTON_STRUCT* button);
+
+
+/*@}*/
+
+#endif /* BUTTON_H */
diff --git a/common/gui/checkbox.c b/common/gui/checkbox.c
index 3f0cb8a..c2878be 100644
--- a/common/gui/checkbox.c
+++ b/common/gui/checkbox.c
@@ -1,121 +1,144 @@
-#include "tft.h"
-#include "touch.h"
-#include "checkbox.h"
-#include
-
-/* The idea is as follows:
- * When the user creates a checkbox we create a touch area for that region and wait for PEN_DOWN events.
- * Once the user puts the pen down in this area we'll redraw the checkbox with different shadows (feedback)
- * and we'll now wait on PEN_UP or PEN_LEAVE events.
- * If the user takes the pen away while in the area (PEN_UP), we toggle the checkbox and we call the provided user callback
- * Otherwise (PEN_LEAVE) we only restore the initial shadows
- */
-
-
-#define ACTIVE_COLOR RGB(251,208,123) //shadow color (inside of border)
-#define BORDER_COLOR RGB(29,82,129) //1px border color
-#define BACKGROUND_COLOR WHITE //Background color
-
-//Callback which is called when the user touches the touch-area we created for the checkbox
-void checkboxes_cb(void* touchArea, TOUCH_ACTION triggeredAction)
-{
- TOUCH_AREA_STRUCT * area = (TOUCH_AREA_STRUCT*)touchArea;
- CHECKBOX_STRUCT* checkbox = (CHECKBOX_STRUCT*)touchArea;
- switch(triggeredAction)
- {
- case PEN_DOWN: //If the user touches the area for the "first time"
- area->hookedActions=PEN_UP|PEN_LEAVE; //for the future we only want PEN_UP and PEN_LEAVE events
-
- //Draw active shadows
- tft_draw_rectangle(checkbox->base.x1+1,checkbox->base.y1+1,checkbox->base.x2-1,checkbox->base.y2-1,ACTIVE_COLOR);
- tft_draw_rectangle(checkbox->base.x1+2,checkbox->base.y1+2,checkbox->base.x2-2,checkbox->base.y2-2,ACTIVE_COLOR);
- break;
- case PEN_UP: //If the user took the pen away, while in the area (=toggle checkbox!)
- checkbox->checked=!checkbox->checked; //Toggle checkbox state
- gui_checkbox_update(checkbox); //redraw/overdraw tickmark
- if(checkbox->callback!=NULL) { //The user provided a callback
- checkbox->callback(checkbox,checkbox->checked); //Call the provided callback with the new checked state
- }
- // no break statement here!
- case PEN_LEAVE: //if the user "slided out" of the area
- area->hookedActions=PEN_DOWN; //for the future we only want PEN_DOWN events
-
- //Draw inactive shadows
- tft_draw_rectangle(checkbox->base.x1+1,checkbox->base.y1+1,checkbox->base.x2-1,checkbox->base.y2-1,BACKGROUND_COLOR);
- tft_draw_rectangle(checkbox->base.x1+2,checkbox->base.y1+2,checkbox->base.x2-2,checkbox->base.y2-2,BACKGROUND_COLOR);
- break;
- default:break;
- }
-}
-
-bool gui_checkbox_add(CHECKBOX_STRUCT* checkbox)
-{
- if(touch_have_empty(1)) //Check if the touch module can handle one additional area
- {
- unsigned char size=0;
- checkbox->base.hookedActions=PEN_DOWN; //At first we are interested in PEN_DOWN events
- checkbox->base.callback = checkboxes_cb; //Use our own callback for the touch area events
-
- //Check the size of the checkbox
- if(checkbox->base.x2>checkbox->base.x1)
- size = checkbox->base.x2 - checkbox->base.x1; //use width a as size
- if(checkbox->base.y2>checkbox->base.y1)
- {
- if((checkbox->base.y2 - checkbox->base.y1)>size) //height is larger than size
- size = checkbox->base.y2 - checkbox->base.y1; //use height as size
- }
- if(size==0) { //no size found (maybe swap x2 and x1 or y2 and y1 ?)
- return false; //signal error
- }
- if((size&0x01)) //the size is an odd number
- size++; //make size an even number
-
- //Correct x2,y2 so that the checkbox is quadratic
- checkbox->base.x2 = checkbox->base.x1 + size;
- checkbox->base.y2 = checkbox->base.y1 + size;
-
- gui_checkbox_redraw(checkbox);//Call redraw method, which will take care of the drawing of the entire checkbox
-
- return touch_register_area(&checkbox->base); //Register the touch area and receive events for this checkbox, from now on
- }
-
- return false; //no more touch areas left
-}
-
-void gui_checkbox_redraw(CHECKBOX_STRUCT* checkbox)
-{
- //Draw background and border
- tft_fill_rectangle(checkbox->base.x1+1,checkbox->base.y1+1,checkbox->base.x2-1,checkbox->base.y2-1,BACKGROUND_COLOR);
- tft_draw_rectangle(checkbox->base.x1,checkbox->base.y1,checkbox->base.x2,checkbox->base.y2,BORDER_COLOR);
-
- if(checkbox->checked) { //checkbox is currently checked
- gui_checkbox_update(checkbox); //Call update method which will draw the tickmark
- }
-}
-
-void gui_checkbox_remove(CHECKBOX_STRUCT* checkbox)
-{
- //We only need to unregister the touch area, as we have not allocated anything else
- touch_unregister_area((TOUCH_AREA_STRUCT*)checkbox);
-}
-
-void gui_checkbox_update(CHECKBOX_STRUCT* checkbox)
-{
- unsigned int c = (checkbox->checked)? checkbox->fgcolor:BACKGROUND_COLOR; //color to use for the tickmark
-
- //helper points inside the checkbox
- unsigned int xcent = checkbox->base.x1+(checkbox->base.x2-checkbox->base.x1)*6/14;
- unsigned int yleft = checkbox->base.y2 - (xcent- checkbox->base.x1) - 1 ;
- unsigned int yright = checkbox->base.y2 - (checkbox->base.x2 - xcent) - 1 ;
- unsigned int ybot = checkbox->base.y2 - 4;
-
- //Draw tickmark as a 3pixel wide line
- tft_draw_line(checkbox->base.x1+3,yleft-1,xcent,ybot -1,c);
- tft_draw_line(checkbox->base.x1+3,yleft,xcent,ybot ,c);
- tft_draw_line(checkbox->base.x1+3,yleft+1,xcent,ybot + 1,c);
- xcent++;
- ybot--;
- tft_draw_line(xcent,ybot-1,checkbox->base.x2-3,yright-1,c);
- tft_draw_line(xcent,ybot,checkbox->base.x2-3,yright+0,c);
- tft_draw_line(xcent,ybot+1,checkbox->base.x2-3,yright+1,c);
-}
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/gui/checkbox.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com b300ac5 Added Checkbox support
+* 2015-05-17 timolang@gmail.com 2d46336 Improved comments in implementation of button, checkbox, numupdown, tft, touch and screen modules/submodules.
+*
+**************************************************************************************************************************************/
+
+#include "tft.h"
+#include "touch.h"
+#include "checkbox.h"
+#include
+
+/* The idea is as follows:
+ * When the user creates a checkbox we create a touch area for that region and wait for PEN_DOWN events.
+ * Once the user puts the pen down in this area we'll redraw the checkbox with different shadows (feedback)
+ * and we'll now wait on PEN_UP or PEN_LEAVE events.
+ * If the user takes the pen away while in the area (PEN_UP), we toggle the checkbox and we call the provided user callback
+ * Otherwise (PEN_LEAVE) we only restore the initial shadows
+ */
+
+
+#define ACTIVE_COLOR RGB(251,208,123) //shadow color (inside of border)
+#define BORDER_COLOR RGB(29,82,129) //1px border color
+#define BACKGROUND_COLOR WHITE //Background color
+
+//Callback which is called when the user touches the touch-area we created for the checkbox
+void checkboxes_cb(void* touchArea, TOUCH_ACTION triggeredAction)
+{
+ TOUCH_AREA_STRUCT* area = (TOUCH_AREA_STRUCT*)touchArea;
+ CHECKBOX_STRUCT* checkbox = (CHECKBOX_STRUCT*)touchArea;
+
+ switch (triggeredAction) {
+ case PEN_DOWN: //If the user touches the area for the "first time"
+ area->hookedActions = PEN_UP | PEN_LEAVE; //for the future we only want PEN_UP and PEN_LEAVE events
+
+ //Draw active shadows
+ tft_draw_rectangle(checkbox->base.x1 + 1, checkbox->base.y1 + 1, checkbox->base.x2 - 1, checkbox->base.y2 - 1, ACTIVE_COLOR);
+ tft_draw_rectangle(checkbox->base.x1 + 2, checkbox->base.y1 + 2, checkbox->base.x2 - 2, checkbox->base.y2 - 2, ACTIVE_COLOR);
+ break;
+
+ case PEN_UP: //If the user took the pen away, while in the area (=toggle checkbox!)
+ checkbox->checked = !checkbox->checked; //Toggle checkbox state
+ gui_checkbox_update(checkbox); //redraw/overdraw tickmark
+
+ if (checkbox->callback != NULL) { //The user provided a callback
+ checkbox->callback(checkbox, checkbox->checked); //Call the provided callback with the new checked state
+ }
+
+ // no break statement here!
+ case PEN_LEAVE: //if the user "slided out" of the area
+ area->hookedActions = PEN_DOWN; //for the future we only want PEN_DOWN events
+
+ //Draw inactive shadows
+ tft_draw_rectangle(checkbox->base.x1 + 1, checkbox->base.y1 + 1, checkbox->base.x2 - 1, checkbox->base.y2 - 1, BACKGROUND_COLOR);
+ tft_draw_rectangle(checkbox->base.x1 + 2, checkbox->base.y1 + 2, checkbox->base.x2 - 2, checkbox->base.y2 - 2, BACKGROUND_COLOR);
+ break;
+
+ default:
+ break;
+ }
+}
+
+bool gui_checkbox_add(CHECKBOX_STRUCT* checkbox)
+{
+ if (touch_have_empty(1)) { //Check if the touch module can handle one additional area
+ unsigned char size = 0;
+ checkbox->base.hookedActions = PEN_DOWN; //At first we are interested in PEN_DOWN events
+ checkbox->base.callback = checkboxes_cb; //Use our own callback for the touch area events
+
+ //Check the size of the checkbox
+ if (checkbox->base.x2 > checkbox->base.x1) {
+ size = checkbox->base.x2 - checkbox->base.x1; //use width a as size
+ }
+
+ if (checkbox->base.y2 > checkbox->base.y1) {
+ if ((checkbox->base.y2 - checkbox->base.y1) > size) { //height is larger than size
+ size = checkbox->base.y2 - checkbox->base.y1; //use height as size
+ }
+ }
+
+ if (size == 0) { //no size found (maybe swap x2 and x1 or y2 and y1 ?)
+ return false; //signal error
+ }
+
+ if ((size & 0x01)) { //the size is an odd number
+ size++; //make size an even number
+ }
+
+ //Correct x2,y2 so that the checkbox is quadratic
+ checkbox->base.x2 = checkbox->base.x1 + size;
+ checkbox->base.y2 = checkbox->base.y1 + size;
+
+ gui_checkbox_redraw(checkbox);//Call redraw method, which will take care of the drawing of the entire checkbox
+
+ return touch_register_area(&checkbox->base); //Register the touch area and receive events for this checkbox, from now on
+ }
+
+ return false; //no more touch areas left
+}
+
+void gui_checkbox_redraw(CHECKBOX_STRUCT* checkbox)
+{
+ //Draw background and border
+ tft_fill_rectangle(checkbox->base.x1 + 1, checkbox->base.y1 + 1, checkbox->base.x2 - 1, checkbox->base.y2 - 1, BACKGROUND_COLOR);
+ tft_draw_rectangle(checkbox->base.x1, checkbox->base.y1, checkbox->base.x2, checkbox->base.y2, BORDER_COLOR);
+
+ if (checkbox->checked) { //checkbox is currently checked
+ gui_checkbox_update(checkbox); //Call update method which will draw the tickmark
+ }
+}
+
+void gui_checkbox_remove(CHECKBOX_STRUCT* checkbox)
+{
+ //We only need to unregister the touch area, as we have not allocated anything else
+ touch_unregister_area((TOUCH_AREA_STRUCT*)checkbox);
+}
+
+void gui_checkbox_update(CHECKBOX_STRUCT* checkbox)
+{
+ unsigned int c = (checkbox->checked) ? checkbox->fgcolor : BACKGROUND_COLOR; //color to use for the tickmark
+
+ //helper points inside the checkbox
+ unsigned int xcent = checkbox->base.x1 + (checkbox->base.x2 - checkbox->base.x1) * 6 / 14;
+ unsigned int yleft = checkbox->base.y2 - (xcent - checkbox->base.x1) - 1 ;
+ unsigned int yright = checkbox->base.y2 - (checkbox->base.x2 - xcent) - 1 ;
+ unsigned int ybot = checkbox->base.y2 - 4;
+
+ //Draw tickmark as a 3pixel wide line
+ tft_draw_line(checkbox->base.x1 + 3, yleft - 1, xcent, ybot - 1, c);
+ tft_draw_line(checkbox->base.x1 + 3, yleft, xcent, ybot , c);
+ tft_draw_line(checkbox->base.x1 + 3, yleft + 1, xcent, ybot + 1, c);
+ xcent++;
+ ybot--;
+ tft_draw_line(xcent, ybot - 1, checkbox->base.x2 - 3, yright - 1, c);
+ tft_draw_line(xcent, ybot, checkbox->base.x2 - 3, yright + 0, c);
+ tft_draw_line(xcent, ybot + 1, checkbox->base.x2 - 3, yright + 1, c);
+}
diff --git a/common/gui/checkbox.h b/common/gui/checkbox.h
index 9165f6c..60c06ef 100644
--- a/common/gui/checkbox.h
+++ b/common/gui/checkbox.h
@@ -1,70 +1,86 @@
-#ifndef CHECKBOX_H
-#define CHECKBOX_H
-
-#include "touch.h"
-
-/**
- * @addtogroup gui
- */
-/*@{*/
-
-/**
- * @defgroup checkbox Checkbox
- * The Checkbox Gui-Element is a clickable, rectangular box with an optional tickmark inside of it.
- * When the checkbox is pressed and released it's tick state changes and you will be notified via the provided callback.
- */
-/*@}*/
-
-/**
- * @addtogroup checkbox
- */
-/*@{*/
-
-/**
- * Prototype for Event Listeners (called when the checkbox state has changed)
- * \note You should NOT execute long running things in this callback nor should you update the gui. But you can call gui_screen_navigate() for instance.
- * @param checkbox The pointer to the CHECKBOX_STRUCT where to corresponding Checkbox has changed the state
- * @param checked A boolean which indicates whether the checkbox is now checked or not.
- */
-typedef void (*CHECKBOX_CALLBACK)(void *checkbox, bool checked);
-
-/**
- * Structure to configure the Checkbox
- */
-typedef struct {
- TOUCH_AREA_STRUCT base; //!< Basic geometry of the Checkbox. You only need to set the x1, y1, x2, y2 members of this struct.
- uint16_t fgcolor; //!< The 16-bit color of the tickmark
- bool checked; //!< A boolean which indicates whether or not the checkbox is currently checked.
- CHECKBOX_CALLBACK callback; //!< Callback which is executed when the checkbox changes state
-} CHECKBOX_STRUCT;
-
-/**
- * Adds a checkbox. Your Callback will be called from now on, if the checkbox changes state
- * @param checkbox A Pointer to the preinitialized CHECKBOX_STRUCT
- * @return true on success
- */
-bool gui_checkbox_add(CHECKBOX_STRUCT* checkbox);
-
-/**
- * Removes the checkbox. You will no longer receive events for this checkbox. This function will not overdraw the region where the checkbox was located.
- * @param checkbox A Pointer to the CHECKBOX_STRUCT
- */
-void gui_checkbox_remove(CHECKBOX_STRUCT* checkbox);
-
-/**
- * Updates the checkbox. Call this function when you change the state of the checkbox through code.
- * @param checkbox A Pointer to the CHECKBOX_STRUCT
- */
-void gui_checkbox_update(CHECKBOX_STRUCT* checkbox);
-
-/**
- * Redraws the checkbox. Call this method if you have to redraw the entire screen or if you want to draw a checkbox on top of an image.
- * @param checkbox A Pointer to the CHECKBOX_STRUCT
- */
-void gui_checkbox_redraw(CHECKBOX_STRUCT* checkbox);
-
-#define CHECKBOX_WIN_FG_COLOR RGB(32,161,34)
-
-/*@}*/
-
-#endif /* CHECKBOX_H */
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/gui/checkbox.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com b300ac5 Added Checkbox support
+* 2015-05-11 timolang@gmail.com 08d9fe0 More work on doxygen module structure
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+* 2015-05-17 timolang@gmail.com 2d46336 Improved comments in implementation of button, checkbox, numupdown, tft, touch and screen modules/submodules.
+*
+**************************************************************************************************************************************/
+
+#ifndef CHECKBOX_H
+#define CHECKBOX_H
+
+#include "touch.h"
+
+/**
+ * @addtogroup gui
+ */
+/*@{*/
+
+/**
+ * @defgroup checkbox Checkbox
+ * The Checkbox Gui-Element is a clickable, rectangular box with an optional tickmark inside of it.
+ * When the checkbox is pressed and released it's tick state changes and you will be notified via the provided callback.
+ */
+/*@}*/
+
+/**
+ * @addtogroup checkbox
+ */
+/*@{*/
+
+/**
+ * Prototype for Event Listeners (called when the checkbox state has changed)
+ * \note You should NOT execute long running things in this callback nor should you update the gui. But you can call gui_screen_navigate() for instance.
+ * @param checkbox The pointer to the CHECKBOX_STRUCT where to corresponding Checkbox has changed the state
+ * @param checked A boolean which indicates whether the checkbox is now checked or not.
+ */
+typedef void (*CHECKBOX_CALLBACK)(void* checkbox, bool checked);
+
+/**
+ * Structure to configure the Checkbox
+ */
+typedef struct {
+ TOUCH_AREA_STRUCT base; //!< Basic geometry of the Checkbox. You only need to set the x1, y1, x2, y2 members of this struct.
+ uint16_t fgcolor; //!< The 16-bit color of the tickmark
+ bool checked; //!< A boolean which indicates whether or not the checkbox is currently checked.
+ CHECKBOX_CALLBACK callback; //!< Callback which is executed when the checkbox changes state
+} CHECKBOX_STRUCT;
+
+/**
+ * Adds a checkbox. Your Callback will be called from now on, if the checkbox changes state
+ * @param checkbox A Pointer to the preinitialized CHECKBOX_STRUCT
+ * @return true on success
+ */
+bool gui_checkbox_add(CHECKBOX_STRUCT* checkbox);
+
+/**
+ * Removes the checkbox. You will no longer receive events for this checkbox. This function will not overdraw the region where the checkbox was located.
+ * @param checkbox A Pointer to the CHECKBOX_STRUCT
+ */
+void gui_checkbox_remove(CHECKBOX_STRUCT* checkbox);
+
+/**
+ * Updates the checkbox. Call this function when you change the state of the checkbox through code.
+ * @param checkbox A Pointer to the CHECKBOX_STRUCT
+ */
+void gui_checkbox_update(CHECKBOX_STRUCT* checkbox);
+
+/**
+ * Redraws the checkbox. Call this method if you have to redraw the entire screen or if you want to draw a checkbox on top of an image.
+ * @param checkbox A Pointer to the CHECKBOX_STRUCT
+ */
+void gui_checkbox_redraw(CHECKBOX_STRUCT* checkbox);
+
+#define CHECKBOX_WIN_FG_COLOR RGB(32,161,34)
+
+/*@}*/
+
+#endif /* CHECKBOX_H */
diff --git a/common/gui/numupdown.c b/common/gui/numupdown.c
index e17a48b..bc6ed42 100644
--- a/common/gui/numupdown.c
+++ b/common/gui/numupdown.c
@@ -1,143 +1,169 @@
-#include "tft.h"
-#include "touch.h"
-#include "button.h"
-#include "numupdown.h"
-#include //for sprintf
-#include //for offsetof macro
-#include //for abs
-
-/* The idea is as follows:
- * When the user add's a numupdown we create two buttons, one with a plus and one with a minus sign in it
- * When the user presses one of the buttons we check and increase the value and execute the provided user callback
- */
-
-
-#define BASE_COLOR RGB(90,90,90) //Background color for the whole element
-
-//Callback which is called when the user presses the "plus" button
-void button_up_cb(void* button)
-{
- //Get the pointer to the numupdown: subtract the offset of the buttonUp member in the struct from the button pointer
- NUMUPDOWN_STRUCT* element = button-offsetof(NUMUPDOWN_STRUCT,buttonUp);
-
- if(element->valuemax) { //old value lies below the maximum
- element->value++; //let's increase the value
- gui_numupdown_update(element); //and redraw everything
- if(element->callback!=NULL) { //the user provided a callback
- element->callback(element,element->value); //Call the user callback with the new value
- }
- }
-}
-
-//Callback which is called when the user presses the "minus" button
-void button_down_cb(void* button)
-{
- //Get the pointer to the numupdown: subtract the offset of the buttonDown member in the struct from the button pointer
- NUMUPDOWN_STRUCT* element = button-offsetof(NUMUPDOWN_STRUCT,buttonDown);
-
- if(element->value>element->min) { //old value lies above the minimum
- element->value--; //let's decrease the value
- gui_numupdown_update(element); //and redraw everything
- if(element->callback!=NULL) { //the user provided a callback
- element->callback(element,element->value); //Call the user callback with the new value
- }
- }
-}
-
-//Method to calculate the number of characters needed to print the provided number in decimal notation (with optional sign)
-static uint8_t calc_text_width(int16_t val) {
- uint8_t width = 1 + (val<0); //1 if positive, 2 if negative (to let space for sign)
- val=abs(val); //Make the number positive
- while(val>=10) { //while we have two or more digits
- val/=10; //remove one digit
- width++; //add one character
- }
- return width;
-}
-
-
-bool gui_numupdown_add(NUMUPDOWN_STRUCT* numupdown)
-{
- if(touch_have_empty(2)) //Check if the touch module can handle two additional areas
- {
- if(numupdown->min > numupdown->max) { //min is bigger than max?
- return false; //invalid parameter
- }
-
- if(numupdown->value < numupdown->min) { //value is smaller than min?
- numupdown->value = numupdown->min; //normalize value
- } else if(numupdown->value > numupdown->max) { //value is bigger than max?
- numupdown->value = numupdown->max; //normalize value
- }
-
- uint8_t tw1 = calc_text_width(numupdown->max); //Calculate character width to render maximum value
- uint8_t tw2 = calc_text_width(numupdown->min); //Calculate character width to render minimum value
- if(tw2 > tw1) tw1 = tw2; //ensure tw1 contains the larger number of the two
- uint8_t width= tft_font_width(0)*(tw1+1); //Calculate width of the number area
-
- //Add "minus" button to the left side of the number area
- numupdown->buttonDown.base.x1=numupdown->x;
- numupdown->buttonDown.base.y1=numupdown->y;
- numupdown->buttonDown.base.x2=AUTO;
- numupdown->buttonDown.base.y2=numupdown->y+tft_font_height(0)*2;
- numupdown->buttonDown.text="-";
- numupdown->buttonDown.font=0;
- numupdown->buttonDown.bgcolor=BASE_COLOR;
- numupdown->buttonDown.txtcolor=WHITE;
- numupdown->buttonDown.callback = button_down_cb;
- gui_button_add(&numupdown->buttonDown);
-
- //Add "plus" button to the right side of the number area
- numupdown->buttonUp.base.x1=numupdown->buttonDown.base.x2+width+2;
- numupdown->buttonUp.base.y1=numupdown->y;
- numupdown->buttonUp.base.x2=AUTO;
- numupdown->buttonUp.base.y2=numupdown->y +tft_font_height(0)*2;
- numupdown->buttonUp.text="+";
- numupdown->buttonUp.font=0;
- numupdown->buttonUp.bgcolor=BASE_COLOR;
- numupdown->buttonUp.txtcolor=WHITE;
- numupdown->buttonUp.callback = button_up_cb;
- gui_button_add(&numupdown->buttonUp);
-
- //Draw background and label of the number area
- tft_fill_rectangle(numupdown->buttonDown.base.x2+2,numupdown->y,numupdown->buttonDown.base.x2+width,numupdown->buttonUp.base.y2,BASE_COLOR);
- tft_print_formatted(numupdown->buttonDown.base.x2+2+tft_font_width(0)/2,numupdown->y+tft_font_height(0)/2,numupdown->fgcolor,BASE_COLOR,0,"%*d",tw1,numupdown->value);
-
- return true;
- }
-
- return false; //not enough touch areas left
- }
-
-void gui_numupdown_remove(NUMUPDOWN_STRUCT* numupdown)
-{
- //remove the two buttons, we have no other allocated resources
- gui_button_remove(&numupdown->buttonUp);
- gui_button_remove(&numupdown->buttonDown);
-}
-
-
-void gui_numupdown_redraw(NUMUPDOWN_STRUCT* numupdown)
-{
- //redraw the two buttons
- gui_button_redraw(&numupdown->buttonUp);
- gui_button_redraw(&numupdown->buttonDown);
-
- //call update method which will take care of the number-area rendering
- gui_numupdown_update(numupdown);
-}
-
-void gui_numupdown_update(NUMUPDOWN_STRUCT* numupdown)
-{
- //Calculate the number area width again (see above)
- uint8_t tw1 = calc_text_width(numupdown->max);
- uint8_t tw2 = calc_text_width(numupdown->min);
- if(tw2 > tw1) tw1 = tw2;
- uint8_t width= tft_font_width(0)*(tw1+1);
-
- //Draw background and label of the number area
- tft_fill_rectangle(numupdown->buttonDown.base.x2+2,numupdown->y,numupdown->buttonDown.base.x2+width,numupdown->buttonUp.base.y2,BASE_COLOR);
- tft_print_formatted(numupdown->buttonDown.base.x2+2+tft_font_width(0)/2,numupdown->y+tft_font_height(0)/2,numupdown->fgcolor,BASE_COLOR,0,"%*d",tw1,numupdown->value);
-}
-
-
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/gui/numupdown.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-30 timolang@gmail.com 76ea9d8 Added num up down support.
+* 2015-04-30 timolang@gmail.com b491b78 Made numupdown horizontal
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+* 2015-05-17 timolang@gmail.com 2d46336 Improved comments in implementation of button, checkbox, numupdown, tft, touch and screen modules/submodules.
+*
+**************************************************************************************************************************************/
+
+#include "tft.h"
+#include "touch.h"
+#include "button.h"
+#include "numupdown.h"
+#include //for sprintf
+#include //for offsetof macro
+#include //for abs
+
+/* The idea is as follows:
+ * When the user add's a numupdown we create two buttons, one with a plus and one with a minus sign in it
+ * When the user presses one of the buttons we check and increase the value and execute the provided user callback
+ */
+
+
+#define BASE_COLOR RGB(90,90,90) //Background color for the whole element
+
+//Callback which is called when the user presses the "plus" button
+void button_up_cb(void* button)
+{
+ //Get the pointer to the numupdown: subtract the offset of the buttonUp member in the struct from the button pointer
+ NUMUPDOWN_STRUCT* element = button - offsetof(NUMUPDOWN_STRUCT, buttonUp);
+
+ if (element->value < element->max) { //old value lies below the maximum
+ element->value++; //let's increase the value
+ gui_numupdown_update(element); //and redraw everything
+
+ if (element->callback != NULL) { //the user provided a callback
+ element->callback(element, element->value); //Call the user callback with the new value
+ }
+ }
+}
+
+//Callback which is called when the user presses the "minus" button
+void button_down_cb(void* button)
+{
+ //Get the pointer to the numupdown: subtract the offset of the buttonDown member in the struct from the button pointer
+ NUMUPDOWN_STRUCT* element = button - offsetof(NUMUPDOWN_STRUCT, buttonDown);
+
+ if (element->value > element->min) { //old value lies above the minimum
+ element->value--; //let's decrease the value
+ gui_numupdown_update(element); //and redraw everything
+
+ if (element->callback != NULL) { //the user provided a callback
+ element->callback(element, element->value); //Call the user callback with the new value
+ }
+ }
+}
+
+//Method to calculate the number of characters needed to print the provided number in decimal notation (with optional sign)
+static uint8_t calc_text_width(int16_t val)
+{
+ uint8_t width = 1 + (val < 0); //1 if positive, 2 if negative (to let space for sign)
+ val = abs(val); //Make the number positive
+
+ while (val >= 10) { //while we have two or more digits
+ val /= 10; //remove one digit
+ width++; //add one character
+ }
+
+ return width;
+}
+
+
+bool gui_numupdown_add(NUMUPDOWN_STRUCT* numupdown)
+{
+ if (touch_have_empty(2)) { //Check if the touch module can handle two additional areas
+ if (numupdown->min > numupdown->max) { //min is bigger than max?
+ return false; //invalid parameter
+ }
+
+ if (numupdown->value < numupdown->min) { //value is smaller than min?
+ numupdown->value = numupdown->min; //normalize value
+ } else if (numupdown->value > numupdown->max) { //value is bigger than max?
+ numupdown->value = numupdown->max; //normalize value
+ }
+
+ uint8_t tw1 = calc_text_width(numupdown->max); //Calculate character width to render maximum value
+ uint8_t tw2 = calc_text_width(numupdown->min); //Calculate character width to render minimum value
+
+ if (tw2 > tw1) {
+ tw1 = tw2; //ensure tw1 contains the larger number of the two
+ }
+
+ uint8_t width = tft_font_width(0) * (tw1 + 1); //Calculate width of the number area
+
+ //Add "minus" button to the left side of the number area
+ numupdown->buttonDown.base.x1 = numupdown->x;
+ numupdown->buttonDown.base.y1 = numupdown->y;
+ numupdown->buttonDown.base.x2 = AUTO;
+ numupdown->buttonDown.base.y2 = numupdown->y + tft_font_height(0) * 2;
+ numupdown->buttonDown.text = "-";
+ numupdown->buttonDown.font = 0;
+ numupdown->buttonDown.bgcolor = BASE_COLOR;
+ numupdown->buttonDown.txtcolor = WHITE;
+ numupdown->buttonDown.callback = button_down_cb;
+ gui_button_add(&numupdown->buttonDown);
+
+ //Add "plus" button to the right side of the number area
+ numupdown->buttonUp.base.x1 = numupdown->buttonDown.base.x2 + width + 2;
+ numupdown->buttonUp.base.y1 = numupdown->y;
+ numupdown->buttonUp.base.x2 = AUTO;
+ numupdown->buttonUp.base.y2 = numupdown->y + tft_font_height(0) * 2;
+ numupdown->buttonUp.text = "+";
+ numupdown->buttonUp.font = 0;
+ numupdown->buttonUp.bgcolor = BASE_COLOR;
+ numupdown->buttonUp.txtcolor = WHITE;
+ numupdown->buttonUp.callback = button_up_cb;
+ gui_button_add(&numupdown->buttonUp);
+
+ //Draw background and label of the number area
+ tft_fill_rectangle(numupdown->buttonDown.base.x2 + 2, numupdown->y, numupdown->buttonDown.base.x2 + width, numupdown->buttonUp.base.y2, BASE_COLOR);
+ tft_print_formatted(numupdown->buttonDown.base.x2 + 2 + tft_font_width(0) / 2, numupdown->y + tft_font_height(0) / 2, numupdown->fgcolor, BASE_COLOR, 0, "%*d", tw1, numupdown->value);
+
+ return true;
+ }
+
+ return false; //not enough touch areas left
+}
+
+void gui_numupdown_remove(NUMUPDOWN_STRUCT* numupdown)
+{
+ //remove the two buttons, we have no other allocated resources
+ gui_button_remove(&numupdown->buttonUp);
+ gui_button_remove(&numupdown->buttonDown);
+}
+
+
+void gui_numupdown_redraw(NUMUPDOWN_STRUCT* numupdown)
+{
+ //redraw the two buttons
+ gui_button_redraw(&numupdown->buttonUp);
+ gui_button_redraw(&numupdown->buttonDown);
+
+ //call update method which will take care of the number-area rendering
+ gui_numupdown_update(numupdown);
+}
+
+void gui_numupdown_update(NUMUPDOWN_STRUCT* numupdown)
+{
+ //Calculate the number area width again (see above)
+ uint8_t tw1 = calc_text_width(numupdown->max);
+ uint8_t tw2 = calc_text_width(numupdown->min);
+
+ if (tw2 > tw1) {
+ tw1 = tw2;
+ }
+
+ uint8_t width = tft_font_width(0) * (tw1 + 1);
+
+ //Draw background and label of the number area
+ tft_fill_rectangle(numupdown->buttonDown.base.x2 + 2, numupdown->y, numupdown->buttonDown.base.x2 + width, numupdown->buttonUp.base.y2, BASE_COLOR);
+ tft_print_formatted(numupdown->buttonDown.base.x2 + 2 + tft_font_width(0) / 2, numupdown->y + tft_font_height(0) / 2, numupdown->fgcolor, BASE_COLOR, 0, "%*d", tw1, numupdown->value);
+}
diff --git a/common/gui/numupdown.h b/common/gui/numupdown.h
index 5734787..80716b9 100644
--- a/common/gui/numupdown.h
+++ b/common/gui/numupdown.h
@@ -1,73 +1,88 @@
-#ifndef NUMUPDOWN_H
-#define NUMUPDOWN_H
-
-#include "button.h"
-
-/**
- * @addtogroup gui
- */
-/*@{*/
-
-/**
- * @defgroup numupdown NummericUpDown
- * The NummericUpDown Gui Element
- */
-/*@}*/
-
-/**
- * @addtogroup numupdown
- */
-/*@{*/
-
-/**
- * Prototype for Event Listeners (called when the NummericUpDown value has changed)
- * \note You should NOT execute long running things in this callback nor should you update the gui. But you can call gui_screen_navigate() for instance.
- * @param numupdown The pointer to the NUMUPDOWN_STRUCT where to corresponding NummericUpDown has changed it's value
- * @param value The new value of the NummericUpDown
- */
-typedef void (*NUMUPDOWN_CALLBACK)(void *numupdown, int16_t value);
-
-/**
- * Structure to configure the NummericUpDown
- */
-typedef struct {
- uint16_t x; //!< The x-Coordinate of the Top-Left Starting Point.
- uint16_t y; //!< The y-Coordinate of the Top-Left Starting Point.
- uint16_t fgcolor; //!< The 16-bit color of the value-text
- int16_t value; //!< The current/default value
- int16_t min; //!< The minimum possible value (inclusive)
- int16_t max; //!< The maximum possible value (inclusive)
- NUMUPDOWN_CALLBACK callback; //!< Callback which is executed when the value changes
-
- BUTTON_STRUCT buttonUp; //!< For internal use, don't change, don't initialize
- BUTTON_STRUCT buttonDown; //!< For internal use, don't change, don't initialize
-} NUMUPDOWN_STRUCT;
-
-/**
- * Adds a NummericUpDown. Your Callback will be called from now on, if the numupdown's value changes
- * @param numupdown A Pointer to the preinitialized NUMUPDOWN_STRUCT
- * @return true on success
- */
-bool gui_numupdown_add(NUMUPDOWN_STRUCT* numupdown);
-
-/**
- * Removes the NummericUpDown. You will no longer receive events for this numupdown. This function will not overdraw the region where the numupdown was located.
- * @param numupdown A Pointer to the NUMUPDOWN_STRUCT
- */
-void gui_numupdown_remove(NUMUPDOWN_STRUCT* numupdown);
-
-/**
- * Updates the NummericUpDown. Call this function when you change the value/min/max of the numupdown through code.
- * @param numupdown A Pointer to the NUMUPDOWN_STRUCT
- */
-void gui_numupdown_update(NUMUPDOWN_STRUCT* numupdown);
-
-/**
- * Redraws the NummericUpDown. Call this method if you have to redraw the entire screen or if you want to draw a numupdown on top of an image.
- * @param numupdown A Pointer to the NUMUPDOWN_STRUCT
- */
-void gui_numupdown_redraw(NUMUPDOWN_STRUCT* numupdown);
-
-/*@}*/
-
-#endif /* NUMUPDOWN_H */
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/gui/numupdown.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-30 timolang@gmail.com 76ea9d8 Added num up down support.
+* 2015-05-11 timolang@gmail.com 08d9fe0 More work on doxygen module structure
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+*
+**************************************************************************************************************************************/
+
+#ifndef NUMUPDOWN_H
+#define NUMUPDOWN_H
+
+#include "button.h"
+
+/**
+ * @addtogroup gui
+ */
+/*@{*/
+
+/**
+ * @defgroup numupdown NummericUpDown
+ * The NummericUpDown Gui Element
+ */
+/*@}*/
+
+/**
+ * @addtogroup numupdown
+ */
+/*@{*/
+
+/**
+ * Prototype for Event Listeners (called when the NummericUpDown value has changed)
+ * \note You should NOT execute long running things in this callback nor should you update the gui. But you can call gui_screen_navigate() for instance.
+ * @param numupdown The pointer to the NUMUPDOWN_STRUCT where to corresponding NummericUpDown has changed it's value
+ * @param value The new value of the NummericUpDown
+ */
+typedef void (*NUMUPDOWN_CALLBACK)(void* numupdown, int16_t value);
+
+/**
+ * Structure to configure the NummericUpDown
+ */
+typedef struct {
+ uint16_t x; //!< The x-Coordinate of the Top-Left Starting Point.
+ uint16_t y; //!< The y-Coordinate of the Top-Left Starting Point.
+ uint16_t fgcolor; //!< The 16-bit color of the value-text
+ int16_t value; //!< The current/default value
+ int16_t min; //!< The minimum possible value (inclusive)
+ int16_t max; //!< The maximum possible value (inclusive)
+ NUMUPDOWN_CALLBACK callback; //!< Callback which is executed when the value changes
+
+ BUTTON_STRUCT buttonUp; //!< For internal use, don't change, don't initialize
+ BUTTON_STRUCT buttonDown; //!< For internal use, don't change, don't initialize
+} NUMUPDOWN_STRUCT;
+
+/**
+ * Adds a NummericUpDown. Your Callback will be called from now on, if the numupdown's value changes
+ * @param numupdown A Pointer to the preinitialized NUMUPDOWN_STRUCT
+ * @return true on success
+ */
+bool gui_numupdown_add(NUMUPDOWN_STRUCT* numupdown);
+
+/**
+ * Removes the NummericUpDown. You will no longer receive events for this numupdown. This function will not overdraw the region where the numupdown was located.
+ * @param numupdown A Pointer to the NUMUPDOWN_STRUCT
+ */
+void gui_numupdown_remove(NUMUPDOWN_STRUCT* numupdown);
+
+/**
+ * Updates the NummericUpDown. Call this function when you change the value/min/max of the numupdown through code.
+ * @param numupdown A Pointer to the NUMUPDOWN_STRUCT
+ */
+void gui_numupdown_update(NUMUPDOWN_STRUCT* numupdown);
+
+/**
+ * Redraws the NummericUpDown. Call this method if you have to redraw the entire screen or if you want to draw a numupdown on top of an image.
+ * @param numupdown A Pointer to the NUMUPDOWN_STRUCT
+ */
+void gui_numupdown_redraw(NUMUPDOWN_STRUCT* numupdown);
+
+/*@}*/
+
+#endif /* NUMUPDOWN_H */
diff --git a/common/gui/screen.c b/common/gui/screen.c
index 8eb3072..2f97f98 100644
--- a/common/gui/screen.c
+++ b/common/gui/screen.c
@@ -1,3 +1,21 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/gui/screen.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
+* 2015-04-27 timolang@gmail.com 77e6d0e Fixed screen implementation.
+* 2015-05-10 timolang@gmail.com b6ab7c8 Fixed compiler warning in tft and screen module.
+* 2015-05-17 timolang@gmail.com 2d46336 Improved comments in implementation of button, checkbox, numupdown, tft, touch and screen modules/submodules.
+* 2015-06-01 timolang@gmail.com eb573bc Finalized calibration. Fixed a bug in screen module.
+* 2015-06-06 timolang@gmail.com c06661d Fixed some outdated comments in source code. Documented Gui Module in docu.
+*
+**************************************************************************************************************************************/
+
#include "screen.h"
/* The idea is as follows:
@@ -14,62 +32,79 @@ static SCREEN_STRUCT* screen_list = NULL; //Head of the linked list which stores
static SCREEN_STRUCT* screen_current = NULL; //Pointer to the current screen (= tail of the list)
static volatile SCREEN_STRUCT* screen_goto = NULL; //Screen we should navigate to once we enter the gui_screen_update() method again
-SCREEN_STRUCT* gui_screen_get_current() {
- return screen_current;
+SCREEN_STRUCT* gui_screen_get_current()
+{
+ return screen_current;
}
-void gui_screen_update() {
- if(screen_goto!=NULL) { //we received the task to switch the screen
- SCREEN_STRUCT* go = (SCREEN_STRUCT*) screen_goto; //Backup volatile variable
- screen_goto=NULL; //reset the "goto instruction", since we're processing it now
- if(go->next!=NULL) { //The screen is not the last in the list, so we're going back
- if(go->next!=screen_current) { //this condition should always be false
- return; //list corrupted?
- }
- screen_current->on_leave(screen_current); //let the current screen free/unregister it's resources
- go->next=NULL; //remove the current screen from the list
- } else { //we're going forward (to a new screen)
- if(screen_current!=NULL) { //this is not the first screen
- screen_current->on_leave(screen_current); //let the current screen free/unregister it's resources
- screen_current->next = go; //append the new screen to the end of the list
- } else { //first screen ever seen
- screen_list=go; //set the new screen as list-head
- }
- }
- go->on_enter(go); //let the new screen allocate/register it's resources
- screen_current = go; //the new screen is now the current screen. Transition done
- }
+void gui_screen_update()
+{
+ if (screen_goto != NULL) { //we received the task to switch the screen
+ SCREEN_STRUCT* go = (SCREEN_STRUCT*) screen_goto; //Backup volatile variable
+ screen_goto = NULL; //reset the "goto instruction", since we're processing it now
- if(screen_current!=NULL) { //A screen has been set
- screen_current->on_update(screen_current); //Update current screen
- }
+ if (go->next != NULL) { //The screen is not the last in the list, so we're going back
+ if (go->next != screen_current) { //this condition should always be false
+ return; //list corrupted?
+ }
+
+ screen_current->on_leave(screen_current); //let the current screen free/unregister it's resources
+ go->next = NULL; //remove the current screen from the list
+ } else { //we're going forward (to a new screen)
+ if (screen_current != NULL) { //this is not the first screen
+ screen_current->on_leave(screen_current); //let the current screen free/unregister it's resources
+ screen_current->next = go; //append the new screen to the end of the list
+ } else { //first screen ever seen
+ screen_list = go; //set the new screen as list-head
+ }
+ }
+
+ go->on_enter(go); //let the new screen allocate/register it's resources
+ screen_current = go; //the new screen is now the current screen. Transition done
+ }
+
+ if (screen_current != NULL) { //A screen has been set
+ screen_current->on_update(screen_current); //Update current screen
+ }
}
-bool gui_screen_navigate(SCREEN_STRUCT* screen) {
- if(screen==NULL || screen==screen_current || screen==screen_goto) { //invalid argument passed
- return false;
- }
- screen->next = NULL; //this will become the new tail of the list, so the next pointer must be NULL
- screen_goto=screen; //"send message" to main loop, to switch the screen
- return true;
+bool gui_screen_navigate(SCREEN_STRUCT* screen)
+{
+ if (screen == NULL || screen == screen_current || screen == screen_goto) { //invalid argument passed
+ return false;
+ }
+
+ screen->next = NULL; //this will become the new tail of the list, so the next pointer must be NULL
+ screen_goto = screen; //"send message" to main loop, to switch the screen
+ return true;
}
-bool gui_screen_back() {
- if(screen_list==NULL) { //the list head is emtpy, nothing to go back to
- return false;
- }
- SCREEN_STRUCT* current = screen_list;
- SCREEN_STRUCT* last = NULL;
- //Find second last element in list
- while(current->next != NULL) {
- last = current;
- current = current->next;
- }
- if(last==NULL) return false; //There's only a single screen, there's no going back here
- if(current!=screen_current) return false; //The last entry in the list is not the current screen. List corrupted?
- screen_goto=last; //"send message" to main loop, to switch the screen
- return true;
+bool gui_screen_back()
+{
+ if (screen_list == NULL) { //the list head is emtpy, nothing to go back to
+ return false;
+ }
+
+ SCREEN_STRUCT* current = screen_list;
+ SCREEN_STRUCT* last = NULL;
+
+ //Find second last element in list
+ while (current->next != NULL) {
+ last = current;
+ current = current->next;
+ }
+
+ if (last == NULL) {
+ return false; //There's only a single screen, there's no going back here
+ }
+
+ if (current != screen_current) {
+ return false; //The last entry in the list is not the current screen. List corrupted?
+ }
+
+ screen_goto = last; //"send message" to main loop, to switch the screen
+ return true;
}
diff --git a/common/gui/screen.h b/common/gui/screen.h
index 8ef82a2..f14a0b5 100644
--- a/common/gui/screen.h
+++ b/common/gui/screen.h
@@ -1,3 +1,21 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/gui/screen.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com cf72baa Introduced a Screen (sub) module and divided app into multiple screens.
+* 2015-04-27 timolang@gmail.com 77e6d0e Fixed screen implementation.
+* 2015-05-11 timolang@gmail.com 08d9fe0 More work on doxygen module structure
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+* 2015-05-17 timolang@gmail.com 2d46336 Improved comments in implementation of button, checkbox, numupdown, tft, touch and screen modules/submodules.
+* 2015-06-06 timolang@gmail.com c06661d Fixed some outdated comments in source code. Documented Gui Module in docu.
+*
+**************************************************************************************************************************************/
+
#ifndef SCREEN_H
#define SCREEN_H
@@ -12,7 +30,7 @@
/**
* @defgroup screen Screen
* The Screen Submodule provides an api to navigate between different "screens" on the UI.
- * Each screen must provide an enter, update and a leave method; which will be called from this module at the right time.
+ * Each screen must provide an enter, update and a leave method; which will be called from this module at the right time.
* The implemented screens of the application are documented in the \ref screens module.
*/
/*@}*/
@@ -31,12 +49,12 @@ typedef void (*SCREEN_CALLBACK)(void* screen);
/**
* Structure to configure the Screen
*/
-typedef struct SCREEN_S{
- SCREEN_CALLBACK on_enter; //!< The Callback which is called when the screen is entered. Add/Register all UI-Elements here
- SCREEN_CALLBACK on_leave; //!< The Callback which is called when the screen is left. Remove/Unregister all UI-Elements here
- SCREEN_CALLBACK on_update; //!< The Callback which is called repeatedly when the screen should be updated. Update/Redraw all UI-Elements here
+typedef struct SCREEN_S {
+ SCREEN_CALLBACK on_enter; //!< The Callback which is called when the screen is entered. Add/Register all UI-Elements here
+ SCREEN_CALLBACK on_leave; //!< The Callback which is called when the screen is left. Remove/Unregister all UI-Elements here
+ SCREEN_CALLBACK on_update; //!< The Callback which is called repeatedly when the screen should be updated. Update/Redraw all UI-Elements here
- struct SCREEN_S* next; //!< Used internally. do not modify, do not initialize
+ struct SCREEN_S* next; //!< Used internally. do not modify, do not initialize
} SCREEN_STRUCT;
diff --git a/common/lowlevel/ll_filesystem.h b/common/lowlevel/ll_filesystem.h
index 8833b1f..e1d2f08 100644
--- a/common/lowlevel/ll_filesystem.h
+++ b/common/lowlevel/ll_filesystem.h
@@ -1,3 +1,17 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/lowlevel/ll_filesystem.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-05-10 timolang@gmail.com e2bce8f Added filesystem module, tests and implementation for it in emulator.
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+*
+**************************************************************************************************************************************/
+
#include "filesystem.h"
/**
diff --git a/common/lowlevel/ll_system.h b/common/lowlevel/ll_system.h
index be422fb..6166283 100644
--- a/common/lowlevel/ll_system.h
+++ b/common/lowlevel/ll_system.h
@@ -1,3 +1,21 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/lowlevel/ll_system.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 1f2af9f Added more tft functions to common and emulator. Fixed eventloop.
+* 2015-04-03 timolang@gmail.com cab8609 Integrated pixy into emulator. Pixy is no longer in the common/libs folder but in emulator/libs and discovery/libs
+* 2015-04-03 timolang@gmail.com 9a1d12a Refactored discovery, to use new project structure. Almost ready.
+* 2015-04-25 timolang@gmail.com 3d1e4b2 Simplified code a bit. Emulator does not work stable when replugging pixy.
+* 2015-04-25 timolang@gmail.com 0858b0d Fixed some bugs when receiving large data.
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+*
+**************************************************************************************************************************************/
+
#include
#include
diff --git a/common/lowlevel/ll_tft.h b/common/lowlevel/ll_tft.h
index d7ac730..52a5168 100644
--- a/common/lowlevel/ll_tft.h
+++ b/common/lowlevel/ll_tft.h
@@ -1,3 +1,24 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/lowlevel/ll_tft.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 51089aa Refactored Project Structure for use with emulator
+* 2015-04-03 timolang@gmail.com 1f2af9f Added more tft functions to common and emulator. Fixed eventloop.
+* 2015-04-03 timolang@gmail.com 9a1d12a Refactored discovery, to use new project structure. Almost ready.
+* 2015-04-03 timolang@gmail.com 1aa9194 Fixed Drawing of rects in Emulator. Got frames from pixy to emulator. Slooooow.
+* 2015-04-27 aaron@duckpond.ch aed90ef Drawcircle added (emulator)
+* 2015-04-27 timolang@gmail.com e249fb2 Added font support
+* 2015-04-27 aaron@duckpond.ch f0a6c3b Implemented init functions for gpio, fsmc and display
+* 2015-04-27 aaron@duckpond.ch 0b61f21 Fixed misplacement of prototypes in ll_tft.h and implemented a propper init function.
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+*
+**************************************************************************************************************************************/
+
#include
#include
@@ -24,10 +45,10 @@ bool ll_tft_init();
// draw functions
void ll_tft_clear(uint16_t color);
void ll_tft_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
-void ll_tft_draw_pixel(uint16_t x,uint16_t y,uint16_t color);
-void ll_tft_draw_rectangle(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2, uint16_t color);
-void ll_tft_fill_rectangle(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2, uint16_t color);
-void ll_tft_draw_bitmap_unscaled(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t *dat);
+void ll_tft_draw_pixel(uint16_t x, uint16_t y, uint16_t color);
+void ll_tft_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
+void ll_tft_fill_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
+void ll_tft_draw_bitmap_unscaled(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t* dat);
void ll_tft_draw_circle(uint16_t x, uint16_t y, uint16_t r, uint16_t color);
@@ -37,5 +58,3 @@ uint8_t ll_tft_font_width(uint8_t fontnum);
void ll_tft_draw_char(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t font, char c);
/*@}*/
-
-
diff --git a/common/lowlevel/ll_touch.h b/common/lowlevel/ll_touch.h
index c61b42e..4c5237b 100644
--- a/common/lowlevel/ll_touch.h
+++ b/common/lowlevel/ll_touch.h
@@ -1,3 +1,17 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/lowlevel/ll_touch.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com 259d446 Added touch support to emulator. Implemented basic touch function.
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+*
+**************************************************************************************************************************************/
+
#include
#include
diff --git a/common/system/system.c b/common/system/system.c
index f7a88cb..48d84d0 100644
--- a/common/system/system.c
+++ b/common/system/system.c
@@ -1,19 +1,39 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/system/system.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 1f2af9f Added more tft functions to common and emulator. Fixed eventloop.
+* 2015-04-03 timolang@gmail.com cab8609 Integrated pixy into emulator. Pixy is no longer in the common/libs folder but in emulator/libs and discovery/libs
+* 2015-04-25 timolang@gmail.com 3d1e4b2 Simplified code a bit. Emulator does not work stable when replugging pixy.
+* 2015-04-25 timolang@gmail.com 0858b0d Fixed some bugs when receiving large data.
+*
+**************************************************************************************************************************************/
+
#include "system.h"
#include "ll_system.h"
-bool system_init() {
- return ll_system_init();
+bool system_init()
+{
+ return ll_system_init();
}
-void system_delay(uint32_t msec) {
- ll_system_delay(msec);
+void system_delay(uint32_t msec)
+{
+ ll_system_delay(msec);
}
-void system_process() {
- ll_system_process();
+void system_process()
+{
+ ll_system_process();
}
-void system_toggle_led() {
- ll_system_toggle_led();
+void system_toggle_led()
+{
+ ll_system_toggle_led();
}
diff --git a/common/system/system.h b/common/system/system.h
index 7c22a68..53a06c3 100644
--- a/common/system/system.h
+++ b/common/system/system.h
@@ -1,3 +1,21 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/system/system.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 1f2af9f Added more tft functions to common and emulator. Fixed eventloop.
+* 2015-04-03 timolang@gmail.com cab8609 Integrated pixy into emulator. Pixy is no longer in the common/libs folder but in emulator/libs and discovery/libs
+* 2015-04-25 timolang@gmail.com 3d1e4b2 Simplified code a bit. Emulator does not work stable when replugging pixy.
+* 2015-04-25 timolang@gmail.com 0858b0d Fixed some bugs when receiving large data.
+* 2015-05-11 timolang@gmail.com 08d9fe0 More work on doxygen module structure
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+*
+**************************************************************************************************************************************/
+
#ifndef SYSTEM_H
#define SYSTEM_H
diff --git a/common/tft/tft.c b/common/tft/tft.c
index 0b5679a..6b6f4d0 100644
--- a/common/tft/tft.c
+++ b/common/tft/tft.c
@@ -1,3 +1,24 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/tft/tft.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 51089aa Refactored Project Structure for use with emulator
+* 2015-04-03 timolang@gmail.com 1f2af9f Added more tft functions to common and emulator. Fixed eventloop.
+* 2015-04-03 timolang@gmail.com 1aa9194 Fixed Drawing of rects in Emulator. Got frames from pixy to emulator. Slooooow.
+* 2015-04-27 aaron@duckpond.ch aed90ef Drawcircle added (emulator)
+* 2015-04-27 timolang@gmail.com e249fb2 Added font support
+* 2015-04-30 timolang@gmail.com 76ea9d8 Added num up down support.
+* 2015-05-10 timolang@gmail.com b6ab7c8 Fixed compiler warning in tft and screen module.
+* 2015-05-15 timolang@gmail.com b08a897 Added tft method to draw a bmp from filesystem. Added another font to emulator.
+* 2015-05-17 timolang@gmail.com 2d46336 Improved comments in implementation of button, checkbox, numupdown, tft, touch and screen modules/submodules.
+*
+**************************************************************************************************************************************/
+
#include "tft.h"
#include "ll_tft.h"
#include
@@ -15,129 +36,148 @@
* For formatted printing implement putchar, instead of writing into a buffer and drawing that buffer afterwards
*/
-bool tft_init() {
- return ll_tft_init();
+bool tft_init()
+{
+ return ll_tft_init();
}
-void tft_clear(uint16_t color) {
- ll_tft_clear(color);
+void tft_clear(uint16_t color)
+{
+ ll_tft_clear(color);
}
-void tft_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) {
- ll_tft_draw_line(x1,y1,x2,y2,color);
+void tft_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
+{
+ ll_tft_draw_line(x1, y1, x2, y2, color);
}
-void tft_draw_pixel(uint16_t x,uint16_t y,uint16_t color) {
- ll_tft_draw_pixel(x,y,color);
+void tft_draw_pixel(uint16_t x, uint16_t y, uint16_t color)
+{
+ ll_tft_draw_pixel(x, y, color);
}
-void tft_draw_rectangle(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2, uint16_t color) {
- //could be implemented with 4 lines instead of introducing a ll func
- ll_tft_draw_rectangle(x1,y1,x2,y2,color);
+void tft_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
+{
+ //could be implemented with 4 lines instead of introducing a ll func
+ ll_tft_draw_rectangle(x1, y1, x2, y2, color);
}
-void tft_fill_rectangle(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2, uint16_t color) {
- ll_tft_fill_rectangle(x1,y1,x2,y2,color);
+void tft_fill_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
+{
+ ll_tft_fill_rectangle(x1, y1, x2, y2, color);
}
-void tft_draw_bitmap_unscaled(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t* dat) {
- ll_tft_draw_bitmap_unscaled(x,y,width,height,dat);
+void tft_draw_bitmap_unscaled(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t* dat)
+{
+ ll_tft_draw_bitmap_unscaled(x, y, width, height, dat);
}
-void tft_draw_circle(uint16_t x, uint16_t y, uint16_t r, uint16_t color) {
+void tft_draw_circle(uint16_t x, uint16_t y, uint16_t r, uint16_t color)
+{
ll_tft_draw_circle(x, y, r, color);
}
-uint8_t tft_num_fonts() {
- return ll_tft_num_fonts();
+uint8_t tft_num_fonts()
+{
+ return ll_tft_num_fonts();
}
-uint8_t tft_font_height(uint8_t fontnum) {
- return ll_tft_font_height(fontnum);
+uint8_t tft_font_height(uint8_t fontnum)
+{
+ return ll_tft_font_height(fontnum);
}
-uint8_t tft_font_width(uint8_t fontnum) {
- return ll_tft_font_width(fontnum);
+uint8_t tft_font_width(uint8_t fontnum)
+{
+ return ll_tft_font_width(fontnum);
}
//Print line can be done with multiple calls to draw_char
-void tft_print_line(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t font, const char* text) {
- if(font>=ll_tft_num_fonts()) return; //invalid font index
- for(int i=0; i= ll_tft_num_fonts()) {
+ return; //invalid font index
+ }
+
+ for (int i = 0; i < strlen(text); i++) { //for each char in the line
+ ll_tft_draw_char(x, y, color, bgcolor, font, text[i]); //draw the char
+ x += ll_tft_font_width(font); //and increase the x position
+ }
}
//Printing a formatted line can be done by printing the line in a buffer using "sprintf" and then calling print_line
-void tft_print_formatted(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t font, const char* format, ...) {
- static char buffer[128]; //buffer to save the formatted text into
+void tft_print_formatted(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t font, const char* format, ...)
+{
+ static char buffer[128]; //buffer to save the formatted text into
- //Since we have variable arguments, we need to forward them. We have to use vsprintf instead of sprintf for that.
- va_list args;
- va_start (args, format); //start the varg-list
- vsprintf(buffer,format,args); //let vsprintf render the formatted string
- tft_print_line(x,y,color,bgcolor,font,buffer); //print the string as normal text
- va_end(args); //end the varg-list
+ //Since we have variable arguments, we need to forward them. We have to use vsprintf instead of sprintf for that.
+ va_list args;
+ va_start(args, format); //start the varg-list
+ vsprintf(buffer, format, args); //let vsprintf render the formatted string
+ tft_print_line(x, y, color, bgcolor, font, buffer); //print the string as normal text
+ va_end(args); //end the varg-list
}
-bool tft_draw_bitmap_file_unscaled(uint16_t x, uint16_t y, const char* filename) {
- //This method reads a .bmp file from the filesystem and tries to draw it.
- //Note: The bmp implementation is not complete, it has some limitations and it makes assumptions. See doxygen comment for this method.
- //Source Copied and adapted from: http://stackoverflow.com/a/17040962/2606757
+bool tft_draw_bitmap_file_unscaled(uint16_t x, uint16_t y, const char* filename)
+{
+ //This method reads a .bmp file from the filesystem and tries to draw it.
+ //Note: The bmp implementation is not complete, it has some limitations and it makes assumptions. See doxygen comment for this method.
+ //Source Copied and adapted from: http://stackoverflow.com/a/17040962/2606757
- FILE_HANDLE* file = filesystem_file_open(filename); //try to open the file
- if(file==NULL) { //file opening failed
- return false;
- }
+ FILE_HANDLE* file = filesystem_file_open(filename); //try to open the file
- unsigned char info[54];
- if(filesystem_file_read(file,info,54)!=F_OK) { //try to read the 54 byte header
- filesystem_file_close(file);
- return false; //reading the header failed
- }
+ if (file == NULL) { //file opening failed
+ return false;
+ }
- // extract image height and width from header
- uint32_t width = *(uint32_t*)&info[18]; //width in pixel
- uint32_t height = *(uint32_t*)&info[22]; //height in pixel
- uint16_t depth = *(uint16_t*)&info[28]; //bit's per pixel (color depth)
- depth/=8; //we want the number of bytes per pixel
+ unsigned char info[54];
- filesystem_file_seek(file,*(uint32_t*)&info[10]); //seek to the place where img data begins
+ if (filesystem_file_read(file, info, 54) != F_OK) { //try to read the 54 byte header
+ filesystem_file_close(file);
+ return false; //reading the header failed
+ }
- uint32_t row_padded = (width*depth + 3) & (~3); //row size must be aligned to 4 bytes
+ // extract image height and width from header
+ uint32_t width = *(uint32_t*)&info[18]; //width in pixel
+ uint32_t height = *(uint32_t*)&info[22]; //height in pixel
+ uint16_t depth = *(uint16_t*)&info[28]; //bit's per pixel (color depth)
+ depth /= 8; //we want the number of bytes per pixel
- unsigned char data [row_padded]; //allocate space for one row (incl. padding)
+ filesystem_file_seek(file, *(uint32_t*)&info[10]); //seek to the place where img data begins
- for(int i = 0; i < height; i++) //for each row
- {
- filesystem_file_read(file,data,row_padded); //read row into buffer
- for(int j = 0; j < width*depth; j += depth) //for each pixel
- {
- unsigned char a,r,g,b;
- if(depth==4) { //a,r,g,b 8bit each
- a = data[j];
- r = data[j+1];
- g = data[j+2];
- b = data[j+3];
- } else if (depth==3) { // b,g,r, 8bit each
- a = 255;
- r = data[j+2];
- g = data[j+1];
- b = data[j];
- }
+ uint32_t row_padded = (width * depth + 3) & (~3); //row size must be aligned to 4 bytes
- if(a!=0) {
- //bmp's are stored "bottom-up", so we start drawing at the bottom
- tft_draw_pixel(x+j/depth,y+height-1-i,RGB(r,g,b));
- }
- }
- }
+ unsigned char data [row_padded]; //allocate space for one row (incl. padding)
- filesystem_file_close(file);
+ for (int i = 0; i < height; i++) { //for each row
+ filesystem_file_read(file, data, row_padded); //read row into buffer
- return true;
+ for (int j = 0; j < width * depth; j += depth) { //for each pixel
+ unsigned char a, r, g, b;
+
+ if (depth == 4) { //a,r,g,b 8bit each
+ a = data[j];
+ r = data[j + 1];
+ g = data[j + 2];
+ b = data[j + 3];
+ } else if (depth == 3) { // b,g,r, 8bit each
+ a = 255;
+ r = data[j + 2];
+ g = data[j + 1];
+ b = data[j];
+ }
+
+ if (a != 0) {
+ //bmp's are stored "bottom-up", so we start drawing at the bottom
+ tft_draw_pixel(x + j / depth, y + height - 1 - i, RGB(r, g, b));
+ }
+ }
+ }
+
+ filesystem_file_close(file);
+
+ return true;
}
diff --git a/common/tft/tft.h b/common/tft/tft.h
index 40157d2..51a05ba 100644
--- a/common/tft/tft.h
+++ b/common/tft/tft.h
@@ -1,3 +1,28 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/tft/tft.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 51089aa Refactored Project Structure for use with emulator
+* 2015-04-03 timolang@gmail.com 1f2af9f Added more tft functions to common and emulator. Fixed eventloop.
+* 2015-04-03 timolang@gmail.com 1aa9194 Fixed Drawing of rects in Emulator. Got frames from pixy to emulator. Slooooow.
+* 2015-04-27 aaron@duckpond.ch aed90ef Drawcircle added (emulator)
+* 2015-04-27 timolang@gmail.com e249fb2 Added font support
+* 2015-04-30 timolang@gmail.com 76ea9d8 Added num up down support.
+* 2015-05-04 aaron@duckpond.ch c224d40 Changed display init
+* 2015-05-10 timolang@gmail.com 21edc56 Added doxyfile (doxygen) for the common folder. Started with doxygen comments for app and tft module.
+* 2015-05-11 timolang@gmail.com a175a2f Added doxygen docu for touch module
+* 2015-05-11 timolang@gmail.com 08d9fe0 More work on doxygen module structure
+* 2015-05-12 timolang@gmail.com 1402598 Added doxygen stuff for button module and some minor changes to touch, screen_main and tft module.
+* 2015-05-15 timolang@gmail.com 9a16865 Added doxgen comments to filesyste, checkbox, numupdown and screen module. And some minor changes to the other modules.
+* 2015-05-15 timolang@gmail.com b08a897 Added tft method to draw a bmp from filesystem. Added another font to emulator.
+*
+**************************************************************************************************************************************/
+
#ifndef TFT_H
#define TFT_H
@@ -69,7 +94,7 @@ void tft_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t
* @param y The y-Coordinate of the pixel
* @param color The 16-bit color to draw the pixel with
*/
-void tft_draw_pixel(uint16_t x,uint16_t y,uint16_t color);
+void tft_draw_pixel(uint16_t x, uint16_t y, uint16_t color);
/**
* Draws the outline of a rectangle onto the display.
@@ -80,7 +105,7 @@ void tft_draw_pixel(uint16_t x,uint16_t y,uint16_t color);
* @param y2 The y-Coordinate of the end-point
* @param color The 16-bit color to draw the pixel with
*/
-void tft_draw_rectangle(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2, uint16_t color);
+void tft_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
/**
* Draws a filled rectangle onto the display. The start,end points are inclusive
@@ -90,7 +115,7 @@ void tft_draw_rectangle(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2, uint16_
* @param y2 The y-Coordinate of the end-point
* @param color The 16-bit color to draw the pixel with
*/
-void tft_fill_rectangle(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2, uint16_t color);
+void tft_fill_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
/**
* Draws a bitmap onto the display without scaling/cropping.
diff --git a/common/touch/screen_calibrate.c b/common/touch/screen_calibrate.c
index c19a7bd..e38cabd 100644
--- a/common/touch/screen_calibrate.c
+++ b/common/touch/screen_calibrate.c
@@ -1,3 +1,17 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/touch/screen_calibrate.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-06-01 timolang@gmail.com 06227da Added calibrate screen (WIP). fixed bug in emulator drawing.
+* 2015-06-01 timolang@gmail.com eb573bc Finalized calibration. Fixed a bug in screen module.
+*
+**************************************************************************************************************************************/
+
#include "screen_calibrate.h"
#include "tft.h"
#include "touch.h"
@@ -6,90 +20,102 @@
extern volatile bool calibration; //from touch.c
-static void enter(void* screen) {
- tft_clear(BLACK);
+static void enter(void* screen)
+{
+ tft_clear(BLACK);
}
-static void leave(void* screen) {
+static void leave(void* screen)
+{
}
-static void update(void* screen) {
- int x1,y1,x2,y2,dx,dy;
+static void update(void* screen)
+{
+ int x1, y1, x2, y2, dx, dy;
- tft_print_line(50,50,WHITE,BLACK,1,"Calibration:");
- tft_print_line(50,120,WHITE,BLACK,0,"Hit the markers exactly!");
- //-----------------First Point--------------------
- tft_draw_line(CCENTER,CBEGIN,CCENTER,CEND,WHITE); //Draw Cross
- tft_draw_line(CBEGIN,CCENTER,CEND,CCENTER,WHITE); //Draw Cross
- calibration=1; //TouchX + TouchY Values will not be converted to Pixels
- while(calibration); //Wait on PenUp
- POINT_STRUCT p1 = touch_get_last_point();
- x1=p1.x;
- y1=p1.y;
- tft_fill_rectangle(CBEGIN,CBEGIN,CEND,CEND,BLACK); //Clear Cross
+ tft_print_line(50, 50, WHITE, BLACK, 1, "Calibration:");
+ tft_print_line(50, 120, WHITE, BLACK, 0, "Hit the markers exactly!");
+ //-----------------First Point--------------------
+ tft_draw_line(CCENTER, CBEGIN, CCENTER, CEND, WHITE); //Draw Cross
+ tft_draw_line(CBEGIN, CCENTER, CEND, CCENTER, WHITE); //Draw Cross
+ calibration = 1; //TouchX + TouchY Values will not be converted to Pixels
- //-----------------Second Point-------------------
- tft_draw_line(DWIDTH-CCENTER,DHEIGHT-CBEGIN,DWIDTH-CCENTER,DHEIGHT-CEND,WHITE);
- tft_draw_line(DWIDTH-CBEGIN,DHEIGHT-CCENTER,DWIDTH-CEND,DHEIGHT-CCENTER,WHITE);
- calibration=1;
- while(calibration);
- POINT_STRUCT p2 = touch_get_last_point();
- x2=p2.x;
- y2=p2.y;
- tft_fill_rectangle(DWIDTH-CBEGIN,DHEIGHT-CBEGIN,DWIDTH-CEND,DHEIGHT-CEND,BLACK);
+ while (calibration); //Wait on PenUp
- //-----------------Third Point--------------------
- tft_draw_line(CCENTER,DHEIGHT-CBEGIN,CCENTER,DHEIGHT-CEND,WHITE);
- tft_draw_line(CBEGIN,DHEIGHT-CCENTER,CEND,DHEIGHT-CCENTER,WHITE);
- calibration=1;
- while(calibration);
- POINT_STRUCT p3 = touch_get_last_point();
- x1+=p3.x; //Add(!) values. We'll build the average later
- y2+=p3.y;
- tft_fill_rectangle(CBEGIN,DHEIGHT-CBEGIN,CEND,DHEIGHT-CEND,BLACK);
+ POINT_STRUCT p1 = touch_get_last_point();
+ x1 = p1.x;
+ y1 = p1.y;
+ tft_fill_rectangle(CBEGIN, CBEGIN, CEND, CEND, BLACK); //Clear Cross
- //------------------4. Point---------------------
- tft_draw_line(DWIDTH-CCENTER,CBEGIN,DWIDTH-CCENTER,CEND,WHITE);
- tft_draw_line(DWIDTH-CBEGIN,CCENTER,DWIDTH-CEND,CCENTER,WHITE);
- calibration=1;
- while(calibration);
- POINT_STRUCT p4 = touch_get_last_point();
- x2+=p4.x;
- y1+=p4.y;
- tft_fill_rectangle(DWIDTH-CBEGIN,CBEGIN,DWIDTH-CEND,CEND,BLACK);
- //-------------------Calculation---------------------
- x1++; //Add 1 and divide by 2 later = +0.5 (for correct rounding)
- y1++;
- x2++;
- y2++;
- x1>>=1; //Divide by 2
- y1>>=1;
- x2>>=1;
- y2>>=1;
- dx = (x2-x1); //Build the Difference
- dy = (y2-y1);
+ //-----------------Second Point-------------------
+ tft_draw_line(DWIDTH - CCENTER, DHEIGHT - CBEGIN, DWIDTH - CCENTER, DHEIGHT - CEND, WHITE);
+ tft_draw_line(DWIDTH - CBEGIN, DHEIGHT - CCENTER, DWIDTH - CEND, DHEIGHT - CCENTER, WHITE);
+ calibration = 1;
- touch_set_calibration_values(x1,dx,y1,dy);
- tft_print_line(50,120,WHITE,BLACK,0,"Calibration Done. Press anywhere");
+ while (calibration);
- calibration=1;
- while(calibration);
- gui_screen_back();
+ POINT_STRUCT p2 = touch_get_last_point();
+ x2 = p2.x;
+ y2 = p2.y;
+ tft_fill_rectangle(DWIDTH - CBEGIN, DHEIGHT - CBEGIN, DWIDTH - CEND, DHEIGHT - CEND, BLACK);
+
+ //-----------------Third Point--------------------
+ tft_draw_line(CCENTER, DHEIGHT - CBEGIN, CCENTER, DHEIGHT - CEND, WHITE);
+ tft_draw_line(CBEGIN, DHEIGHT - CCENTER, CEND, DHEIGHT - CCENTER, WHITE);
+ calibration = 1;
+
+ while (calibration);
+
+ POINT_STRUCT p3 = touch_get_last_point();
+ x1 += p3.x; //Add(!) values. We'll build the average later
+ y2 += p3.y;
+ tft_fill_rectangle(CBEGIN, DHEIGHT - CBEGIN, CEND, DHEIGHT - CEND, BLACK);
+
+ //------------------4. Point---------------------
+ tft_draw_line(DWIDTH - CCENTER, CBEGIN, DWIDTH - CCENTER, CEND, WHITE);
+ tft_draw_line(DWIDTH - CBEGIN, CCENTER, DWIDTH - CEND, CCENTER, WHITE);
+ calibration = 1;
+
+ while (calibration);
+
+ POINT_STRUCT p4 = touch_get_last_point();
+ x2 += p4.x;
+ y1 += p4.y;
+ tft_fill_rectangle(DWIDTH - CBEGIN, CBEGIN, DWIDTH - CEND, CEND, BLACK);
+ //-------------------Calculation---------------------
+ x1++; //Add 1 and divide by 2 later = +0.5 (for correct rounding)
+ y1++;
+ x2++;
+ y2++;
+ x1 >>= 1; //Divide by 2
+ y1 >>= 1;
+ x2 >>= 1;
+ y2 >>= 1;
+ dx = (x2 - x1); //Build the Difference
+ dy = (y2 - y1);
+
+ touch_set_calibration_values(x1, dx, y1, dy);
+ tft_print_line(50, 120, WHITE, BLACK, 0, "Calibration Done. Press anywhere");
+
+ calibration = 1;
+
+ while (calibration);
+
+ gui_screen_back();
}
static SCREEN_STRUCT screen = {
- enter,
- leave,
- update
+ enter,
+ leave,
+ update
};
-SCREEN_STRUCT* get_screen_calibrate() {
- return &screen;
+SCREEN_STRUCT* get_screen_calibrate()
+{
+ return &screen;
}
-
-
diff --git a/common/touch/screen_calibrate.h b/common/touch/screen_calibrate.h
index 107ce06..f1cbf7f 100644
--- a/common/touch/screen_calibrate.h
+++ b/common/touch/screen_calibrate.h
@@ -1,3 +1,17 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/touch/screen_calibrate.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-06-01 timolang@gmail.com 06227da Added calibrate screen (WIP). fixed bug in emulator drawing.
+* 2015-06-01 timolang@gmail.com eb573bc Finalized calibration. Fixed a bug in screen module.
+*
+**************************************************************************************************************************************/
+
#include "screen.h"
/**
diff --git a/common/touch/touch.c b/common/touch/touch.c
index fbd9d5f..0b74b57 100644
--- a/common/touch/touch.c
+++ b/common/touch/touch.c
@@ -1,3 +1,21 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: common/touch/touch.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com 259d446 Added touch support to emulator. Implemented basic touch function.
+* 2015-05-02 timolang@gmail.com 3281616 Added some more touch functions. Improved pixy test. Drag the Image around!
+* 2015-05-17 timolang@gmail.com 2d46336 Improved comments in implementation of button, checkbox, numupdown, tft, touch and screen modules/submodules.
+* 2015-06-01 timolang@gmail.com 06227da Added calibrate screen (WIP). fixed bug in emulator drawing.
+* 2015-06-01 timolang@gmail.com eb573bc Finalized calibration. Fixed a bug in screen module.
+* 2015-06-06 timolang@gmail.com c06661d Fixed some outdated comments in source code. Documented Gui Module in docu.
+*
+**************************************************************************************************************************************/
+
#include "touch.h"
#include "ll_touch.h"
#include "screen_calibrate.h"
@@ -18,184 +36,179 @@
TOUCH_AREA_STRUCT* areas[NUM_AREAS] = {NULL}; //list with pointers to all managed touch area's
volatile POINT_STRUCT pos; //the last touch point
-volatile TOUCH_STATE oldState=TOUCH_UP; //the last touch state
+volatile TOUCH_STATE oldState = TOUCH_UP; //the last touch state
volatile bool calibration = false; //whether or not we're currently calibrating
-bool use_calibration=false; //Whether or not the current platform needs calibration and recalc of the values
+bool use_calibration = false; //Whether or not the current platform needs calibration and recalc of the values
//Calibration parameters (dummy values).
-int cal_xs=10;
-int cal_dx=100;
-int cal_ys=10;
-int cal_dy=100;
+int cal_xs = 10;
+int cal_dx = 100;
+int cal_ys = 10;
+int cal_dy = 100;
-void touch_set_calibration_values(int xs, int dx, int ys, int dy) {
- cal_xs = xs;
- cal_ys = ys;
- cal_dx = dx;
- cal_dy = dy;
+void touch_set_calibration_values(int xs, int dx, int ys, int dy)
+{
+ cal_xs = xs;
+ cal_ys = ys;
+ cal_dx = dx;
+ cal_dy = dy;
}
-bool touch_init() {
- return ll_touch_init();
+bool touch_init()
+{
+ return ll_touch_init();
}
-void touch_set_value_convert_mode(bool uc) {
- use_calibration=uc;
+void touch_set_value_convert_mode(bool uc)
+{
+ use_calibration = uc;
}
-bool touch_add_raw_event(uint16_t touchX, uint16_t touchY, TOUCH_STATE state) {
- //Update current and old position/state
- bool penDown = (state==TOUCH_DOWN);
- bool oldPenDown = (oldState==TOUCH_DOWN);
- oldState=state;
+bool touch_add_raw_event(uint16_t touchX, uint16_t touchY, TOUCH_STATE state)
+{
+ //Update current and old position/state
+ bool penDown = (state == TOUCH_DOWN);
+ bool oldPenDown = (oldState == TOUCH_DOWN);
+ oldState = state;
- if(calibration) //If in Calibration mode
- {
- if(penDown)
- {
- pos.x=touchX;
- pos.y=touchY;
- }
- else
- {
- if(oldPenDown) //Run only if we got at least one pen down
- calibration=0; //Calibration finish (Touch X and Y are the values from the last measure, where the pen was down)
- }
- return true;
- }
+ if (calibration) { //If in Calibration mode
+ if (penDown) {
+ pos.x = touchX;
+ pos.y = touchY;
+ } else {
+ if (oldPenDown) { //Run only if we got at least one pen down
+ calibration = 0; //Calibration finish (Touch X and Y are the values from the last measure, where the pen was down)
+ }
+ }
- //If we reach this point we're not in calibration mode and we need to process the event and call the registred handlers..
+ return true;
+ }
- if(use_calibration) { //the underlying touch hardware uses calibration
- //Calculate the real touch position out of the passed ones, and the calibration values
- pos.x=touchX=(((long)(DWIDTH-2*CCENTER)*2*(long)((long)touchX-cal_xs)/cal_dx+1)>>1)+CCENTER;
- pos.y=touchY=(((long)(DHEIGHT-2*CCENTER)*2*(long)((long)touchY-cal_ys)/cal_dy+1)>>1)+CCENTER;
- } else { //no conversion needed for the underlying hardware
- pos.x=touchX;
- pos.y=touchY;
- }
+ //If we reach this point we're not in calibration mode and we need to process the event and call the registred handlers..
- if(penDown) //pen is down now
- {
- //tft_draw_pixel(touchX,touchY,WHITE);
- if(!oldPenDown) //pen wasn't down before (positive edge) => First Touch
- {
- for(int z=0; z < NUM_AREAS; z++) // For every touch area
- {
- //Check if pos is inside area
- if(areas[z]!=NULL && touchX >= areas[z]->x1 && touchX <= areas[z]->x2 && touchY >= areas[z]->y1 && touchY <= areas[z]->y2 )
- {
- areas[z]->flags=1; //Save PenInside=1
- if(areas[z]->hookedActions & PEN_DOWN) //The user wants to receive pen down events
- areas[z]->callback(areas[z],PEN_DOWN); //Send event to user callback
- }
- }
- }
- else //Pen was down before => Second, Third event in row
- {
- for(int z=0; z < NUM_AREAS; z++) // For every touch area
- {
- if(areas[z]!=NULL )
- {
- //Check if pos is inside area
- if(touchX >= areas[z]->x1 && touchX <= areas[z]->x2 && touchY >= areas[z]->y1 && touchY <= areas[z]->y2)
- {
- if(areas[z]->flags==0) //Pen was not inside before (PenInside==0)
- {
- areas[z]->flags=1; //Pen is inside now (PenInside=1)
- if(areas[z]->hookedActions & PEN_ENTER) //The user wants to receive pen enter events
- areas[z]->callback(areas[z],PEN_ENTER);
- }
- }
- else if(areas[z]->flags) //Pos not inside area, but it was before (PenInside==1)
- {
- areas[z]->flags=0; //Pen is no longer inside (PenInside=0)
- if(areas[z]->hookedActions & PEN_LEAVE) //The user wants to receive pen leave events
- areas[z]->callback(areas[z],PEN_LEAVE);
- }
- }
- }
- }
- for(int z=0; z < NUM_AREAS; z++) // For every touch area
- {
- if(areas[z]!=NULL && (areas[z]->hookedActions&PEN_MOVE)) //User want's to receive pen move events
- {
- //Check if pos is inside area
- if(touchX >= areas[z]->x1 && touchX <= areas[z]->x2 && touchY >= areas[z]->y1 && touchY <= areas[z]->y2)
- {
- areas[z]->callback(areas[z],PEN_MOVE);
- }
- }
- }
- }
- else //pen is not down now
- {
- if(oldPenDown) //but it was down before (negative edge)
- {
- for(int z=0; z < NUM_AREAS; z++) // For every touch area
- {
- //Check if pos is inside area
- if(areas[z]!=NULL && touchX >= areas[z]->x1 && touchX <= areas[z]->x2 && touchY >= areas[z]->y1 && touchY <= areas[z]->y2 )
- {
- areas[z]->flags=0; //The pen is no longer inside (PenInside = 0);
- if(areas[z]->hookedActions & PEN_UP) //user want's to receive pen up events
- areas[z]->callback(areas[z],PEN_UP);
- }
- }
- }
- }
- return true;
+ if (use_calibration) { //the underlying touch hardware uses calibration
+ //Calculate the real touch position out of the passed ones, and the calibration values
+ pos.x = touchX = (((long)(DWIDTH - 2 * CCENTER) * 2 * (long)((long)touchX - cal_xs) / cal_dx + 1) >> 1) + CCENTER;
+ pos.y = touchY = (((long)(DHEIGHT - 2 * CCENTER) * 2 * (long)((long)touchY - cal_ys) / cal_dy + 1) >> 1) + CCENTER;
+ } else { //no conversion needed for the underlying hardware
+ pos.x = touchX;
+ pos.y = touchY;
+ }
+
+ if (penDown) { //pen is down now
+ //tft_draw_pixel(touchX,touchY,WHITE);
+ if (!oldPenDown) { //pen wasn't down before (positive edge) => First Touch
+ for (int z = 0; z < NUM_AREAS; z++) { // For every touch area
+ //Check if pos is inside area
+ if (areas[z] != NULL && touchX >= areas[z]->x1 && touchX <= areas[z]->x2 && touchY >= areas[z]->y1 && touchY <= areas[z]->y2) {
+ areas[z]->flags = 1; //Save PenInside=1
+
+ if (areas[z]->hookedActions & PEN_DOWN) { //The user wants to receive pen down events
+ areas[z]->callback(areas[z], PEN_DOWN); //Send event to user callback
+ }
+ }
+ }
+ } else { //Pen was down before => Second, Third event in row
+ for (int z = 0; z < NUM_AREAS; z++) { // For every touch area
+ if (areas[z] != NULL) {
+ //Check if pos is inside area
+ if (touchX >= areas[z]->x1 && touchX <= areas[z]->x2 && touchY >= areas[z]->y1 && touchY <= areas[z]->y2) {
+ if (areas[z]->flags == 0) { //Pen was not inside before (PenInside==0)
+ areas[z]->flags = 1; //Pen is inside now (PenInside=1)
+
+ if (areas[z]->hookedActions & PEN_ENTER) { //The user wants to receive pen enter events
+ areas[z]->callback(areas[z], PEN_ENTER);
+ }
+ }
+ } else if (areas[z]->flags) { //Pos not inside area, but it was before (PenInside==1)
+ areas[z]->flags = 0; //Pen is no longer inside (PenInside=0)
+
+ if (areas[z]->hookedActions & PEN_LEAVE) { //The user wants to receive pen leave events
+ areas[z]->callback(areas[z], PEN_LEAVE);
+ }
+ }
+ }
+ }
+ }
+
+ for (int z = 0; z < NUM_AREAS; z++) { // For every touch area
+ if (areas[z] != NULL && (areas[z]->hookedActions & PEN_MOVE)) { //User want's to receive pen move events
+ //Check if pos is inside area
+ if (touchX >= areas[z]->x1 && touchX <= areas[z]->x2 && touchY >= areas[z]->y1 && touchY <= areas[z]->y2) {
+ areas[z]->callback(areas[z], PEN_MOVE);
+ }
+ }
+ }
+ } else { //pen is not down now
+ if (oldPenDown) { //but it was down before (negative edge)
+ for (int z = 0; z < NUM_AREAS; z++) { // For every touch area
+ //Check if pos is inside area
+ if (areas[z] != NULL && touchX >= areas[z]->x1 && touchX <= areas[z]->x2 && touchY >= areas[z]->y1 && touchY <= areas[z]->y2) {
+ areas[z]->flags = 0; //The pen is no longer inside (PenInside = 0);
+
+ if (areas[z]->hookedActions & PEN_UP) { //user want's to receive pen up events
+ areas[z]->callback(areas[z], PEN_UP);
+ }
+ }
+ }
+ }
+ }
+
+ return true;
}
bool touch_have_empty(unsigned char num)
{
- //go through pointer array and check for free spaces
- for(unsigned char i=0; iflags=0; //we start with empty flags (PenInside=0)
- areas[i]=area; //save pointer into list
- return true;
- }
- }
- return false; //no free space found
+ //go through pointer array and check for free space
+ for (unsigned char i = 0; i < NUM_AREAS; i++) {
+ if (areas[i] == NULL) { //free space found
+ area->flags = 0; //we start with empty flags (PenInside=0)
+ areas[i] = area; //save pointer into list
+ return true;
+ }
+ }
+
+ return false; //no free space found
}
void touch_unregister_area(TOUCH_AREA_STRUCT* area)
{
- if(area==NULL) return;
+ if (area == NULL) {
+ return;
+ }
- //go through pointer array and find the area to remove
- for(unsigned char i=0; i
-// SmallFont.c
+// SmallFont.c
// Font Size : 8x12
// Memory usage : 1216 bytes
// # characters : 101
-const char small_font[1216] = {
-0x08,0x0C,0x20,0x65,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //
-0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, // !
-0x00,0x28,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "
-0x00,0x00,0x28,0x28,0xFC,0x28,0x50,0xFC,0x50,0x50,0x00,0x00, // #
-0x00,0x20,0x78,0xA8,0xA0,0x60,0x30,0x28,0xA8,0xF0,0x20,0x00, // $
-0x00,0x00,0x48,0xA8,0xB0,0x50,0x28,0x34,0x54,0x48,0x00,0x00, // %
-0x00,0x00,0x20,0x50,0x50,0x78,0xA8,0xA8,0x90,0x6C,0x00,0x00, // &
-0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // '
-0x00,0x04,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x04,0x00, // (
-0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x00, // )
-0x00,0x00,0x00,0x20,0xA8,0x70,0x70,0xA8,0x20,0x00,0x00,0x00, // *
-0x00,0x00,0x20,0x20,0x20,0xF8,0x20,0x20,0x20,0x00,0x00,0x00, // +
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x80, // ,
-0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, // -
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, // .
-0x00,0x08,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x80,0x00, // /
-0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, // 0
-0x00,0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, // 1
-0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x40,0x80,0xF8,0x00,0x00, // 2
-0x00,0x00,0x70,0x88,0x08,0x30,0x08,0x08,0x88,0x70,0x00,0x00, // 3
-0x00,0x00,0x10,0x30,0x50,0x50,0x90,0x78,0x10,0x18,0x00,0x00, // 4
-0x00,0x00,0xF8,0x80,0x80,0xF0,0x08,0x08,0x88,0x70,0x00,0x00, // 5
-0x00,0x00,0x70,0x90,0x80,0xF0,0x88,0x88,0x88,0x70,0x00,0x00, // 6
-0x00,0x00,0xF8,0x90,0x10,0x20,0x20,0x20,0x20,0x20,0x00,0x00, // 7
-0x00,0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x88,0x70,0x00,0x00, // 8
-0x00,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x48,0x70,0x00,0x00, // 9
-0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x20,0x00,0x00, // :
-0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x20,0x00, // ;
-0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00, // <
-0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, // =
-0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00, // >
-0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x20,0x00,0x20,0x00,0x00, // ?
-0x00,0x00,0x70,0x88,0x98,0xA8,0xA8,0xB8,0x80,0x78,0x00,0x00, // @
-0x00,0x00,0x20,0x20,0x30,0x50,0x50,0x78,0x48,0xCC,0x00,0x00, // A
-0x00,0x00,0xF0,0x48,0x48,0x70,0x48,0x48,0x48,0xF0,0x00,0x00, // B
-0x00,0x00,0x78,0x88,0x80,0x80,0x80,0x80,0x88,0x70,0x00,0x00, // C
-0x00,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0x48,0xF0,0x00,0x00, // D
-0x00,0x00,0xF8,0x48,0x50,0x70,0x50,0x40,0x48,0xF8,0x00,0x00, // E
-0x00,0x00,0xF8,0x48,0x50,0x70,0x50,0x40,0x40,0xE0,0x00,0x00, // F
-0x00,0x00,0x38,0x48,0x80,0x80,0x9C,0x88,0x48,0x30,0x00,0x00, // G
-0x00,0x00,0xCC,0x48,0x48,0x78,0x48,0x48,0x48,0xCC,0x00,0x00, // H
-0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00, // I
-0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0xE0,0x00, // J
-0x00,0x00,0xEC,0x48,0x50,0x60,0x50,0x50,0x48,0xEC,0x00,0x00, // K
-0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x44,0xFC,0x00,0x00, // L
-0x00,0x00,0xD8,0xD8,0xD8,0xD8,0xA8,0xA8,0xA8,0xA8,0x00,0x00, // M
-0x00,0x00,0xDC,0x48,0x68,0x68,0x58,0x58,0x48,0xE8,0x00,0x00, // N
-0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, // O
-0x00,0x00,0xF0,0x48,0x48,0x70,0x40,0x40,0x40,0xE0,0x00,0x00, // P
-0x00,0x00,0x70,0x88,0x88,0x88,0x88,0xE8,0x98,0x70,0x18,0x00, // Q
-0x00,0x00,0xF0,0x48,0x48,0x70,0x50,0x48,0x48,0xEC,0x00,0x00, // R
-0x00,0x00,0x78,0x88,0x80,0x60,0x10,0x08,0x88,0xF0,0x00,0x00, // S
-0x00,0x00,0xF8,0xA8,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, // T
-0x00,0x00,0xCC,0x48,0x48,0x48,0x48,0x48,0x48,0x30,0x00,0x00, // U
-0x00,0x00,0xCC,0x48,0x48,0x50,0x50,0x30,0x20,0x20,0x00,0x00, // V
-0x00,0x00,0xA8,0xA8,0xA8,0x70,0x50,0x50,0x50,0x50,0x00,0x00, // W
-0x00,0x00,0xD8,0x50,0x50,0x20,0x20,0x50,0x50,0xD8,0x00,0x00, // X
-0x00,0x00,0xD8,0x50,0x50,0x20,0x20,0x20,0x20,0x70,0x00,0x00, // Y
-0x00,0x00,0xF8,0x90,0x10,0x20,0x20,0x40,0x48,0xF8,0x00,0x00, // Z
-0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, // [
-0x00,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x00,0x00, //
-0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00, // ]
-0x00,0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ^
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, // _
-0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // '
-0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x38,0x48,0x3C,0x00,0x00, // a
-0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x48,0x70,0x00,0x00, // b
-0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x40,0x40,0x38,0x00,0x00, // c
-0x00,0x00,0x18,0x08,0x08,0x38,0x48,0x48,0x48,0x3C,0x00,0x00, // d
-0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x78,0x40,0x38,0x00,0x00, // e
-0x00,0x00,0x1C,0x20,0x20,0x78,0x20,0x20,0x20,0x78,0x00,0x00, // f
-0x00,0x00,0x00,0x00,0x00,0x3C,0x48,0x30,0x40,0x78,0x44,0x38, // g
-0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x48,0xEC,0x00,0x00, // h
-0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x70,0x00,0x00, // i
-0x00,0x00,0x10,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0xE0, // j
-0x00,0x00,0xC0,0x40,0x40,0x5C,0x50,0x70,0x48,0xEC,0x00,0x00, // k
-0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00, // l
-0x00,0x00,0x00,0x00,0x00,0xF0,0xA8,0xA8,0xA8,0xA8,0x00,0x00, // m
-0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0x48,0x48,0xEC,0x00,0x00, // n
-0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x30,0x00,0x00, // o
-0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0x48,0x48,0x70,0x40,0xE0, // p
-0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x48,0x48,0x38,0x08,0x1C, // q
-0x00,0x00,0x00,0x00,0x00,0xD8,0x60,0x40,0x40,0xE0,0x00,0x00, // r
-0x00,0x00,0x00,0x00,0x00,0x78,0x40,0x30,0x08,0x78,0x00,0x00, // s
-0x00,0x00,0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x18,0x00,0x00, // t
-0x00,0x00,0x00,0x00,0x00,0xD8,0x48,0x48,0x48,0x3C,0x00,0x00, // u
-0x00,0x00,0x00,0x00,0x00,0xEC,0x48,0x50,0x30,0x20,0x00,0x00, // v
-0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x70,0x50,0x50,0x00,0x00, // w
-0x00,0x00,0x00,0x00,0x00,0xD8,0x50,0x20,0x50,0xD8,0x00,0x00, // x
-0x00,0x00,0x00,0x00,0x00,0xEC,0x48,0x50,0x30,0x20,0x20,0xC0, // y
-0x00,0x00,0x00,0x00,0x00,0x78,0x10,0x20,0x20,0x78,0x00,0x00, // z
-0x00,0x18,0x10,0x10,0x10,0x20,0x10,0x10,0x10,0x10,0x18,0x00, // {
-0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, // |
-0x00,0x60,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0x60,0x00, // }
-0x40,0xA4,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ~
-0x50,0x00,0x20,0x20,0x30,0x50,0x50,0x78,0x48,0xCC,0x00,0x00, // Ä
-0x50,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, // Ö
-0x48,0x00,0xCC,0x48,0x48,0x48,0x48,0x48,0x48,0x30,0x00,0x00, // Ü
-0x00,0x00,0x00,0x48,0x00,0x30,0x48,0x38,0x48,0x3C,0x00,0x00, // ä
-0x00,0x00,0x00,0x48,0x00,0x30,0x48,0x48,0x48,0x30,0x00,0x00, // ö
-0x00,0x00,0x00,0x48,0x00,0xD8,0x48,0x48,0x48,0x3C,0x00,0x00 // ü
-};
+const char small_font[1216] = {
+ 0x08, 0x0C, 0x20, 0x65,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20, 0x00, 0x00, // !
+ 0x00, 0x28, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "
+ 0x00, 0x00, 0x28, 0x28, 0xFC, 0x28, 0x50, 0xFC, 0x50, 0x50, 0x00, 0x00, // #
+ 0x00, 0x20, 0x78, 0xA8, 0xA0, 0x60, 0x30, 0x28, 0xA8, 0xF0, 0x20, 0x00, // $
+ 0x00, 0x00, 0x48, 0xA8, 0xB0, 0x50, 0x28, 0x34, 0x54, 0x48, 0x00, 0x00, // %
+ 0x00, 0x00, 0x20, 0x50, 0x50, 0x78, 0xA8, 0xA8, 0x90, 0x6C, 0x00, 0x00, // &
+ 0x00, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // '
+ 0x00, 0x04, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x04, 0x00, // (
+ 0x00, 0x40, 0x20, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x40, 0x00, // )
+ 0x00, 0x00, 0x00, 0x20, 0xA8, 0x70, 0x70, 0xA8, 0x20, 0x00, 0x00, 0x00, // *
+ 0x00, 0x00, 0x20, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, // +
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x80, // ,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // -
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, // .
+ 0x00, 0x08, 0x10, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x80, 0x00, // /
+ 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, // 0
+ 0x00, 0x00, 0x20, 0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x00, 0x00, // 1
+ 0x00, 0x00, 0x70, 0x88, 0x88, 0x10, 0x20, 0x40, 0x80, 0xF8, 0x00, 0x00, // 2
+ 0x00, 0x00, 0x70, 0x88, 0x08, 0x30, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, // 3
+ 0x00, 0x00, 0x10, 0x30, 0x50, 0x50, 0x90, 0x78, 0x10, 0x18, 0x00, 0x00, // 4
+ 0x00, 0x00, 0xF8, 0x80, 0x80, 0xF0, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, // 5
+ 0x00, 0x00, 0x70, 0x90, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, // 6
+ 0x00, 0x00, 0xF8, 0x90, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, // 7
+ 0x00, 0x00, 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, // 8
+ 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x78, 0x08, 0x48, 0x70, 0x00, 0x00, // 9
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, // :
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, // ;
+ 0x00, 0x04, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, // <
+ 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, // =
+ 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, // >
+ 0x00, 0x00, 0x70, 0x88, 0x88, 0x10, 0x20, 0x20, 0x00, 0x20, 0x00, 0x00, // ?
+ 0x00, 0x00, 0x70, 0x88, 0x98, 0xA8, 0xA8, 0xB8, 0x80, 0x78, 0x00, 0x00, // @
+ 0x00, 0x00, 0x20, 0x20, 0x30, 0x50, 0x50, 0x78, 0x48, 0xCC, 0x00, 0x00, // A
+ 0x00, 0x00, 0xF0, 0x48, 0x48, 0x70, 0x48, 0x48, 0x48, 0xF0, 0x00, 0x00, // B
+ 0x00, 0x00, 0x78, 0x88, 0x80, 0x80, 0x80, 0x80, 0x88, 0x70, 0x00, 0x00, // C
+ 0x00, 0x00, 0xF0, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0xF0, 0x00, 0x00, // D
+ 0x00, 0x00, 0xF8, 0x48, 0x50, 0x70, 0x50, 0x40, 0x48, 0xF8, 0x00, 0x00, // E
+ 0x00, 0x00, 0xF8, 0x48, 0x50, 0x70, 0x50, 0x40, 0x40, 0xE0, 0x00, 0x00, // F
+ 0x00, 0x00, 0x38, 0x48, 0x80, 0x80, 0x9C, 0x88, 0x48, 0x30, 0x00, 0x00, // G
+ 0x00, 0x00, 0xCC, 0x48, 0x48, 0x78, 0x48, 0x48, 0x48, 0xCC, 0x00, 0x00, // H
+ 0x00, 0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xF8, 0x00, 0x00, // I
+ 0x00, 0x00, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0xE0, 0x00, // J
+ 0x00, 0x00, 0xEC, 0x48, 0x50, 0x60, 0x50, 0x50, 0x48, 0xEC, 0x00, 0x00, // K
+ 0x00, 0x00, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0xFC, 0x00, 0x00, // L
+ 0x00, 0x00, 0xD8, 0xD8, 0xD8, 0xD8, 0xA8, 0xA8, 0xA8, 0xA8, 0x00, 0x00, // M
+ 0x00, 0x00, 0xDC, 0x48, 0x68, 0x68, 0x58, 0x58, 0x48, 0xE8, 0x00, 0x00, // N
+ 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, // O
+ 0x00, 0x00, 0xF0, 0x48, 0x48, 0x70, 0x40, 0x40, 0x40, 0xE0, 0x00, 0x00, // P
+ 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0xE8, 0x98, 0x70, 0x18, 0x00, // Q
+ 0x00, 0x00, 0xF0, 0x48, 0x48, 0x70, 0x50, 0x48, 0x48, 0xEC, 0x00, 0x00, // R
+ 0x00, 0x00, 0x78, 0x88, 0x80, 0x60, 0x10, 0x08, 0x88, 0xF0, 0x00, 0x00, // S
+ 0x00, 0x00, 0xF8, 0xA8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x00, 0x00, // T
+ 0x00, 0x00, 0xCC, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x30, 0x00, 0x00, // U
+ 0x00, 0x00, 0xCC, 0x48, 0x48, 0x50, 0x50, 0x30, 0x20, 0x20, 0x00, 0x00, // V
+ 0x00, 0x00, 0xA8, 0xA8, 0xA8, 0x70, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00, // W
+ 0x00, 0x00, 0xD8, 0x50, 0x50, 0x20, 0x20, 0x50, 0x50, 0xD8, 0x00, 0x00, // X
+ 0x00, 0x00, 0xD8, 0x50, 0x50, 0x20, 0x20, 0x20, 0x20, 0x70, 0x00, 0x00, // Y
+ 0x00, 0x00, 0xF8, 0x90, 0x10, 0x20, 0x20, 0x40, 0x48, 0xF8, 0x00, 0x00, // Z
+ 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, // [
+ 0x00, 0x40, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x10, 0x08, 0x00, 0x00, //
+ 0x00, 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x00, // ]
+ 0x00, 0x20, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ^
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, // _
+ 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // '
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x48, 0x38, 0x48, 0x3C, 0x00, 0x00, // a
+ 0x00, 0x00, 0xC0, 0x40, 0x40, 0x70, 0x48, 0x48, 0x48, 0x70, 0x00, 0x00, // b
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x48, 0x40, 0x40, 0x38, 0x00, 0x00, // c
+ 0x00, 0x00, 0x18, 0x08, 0x08, 0x38, 0x48, 0x48, 0x48, 0x3C, 0x00, 0x00, // d
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x48, 0x78, 0x40, 0x38, 0x00, 0x00, // e
+ 0x00, 0x00, 0x1C, 0x20, 0x20, 0x78, 0x20, 0x20, 0x20, 0x78, 0x00, 0x00, // f
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x48, 0x30, 0x40, 0x78, 0x44, 0x38, // g
+ 0x00, 0x00, 0xC0, 0x40, 0x40, 0x70, 0x48, 0x48, 0x48, 0xEC, 0x00, 0x00, // h
+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x20, 0x20, 0x20, 0x70, 0x00, 0x00, // i
+ 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0xE0, // j
+ 0x00, 0x00, 0xC0, 0x40, 0x40, 0x5C, 0x50, 0x70, 0x48, 0xEC, 0x00, 0x00, // k
+ 0x00, 0x00, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xF8, 0x00, 0x00, // l
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xA8, 0xA8, 0xA8, 0xA8, 0x00, 0x00, // m
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x48, 0x48, 0x48, 0xEC, 0x00, 0x00, // n
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x48, 0x48, 0x48, 0x30, 0x00, 0x00, // o
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x48, 0x48, 0x48, 0x70, 0x40, 0xE0, // p
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x48, 0x48, 0x48, 0x38, 0x08, 0x1C, // q
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x60, 0x40, 0x40, 0xE0, 0x00, 0x00, // r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x40, 0x30, 0x08, 0x78, 0x00, 0x00, // s
+ 0x00, 0x00, 0x00, 0x20, 0x20, 0x70, 0x20, 0x20, 0x20, 0x18, 0x00, 0x00, // t
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x48, 0x48, 0x48, 0x3C, 0x00, 0x00, // u
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x48, 0x50, 0x30, 0x20, 0x00, 0x00, // v
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xA8, 0x70, 0x50, 0x50, 0x00, 0x00, // w
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x50, 0x20, 0x50, 0xD8, 0x00, 0x00, // x
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x48, 0x50, 0x30, 0x20, 0x20, 0xC0, // y
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x10, 0x20, 0x20, 0x78, 0x00, 0x00, // z
+ 0x00, 0x18, 0x10, 0x10, 0x10, 0x20, 0x10, 0x10, 0x10, 0x10, 0x18, 0x00, // {
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // |
+ 0x00, 0x60, 0x20, 0x20, 0x20, 0x10, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, // }
+ 0x40, 0xA4, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ~
+ 0x50, 0x00, 0x20, 0x20, 0x30, 0x50, 0x50, 0x78, 0x48, 0xCC, 0x00, 0x00, // Ä
+ 0x50, 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, // Ö
+ 0x48, 0x00, 0xCC, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x30, 0x00, 0x00, // Ü
+ 0x00, 0x00, 0x00, 0x48, 0x00, 0x30, 0x48, 0x38, 0x48, 0x3C, 0x00, 0x00, // ä
+ 0x00, 0x00, 0x00, 0x48, 0x00, 0x30, 0x48, 0x48, 0x48, 0x30, 0x00, 0x00, // ö
+ 0x00, 0x00, 0x00, 0x48, 0x00, 0xD8, 0x48, 0x48, 0x48, 0x3C, 0x00, 0x00 // ü
+};
// BigFont.c (C)2010 by Henning Karlsen
// Font Size : 16x16
// Memory usage : 3236 bytes
// # characters : 101
-const char big_font[3236] = {
-0x10,0x10,0x20,0x65,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //
-0x00,0x00,0x00,0x00,0x07,0x00,0x0F,0x80,0x0F,0x80,0x0F,0x80,0x0F,0x80,0x0F,0x80,0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00, // !
-0x00,0x00,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "
-0x00,0x00,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x7F,0xFE,0x7F,0xFE,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x7F,0xFE,0x7F,0xFE,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x00,0x00, // #
-0x00,0x00,0x02,0x40,0x02,0x40,0x0F,0xF8,0x1F,0xF8,0x1A,0x40,0x1A,0x40,0x1F,0xF0,0x0F,0xF8,0x02,0x58,0x02,0x58,0x1F,0xF8,0x1F,0xF0,0x02,0x40,0x02,0x40,0x00,0x00, // $
-0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x10,0x0E,0x30,0x0E,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x70,0x0C,0x70,0x08,0x70,0x00,0x00,0x00,0x00,0x00,0x00, // %
-0x00,0x00,0x00,0x00,0x0F,0x00,0x19,0x80,0x19,0x80,0x19,0x80,0x0F,0x00,0x0F,0x08,0x0F,0x98,0x19,0xF8,0x18,0xF0,0x18,0xE0,0x19,0xF0,0x0F,0x98,0x00,0x00,0x00,0x00, // &
-0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // '
-0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xF0,0x00,0x00,0x00,0x00, // (
-0x00,0x00,0x00,0x00,0x0F,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x0F,0x00,0x00,0x00,0x00,0x00, // )
-0x00,0x00,0x00,0x00,0x01,0x80,0x11,0x88,0x09,0x90,0x07,0xE0,0x07,0xE0,0x3F,0xFC,0x3F,0xFC,0x07,0xE0,0x07,0xE0,0x09,0x90,0x11,0x88,0x01,0x80,0x00,0x00,0x00,0x00, // *
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x0F,0xF0,0x0F,0xF0,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // +
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x0E,0x00,0x00,0x00, // ,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xF8,0x1F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // -
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00, // ,
-0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x06,0x00,0x0E,0x00,0x1C,0x00,0x38,0x00,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, // /
+const char big_font[3236] = {
+ 0x10, 0x10, 0x20, 0x65,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x0F, 0x80, 0x0F, 0x80, 0x0F, 0x80, 0x0F, 0x80, 0x0F, 0x80, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, // !
+ 0x00, 0x00, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x06, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "
+ 0x00, 0x00, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x7F, 0xFE, 0x7F, 0xFE, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x7F, 0xFE, 0x7F, 0xFE, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x00, 0x00, // #
+ 0x00, 0x00, 0x02, 0x40, 0x02, 0x40, 0x0F, 0xF8, 0x1F, 0xF8, 0x1A, 0x40, 0x1A, 0x40, 0x1F, 0xF0, 0x0F, 0xF8, 0x02, 0x58, 0x02, 0x58, 0x1F, 0xF8, 0x1F, 0xF0, 0x02, 0x40, 0x02, 0x40, 0x00, 0x00, // $
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x10, 0x0E, 0x30, 0x0E, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x70, 0x0C, 0x70, 0x08, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // %
+ 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x19, 0x80, 0x19, 0x80, 0x19, 0x80, 0x0F, 0x00, 0x0F, 0x08, 0x0F, 0x98, 0x19, 0xF8, 0x18, 0xF0, 0x18, 0xE0, 0x19, 0xF0, 0x0F, 0x98, 0x00, 0x00, 0x00, 0x00, // &
+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // '
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, // (
+ 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, // )
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x11, 0x88, 0x09, 0x90, 0x07, 0xE0, 0x07, 0xE0, 0x3F, 0xFC, 0x3F, 0xFC, 0x07, 0xE0, 0x07, 0xE0, 0x09, 0x90, 0x11, 0x88, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, // *
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x0F, 0xF0, 0x0F, 0xF0, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // +
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x0E, 0x00, 0x00, 0x00, // ,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // -
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, // ,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, // /
-0x00,0x00,0x00,0x00,0x0F,0xF0,0x1C,0x38,0x1C,0x78,0x1C,0xF8,0x1C,0xF8,0x1D,0xB8,0x1D,0xB8,0x1F,0x38,0x1F,0x38,0x1E,0x38,0x1C,0x38,0x0F,0xF0,0x00,0x00,0x00,0x00, // 0
-0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x03,0x80,0x1F,0x80,0x1F,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x1F,0xF0,0x00,0x00,0x00,0x00, // 1
-0x00,0x00,0x00,0x00,0x0F,0xE0,0x1C,0x70,0x1C,0x38,0x00,0x38,0x00,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x38,0x1C,0x38,0x1F,0xF8,0x00,0x00,0x00,0x00, // 2
-0x00,0x00,0x00,0x00,0x0F,0xE0,0x1C,0x70,0x1C,0x38,0x00,0x38,0x00,0x70,0x03,0xC0,0x03,0xC0,0x00,0x70,0x00,0x38,0x1C,0x38,0x1C,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // 3
-0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0xE0,0x03,0xE0,0x06,0xE0,0x0C,0xE0,0x18,0xE0,0x1F,0xF8,0x1F,0xF8,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x03,0xF8,0x00,0x00,0x00,0x00, // 4
-0x00,0x00,0x00,0x00,0x1F,0xF8,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1F,0xE0,0x1F,0xF0,0x00,0x78,0x00,0x38,0x1C,0x38,0x1C,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // 5
-0x00,0x00,0x00,0x00,0x03,0xE0,0x07,0x00,0x0E,0x00,0x1C,0x00,0x1C,0x00,0x1F,0xF0,0x1F,0xF8,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x0F,0xF0,0x00,0x00,0x00,0x00, // 6
-0x00,0x00,0x00,0x00,0x1F,0xFC,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x00,0x1C,0x00,0x38,0x00,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00, // 7
-0x00,0x00,0x00,0x00,0x0F,0xF0,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1F,0x38,0x07,0xE0,0x07,0xE0,0x1C,0xF8,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x0F,0xF0,0x00,0x00,0x00,0x00, // 8
-0x00,0x00,0x00,0x00,0x0F,0xF0,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1F,0xF8,0x0F,0xF8,0x00,0x38,0x00,0x38,0x00,0x70,0x00,0xE0,0x07,0xC0,0x00,0x00,0x00,0x00, // 9
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // :
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ;
-0x00,0x00,0x00,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x00,0x1C,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x00, // <
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFC,0x3F,0xFC,0x00,0x00,0x00,0x00,0x3F,0xFC,0x3F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // =
-0x00,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x00,0x1C,0x00,0x00,0x00, // >
-0x00,0x00,0x03,0xC0,0x0F,0xF0,0x1E,0x78,0x18,0x38,0x00,0x38,0x00,0x70,0x00,0xE0,0x01,0xC0,0x01,0xC0,0x00,0x00,0x00,0x00,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x00,0x00, // ?
+ 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x1C, 0x38, 0x1C, 0x78, 0x1C, 0xF8, 0x1C, 0xF8, 0x1D, 0xB8, 0x1D, 0xB8, 0x1F, 0x38, 0x1F, 0x38, 0x1E, 0x38, 0x1C, 0x38, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, // 0
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x03, 0x80, 0x1F, 0x80, 0x1F, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x1F, 0xF0, 0x00, 0x00, 0x00, 0x00, // 1
+ 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x1C, 0x70, 0x1C, 0x38, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x38, 0x1C, 0x38, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, // 2
+ 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x1C, 0x70, 0x1C, 0x38, 0x00, 0x38, 0x00, 0x70, 0x03, 0xC0, 0x03, 0xC0, 0x00, 0x70, 0x00, 0x38, 0x1C, 0x38, 0x1C, 0x70, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, // 3
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0xE0, 0x03, 0xE0, 0x06, 0xE0, 0x0C, 0xE0, 0x18, 0xE0, 0x1F, 0xF8, 0x1F, 0xF8, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, // 4
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x1C, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x1F, 0xE0, 0x1F, 0xF0, 0x00, 0x78, 0x00, 0x38, 0x1C, 0x38, 0x1C, 0x70, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, // 5
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x1F, 0xF0, 0x1F, 0xF8, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, // 6
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, // 7
+ 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1F, 0x38, 0x07, 0xE0, 0x07, 0xE0, 0x1C, 0xF8, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, // 8
+ 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1F, 0xF8, 0x0F, 0xF8, 0x00, 0x38, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x00, // 9
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // :
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ;
+ 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x00, // <
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFC, 0x3F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFC, 0x3F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // =
+ 0x00, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x00, 0x00, // >
+ 0x00, 0x00, 0x03, 0xC0, 0x0F, 0xF0, 0x1E, 0x78, 0x18, 0x38, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0x00, // ?
-0x00,0x00,0x0F,0xF8,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0xFC,0x1C,0xFC,0x1C,0xFC,0x1C,0xFC,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1F,0xF0,0x07,0xF8,0x00,0x00, // @
-0x00,0x00,0x00,0x00,0x03,0xC0,0x07,0xE0,0x0E,0x70,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1F,0xF8,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x00,0x00,0x00,0x00, // A
-0x00,0x00,0x00,0x00,0x1F,0xF0,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0F,0xF0,0x0F,0xF0,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1F,0xF0,0x00,0x00,0x00,0x00, // B
-0x00,0x00,0x00,0x00,0x07,0xF0,0x0E,0x38,0x1C,0x38,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x38,0x0E,0x38,0x07,0xF0,0x00,0x00,0x00,0x00, // C
-0x00,0x00,0x00,0x00,0x1F,0xE0,0x0E,0x70,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x70,0x1F,0xE0,0x00,0x00,0x00,0x00, // D
-0x00,0x00,0x00,0x00,0x1F,0xF8,0x0E,0x18,0x0E,0x08,0x0E,0x00,0x0E,0x30,0x0F,0xF0,0x0F,0xF0,0x0E,0x30,0x0E,0x00,0x0E,0x08,0x0E,0x18,0x1F,0xF8,0x00,0x00,0x00,0x00, // E
-0x00,0x00,0x00,0x00,0x1F,0xF8,0x0E,0x18,0x0E,0x08,0x0E,0x00,0x0E,0x30,0x0F,0xF0,0x0F,0xF0,0x0E,0x30,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x1F,0x00,0x00,0x00,0x00,0x00, // F
-0x00,0x00,0x00,0x00,0x07,0xF0,0x0E,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0xF8,0x1C,0x38,0x1C,0x38,0x0E,0x38,0x07,0xF8,0x00,0x00,0x00,0x00, // G
-0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1F,0xF0,0x1F,0xF0,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x00,0x00,0x00,0x00, // H
-0x00,0x00,0x00,0x00,0x0F,0xE0,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x0F,0xE0,0x00,0x00,0x00,0x00, // I
-0x00,0x00,0x00,0x00,0x01,0xFC,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x38,0x70,0x38,0x70,0x38,0x70,0x38,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // J
-0x00,0x00,0x00,0x00,0x1E,0x38,0x0E,0x38,0x0E,0x70,0x0E,0xE0,0x0F,0xC0,0x0F,0x80,0x0F,0x80,0x0F,0xC0,0x0E,0xE0,0x0E,0x70,0x0E,0x38,0x1E,0x38,0x00,0x00,0x00,0x00, // K
-0x00,0x00,0x00,0x00,0x1F,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x08,0x0E,0x18,0x0E,0x38,0x1F,0xF8,0x00,0x00,0x00,0x00, // L
-0x00,0x00,0x00,0x00,0x1C,0x1C,0x1E,0x3C,0x1F,0x7C,0x1F,0xFC,0x1F,0xFC,0x1D,0xDC,0x1C,0x9C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00, // M
-0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x1C,0x1E,0x1C,0x1F,0x1C,0x1F,0x9C,0x1D,0xDC,0x1C,0xFC,0x1C,0x7C,0x1C,0x3C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00, // N
-0x00,0x00,0x00,0x00,0x03,0xE0,0x07,0xF0,0x0E,0x38,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x0E,0x38,0x07,0xF0,0x03,0xE0,0x00,0x00,0x00,0x00, // O
+ 0x00, 0x00, 0x0F, 0xF8, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0xFC, 0x1C, 0xFC, 0x1C, 0xFC, 0x1C, 0xFC, 0x1C, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x1F, 0xF0, 0x07, 0xF8, 0x00, 0x00, // @
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x07, 0xE0, 0x0E, 0x70, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1F, 0xF8, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x00, 0x00, 0x00, 0x00, // A
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF0, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0F, 0xF0, 0x0F, 0xF0, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x1F, 0xF0, 0x00, 0x00, 0x00, 0x00, // B
+ 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x0E, 0x38, 0x1C, 0x38, 0x1C, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x1C, 0x38, 0x0E, 0x38, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, // C
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0xE0, 0x0E, 0x70, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x70, 0x1F, 0xE0, 0x00, 0x00, 0x00, 0x00, // D
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x0E, 0x18, 0x0E, 0x08, 0x0E, 0x00, 0x0E, 0x30, 0x0F, 0xF0, 0x0F, 0xF0, 0x0E, 0x30, 0x0E, 0x00, 0x0E, 0x08, 0x0E, 0x18, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, // E
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x0E, 0x18, 0x0E, 0x08, 0x0E, 0x00, 0x0E, 0x30, 0x0F, 0xF0, 0x0F, 0xF0, 0x0E, 0x30, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, // F
+ 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x0E, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x1C, 0xF8, 0x1C, 0x38, 0x1C, 0x38, 0x0E, 0x38, 0x07, 0xF8, 0x00, 0x00, 0x00, 0x00, // G
+ 0x00, 0x00, 0x00, 0x00, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1F, 0xF0, 0x1F, 0xF0, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x00, 0x00, 0x00, 0x00, // H
+ 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, // I
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x38, 0x70, 0x38, 0x70, 0x38, 0x70, 0x38, 0x70, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, // J
+ 0x00, 0x00, 0x00, 0x00, 0x1E, 0x38, 0x0E, 0x38, 0x0E, 0x70, 0x0E, 0xE0, 0x0F, 0xC0, 0x0F, 0x80, 0x0F, 0x80, 0x0F, 0xC0, 0x0E, 0xE0, 0x0E, 0x70, 0x0E, 0x38, 0x1E, 0x38, 0x00, 0x00, 0x00, 0x00, // K
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x08, 0x0E, 0x18, 0x0E, 0x38, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, // L
+ 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x1E, 0x3C, 0x1F, 0x7C, 0x1F, 0xFC, 0x1F, 0xFC, 0x1D, 0xDC, 0x1C, 0x9C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x00, 0x00, 0x00, 0x00, // M
+ 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x1C, 0x1C, 0x1E, 0x1C, 0x1F, 0x1C, 0x1F, 0x9C, 0x1D, 0xDC, 0x1C, 0xFC, 0x1C, 0x7C, 0x1C, 0x3C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x00, 0x00, 0x00, 0x00, // N
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x07, 0xF0, 0x0E, 0x38, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x0E, 0x38, 0x07, 0xF0, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, // O
-0x00,0x00,0x00,0x00,0x1F,0xF0,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0F,0xF0,0x0F,0xF0,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x1F,0x00,0x00,0x00,0x00,0x00, // P
-0x00,0x00,0x00,0x00,0x03,0xE0,0x0F,0x78,0x0E,0x38,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x7C,0x1C,0xFC,0x0F,0xF8,0x0F,0xF8,0x00,0x38,0x00,0xFC,0x00,0x00, // Q
-0x00,0x00,0x00,0x00,0x1F,0xF0,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0F,0xF0,0x0F,0xF0,0x0E,0x70,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1E,0x38,0x00,0x00,0x00,0x00, // R
-0x00,0x00,0x00,0x00,0x0F,0xF0,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x00,0x0F,0xE0,0x07,0xF0,0x00,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x0F,0xF0,0x00,0x00,0x00,0x00, // S
-0x00,0x00,0x00,0x00,0x1F,0xFC,0x19,0xCC,0x11,0xC4,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x07,0xF0,0x00,0x00,0x00,0x00, // T
-0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // U
-0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0E,0xE0,0x07,0xC0,0x03,0x80,0x00,0x00,0x00,0x00, // V
-0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x9C,0x1C,0x9C,0x1C,0x9C,0x0F,0xF8,0x0F,0xF8,0x07,0x70,0x07,0x70,0x00,0x00,0x00,0x00, // W
-0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0E,0xE0,0x07,0xC0,0x03,0x80,0x03,0x80,0x07,0xC0,0x0E,0xE0,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x00,0x00,0x00,0x00, // X
-0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0E,0xE0,0x07,0xC0,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x0F,0xE0,0x00,0x00,0x00,0x00, // Y
-0x00,0x00,0x00,0x00,0x1F,0xF8,0x1C,0x38,0x18,0x38,0x10,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x08,0x1C,0x18,0x1C,0x38,0x1F,0xF8,0x00,0x00,0x00,0x00, // Z
-0x00,0x00,0x00,0x00,0x07,0xF0,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0xF0,0x00,0x00,0x00,0x00, // [
-0x00,0x00,0x00,0x00,0x10,0x00,0x18,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0x07,0x00,0x00,0x00,0x00, //
-0x00,0x00,0x00,0x00,0x07,0xF0,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x07,0xF0,0x00,0x00,0x00,0x00, // ]
-0x00,0x00,0x01,0x80,0x03,0xC0,0x07,0xE0,0x0E,0x70,0x1C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ^
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFF,0x7F,0xFF, // _
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF0, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0F, 0xF0, 0x0F, 0xF0, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, // P
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x0F, 0x78, 0x0E, 0x38, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x7C, 0x1C, 0xFC, 0x0F, 0xF8, 0x0F, 0xF8, 0x00, 0x38, 0x00, 0xFC, 0x00, 0x00, // Q
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF0, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0F, 0xF0, 0x0F, 0xF0, 0x0E, 0x70, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x1E, 0x38, 0x00, 0x00, 0x00, 0x00, // R
+ 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x00, 0x0F, 0xE0, 0x07, 0xF0, 0x00, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, // S
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x19, 0xCC, 0x11, 0xC4, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, // T
+ 0x00, 0x00, 0x00, 0x00, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, // U
+ 0x00, 0x00, 0x00, 0x00, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x0E, 0xE0, 0x07, 0xC0, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, // V
+ 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x9C, 0x1C, 0x9C, 0x1C, 0x9C, 0x0F, 0xF8, 0x0F, 0xF8, 0x07, 0x70, 0x07, 0x70, 0x00, 0x00, 0x00, 0x00, // W
+ 0x00, 0x00, 0x00, 0x00, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x0E, 0xE0, 0x07, 0xC0, 0x03, 0x80, 0x03, 0x80, 0x07, 0xC0, 0x0E, 0xE0, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x00, 0x00, 0x00, 0x00, // X
+ 0x00, 0x00, 0x00, 0x00, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x0E, 0xE0, 0x07, 0xC0, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, // Y
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x1C, 0x38, 0x18, 0x38, 0x10, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x08, 0x1C, 0x18, 0x1C, 0x38, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, // Z
+ 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, // [
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x18, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, // ]
+ 0x00, 0x00, 0x01, 0x80, 0x03, 0xC0, 0x07, 0xE0, 0x0E, 0x70, 0x1C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ^
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x7F, 0xFF, // _
-0x00,0x00,0x00,0x00,0x1C,0x00,0x1C,0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // '
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xE0,0x00,0x70,0x00,0x70,0x0F,0xF0,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xD8,0x00,0x00,0x00,0x00, // a
-0x00,0x00,0x00,0x00,0x1E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0F,0xF0,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1B,0xF0,0x00,0x00,0x00,0x00, // b
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xE0,0x1C,0x70,0x1C,0x70,0x1C,0x00,0x1C,0x00,0x1C,0x70,0x1C,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // c
-0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x70,0x00,0x70,0x00,0x70,0x0F,0xF0,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xD8,0x00,0x00,0x00,0x00, // d
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xE0,0x1C,0x70,0x1C,0x70,0x1F,0xF0,0x1C,0x00,0x1C,0x70,0x1C,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // e
-0x00,0x00,0x00,0x00,0x03,0xE0,0x07,0x70,0x07,0x70,0x07,0x00,0x07,0x00,0x1F,0xE0,0x1F,0xE0,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x1F,0xC0,0x00,0x00,0x00,0x00, // f
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xD8,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xF0,0x07,0xF0,0x00,0x70,0x1C,0x70,0x0F,0xE0, // g
-0x00,0x00,0x00,0x00,0x1E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0xF0,0x0F,0x38,0x0F,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1E,0x38,0x00,0x00,0x00,0x00, // h
-0x00,0x00,0x00,0x00,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x00,0x00,0x0F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x0F,0xF8,0x00,0x00,0x00,0x00, // i
-0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x00,0x03,0xF0,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x1C,0x70,0x0C,0xF0,0x07,0xE0, // j
-0x00,0x00,0x00,0x00,0x1E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x38,0x0E,0x70,0x0E,0xE0,0x0F,0xC0,0x0E,0xE0,0x0E,0x70,0x0E,0x38,0x1E,0x38,0x00,0x00,0x00,0x00, // k
-0x00,0x00,0x00,0x00,0x0F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x0F,0xF8,0x00,0x00,0x00,0x00, // l
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xF8,0x1C,0x9C,0x1C,0x9C,0x1C,0x9C,0x1C,0x9C,0x1C,0x9C,0x1C,0x9C,0x1C,0x9C,0x00,0x00,0x00,0x00, // m
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xE0,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x00,0x00,0x00,0x00, // n
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xE0,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // o
+ 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // '
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x70, 0x00, 0x70, 0x0F, 0xF0, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x0F, 0xD8, 0x00, 0x00, 0x00, 0x00, // a
+ 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0F, 0xF0, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x1B, 0xF0, 0x00, 0x00, 0x00, 0x00, // b
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x00, 0x1C, 0x00, 0x1C, 0x70, 0x1C, 0x70, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, // c
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x0F, 0xF0, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x0F, 0xD8, 0x00, 0x00, 0x00, 0x00, // d
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x1C, 0x70, 0x1C, 0x70, 0x1F, 0xF0, 0x1C, 0x00, 0x1C, 0x70, 0x1C, 0x70, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, // e
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x07, 0x70, 0x07, 0x70, 0x07, 0x00, 0x07, 0x00, 0x1F, 0xE0, 0x1F, 0xE0, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x00, // f
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xD8, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x0F, 0xF0, 0x07, 0xF0, 0x00, 0x70, 0x1C, 0x70, 0x0F, 0xE0, // g
+ 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0xF0, 0x0F, 0x38, 0x0F, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x1E, 0x38, 0x00, 0x00, 0x00, 0x00, // h
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0x00, 0x0F, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x0F, 0xF8, 0x00, 0x00, 0x00, 0x00, // i
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x1C, 0x70, 0x0C, 0xF0, 0x07, 0xE0, // j
+ 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x38, 0x0E, 0x70, 0x0E, 0xE0, 0x0F, 0xC0, 0x0E, 0xE0, 0x0E, 0x70, 0x0E, 0x38, 0x1E, 0x38, 0x00, 0x00, 0x00, 0x00, // k
+ 0x00, 0x00, 0x00, 0x00, 0x0F, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x0F, 0xF8, 0x00, 0x00, 0x00, 0x00, // l
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x1C, 0x9C, 0x1C, 0x9C, 0x1C, 0x9C, 0x1C, 0x9C, 0x1C, 0x9C, 0x1C, 0x9C, 0x1C, 0x9C, 0x00, 0x00, 0x00, 0x00, // m
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xE0, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x00, 0x00, 0x00, 0x00, // n
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, // o
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0xF0,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0F,0xF0,0x0E,0x00,0x0E,0x00,0x1F,0x00, // p
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xB0,0x38,0xE0,0x38,0xE0,0x38,0xE0,0x38,0xE0,0x38,0xE0,0x1F,0xE0,0x00,0xE0,0x00,0xE0,0x01,0xF0, // q
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0xF0,0x0F,0xF8,0x0F,0x38,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x1F,0x00,0x00,0x00,0x00,0x00, // r
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xE0,0x1C,0x30,0x1C,0x30,0x0F,0x80,0x03,0xE0,0x18,0x70,0x18,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // s
-0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x07,0x00,0x1F,0xF0,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x70,0x07,0x70,0x03,0xE0,0x00,0x00,0x00,0x00, // t
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xD8,0x00,0x00,0x00,0x00, // u
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0E,0xE0,0x07,0xC0,0x03,0x80,0x00,0x00,0x00,0x00, // v
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x9C,0x1C,0x9C,0x0F,0xF8,0x07,0x70,0x07,0x70,0x00,0x00,0x00,0x00, // w
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0xE0,0x1C,0xE0,0x0F,0xC0,0x07,0x80,0x07,0x80,0x0F,0xC0,0x1C,0xE0,0x1C,0xE0,0x00,0x00,0x00,0x00, // x
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x07,0xF0,0x03,0xE0,0x00,0xE0,0x01,0xC0,0x1F,0x80, // y
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xE0,0x18,0xE0,0x11,0xC0,0x03,0x80,0x07,0x00,0x0E,0x20,0x1C,0x60,0x1F,0xE0,0x00,0x00,0x00,0x00, // z
-0x00,0x00,0x00,0x00,0x01,0xF8,0x03,0x80,0x03,0x80,0x03,0x80,0x07,0x00,0x1C,0x00,0x1C,0x00,0x07,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x01,0xF8,0x00,0x00,0x00,0x00, // {
-0x00,0x00,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x00,0x00, // |
-0x00,0x00,0x00,0x00,0x1F,0x80,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x00,0xE0,0x00,0x38,0x00,0x38,0x00,0xE0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x1F,0x80,0x00,0x00,0x00,0x00, // }
-0x00,0x00,0x00,0x00,0x1F,0x1C,0x3B,0x9C,0x39,0xDC,0x38,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ~
-0x0C,0x30,0x0C,0x30,0x03,0xC0,0x07,0xE0,0x0E,0x70,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1F,0xF8,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x00,0x00,0x00,0x00, // Ä
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xF0, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0F, 0xF0, 0x0E, 0x00, 0x0E, 0x00, 0x1F, 0x00, // p
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xB0, 0x38, 0xE0, 0x38, 0xE0, 0x38, 0xE0, 0x38, 0xE0, 0x38, 0xE0, 0x1F, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x01, 0xF0, // q
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xF0, 0x0F, 0xF8, 0x0F, 0x38, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, // r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x1C, 0x30, 0x1C, 0x30, 0x0F, 0x80, 0x03, 0xE0, 0x18, 0x70, 0x18, 0x70, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, // s
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x07, 0x00, 0x1F, 0xF0, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x70, 0x07, 0x70, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, // t
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x0F, 0xD8, 0x00, 0x00, 0x00, 0x00, // u
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x0E, 0xE0, 0x07, 0xC0, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, // v
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x9C, 0x1C, 0x9C, 0x0F, 0xF8, 0x07, 0x70, 0x07, 0x70, 0x00, 0x00, 0x00, 0x00, // w
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xE0, 0x1C, 0xE0, 0x0F, 0xC0, 0x07, 0x80, 0x07, 0x80, 0x0F, 0xC0, 0x1C, 0xE0, 0x1C, 0xE0, 0x00, 0x00, 0x00, 0x00, // x
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x07, 0xF0, 0x03, 0xE0, 0x00, 0xE0, 0x01, 0xC0, 0x1F, 0x80, // y
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xE0, 0x18, 0xE0, 0x11, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x20, 0x1C, 0x60, 0x1F, 0xE0, 0x00, 0x00, 0x00, 0x00, // z
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x07, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x07, 0x00, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, // {
+ 0x00, 0x00, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0x00, // |
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x80, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x38, 0x00, 0xE0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, // }
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1C, 0x3B, 0x9C, 0x39, 0xDC, 0x38, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ~
+ 0x0C, 0x30, 0x0C, 0x30, 0x03, 0xC0, 0x07, 0xE0, 0x0E, 0x70, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1F, 0xF8, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x00, 0x00, 0x00, 0x00, // Ä
-0x0C,0x18,0x0C,0x18,0x03,0xE0,0x07,0xF0,0x0E,0x38,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x0E,0x38,0x07,0xF0,0x03,0xE0,0x00,0x00,0x00,0x00, // Ö
-0x0C,0x60,0x0C,0x60,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // Ü
-0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x60,0x0C,0x60,0x00,0x00,0x0F,0xE0,0x00,0x70,0x00,0x70,0x0F,0xF0,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xD8,0x00,0x00,0x00,0x00, // ä
-0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x60,0x0C,0x60,0x00,0x00,0x0F,0xE0,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // o
-0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x60,0x0C,0x60,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xD8,0x00,0x00,0x00,0x00 // u
-};
+ 0x0C, 0x18, 0x0C, 0x18, 0x03, 0xE0, 0x07, 0xF0, 0x0E, 0x38, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x0E, 0x38, 0x07, 0xF0, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, // Ö
+ 0x0C, 0x60, 0x0C, 0x60, 0x00, 0x00, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, // Ü
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x60, 0x0C, 0x60, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x70, 0x00, 0x70, 0x0F, 0xF0, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x0F, 0xD8, 0x00, 0x00, 0x00, 0x00, // ä
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x60, 0x0C, 0x60, 0x00, 0x00, 0x0F, 0xE0, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, // o
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x60, 0x0C, 0x60, 0x00, 0x00, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x0F, 0xD8, 0x00, 0x00, 0x00, 0x00 // u
+};
// SevenSegNumFont.c
// Font Size : 32x50
// Memory usage : 2004 bytes
// # characters : 10
-const char seven_seg_num_font[2004] = {
-0x20,0x32,0x30,0x0A,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x60,0x0C,0xFF,0xFE,0xF0,0x1E,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3E,0x00,0x00,0x78,0x38,0x00,0x00,0x18,0x20,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x38,0x00,0x00,0x18,0x3E,0x00,0x00,0x78,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x1E,0x00,0x00,0xF0,0x0C,0xFF,0xFE,0x60,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xF0,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x78,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 1
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x60,0x00,0xFF,0xFE,0xF0,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x00,0x78,0x01,0xFF,0xFE,0x18,0x03,0xFF,0xFF,0x88,0x0F,0xFF,0xFF,0xE0,0x27,0xFF,0xFF,0xC0,0x39,0xFF,0xFF,0x00,0x3E,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x0C,0xFF,0xFE,0x00,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 2
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x60,0x00,0xFF,0xFE,0xF0,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x00,0x78,0x01,0xFF,0xFE,0x18,0x03,0xFF,0xFF,0x88,0x0F,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xC0,0x01,0xFF,0xFF,0x18,0x00,0x00,0x00,0x78,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x00,0xF0,0x00,0xFF,0xFE,0x60,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 3
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x0C,0x00,0x00,0xF0,0x1E,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3E,0x00,0x00,0x78,0x39,0xFF,0xFE,0x18,0x23,0xFF,0xFF,0x88,0x0F,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xC0,0x01,0xFF,0xFF,0x18,0x00,0x00,0x00,0x78,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 4
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x00,0x0C,0xFF,0xFE,0x00,0x1E,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x39,0xFF,0xFE,0x00,0x23,0xFF,0xFF,0x80,0x0F,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xC0,0x01,0xFF,0xFF,0x18,0x00,0x00,0x00,0x78,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x00,0xF0,0x00,0xFF,0xFE,0x60,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 5
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x00,0x0C,0xFF,0xFE,0x00,0x1E,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x39,0xFF,0xFE,0x00,0x23,0xFF,0xFF,0x80,0x0F,0xFF,0xFF,0xE0,0x27,0xFF,0xFF,0xC0,0x39,0xFF,0xFF,0x18,0x3E,0x00,0x00,0x78,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x1E,0x00,0x00,0xF0,0x0C,0xFF,0xFE,0x60,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 6
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x60,0x00,0xFF,0xFE,0xF0,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x78,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 7
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x60,0x0C,0xFF,0xFE,0xF0,0x1E,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3E,0x00,0x00,0x78,0x39,0xFF,0xFE,0x18,0x23,0xFF,0xFF,0x88,0x0F,0xFF,0xFF,0xE0,0x27,0xFF,0xFF,0xC0,0x39,0xFF,0xFF,0x18,0x3E,0x00,0x00,0x78,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x1E,0x00,0x00,0xF0,0x0C,0xFF,0xFE,0x60,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 8
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x60,0x0C,0xFF,0xFE,0xF0,0x1E,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3E,0x00,0x00,0x78,0x39,0xFF,0xFE,0x18,0x23,0xFF,0xFF,0x88,0x0F,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xC0,0x01,0xFF,0xFF,0x18,0x00,0x00,0x00,0x78,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x00,0xF0,0x00,0xFF,0xFE,0x60,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 9
+const char seven_seg_num_font[2004] = {
+ 0x20, 0x32, 0x30, 0x0A,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x60, 0x0C, 0xFF, 0xFE, 0xF0, 0x1E, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3E, 0x00, 0x00, 0x78, 0x38, 0x00, 0x00, 0x18, 0x20, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x18, 0x3E, 0x00, 0x00, 0x78, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x1E, 0x00, 0x00, 0xF0, 0x0C, 0xFF, 0xFE, 0x60, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x60, 0x00, 0xFF, 0xFE, 0xF0, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x78, 0x01, 0xFF, 0xFE, 0x18, 0x03, 0xFF, 0xFF, 0x88, 0x0F, 0xFF, 0xFF, 0xE0, 0x27, 0xFF, 0xFF, 0xC0, 0x39, 0xFF, 0xFF, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x60, 0x00, 0xFF, 0xFE, 0xF0, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x78, 0x01, 0xFF, 0xFE, 0x18, 0x03, 0xFF, 0xFF, 0x88, 0x0F, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0x18, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xFF, 0xFE, 0x60, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0C, 0x00, 0x00, 0xF0, 0x1E, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3E, 0x00, 0x00, 0x78, 0x39, 0xFF, 0xFE, 0x18, 0x23, 0xFF, 0xFF, 0x88, 0x0F, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0x18, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 4
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x00, 0x0C, 0xFF, 0xFE, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x39, 0xFF, 0xFE, 0x00, 0x23, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0x18, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xFF, 0xFE, 0x60, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 5
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x00, 0x0C, 0xFF, 0xFE, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x39, 0xFF, 0xFE, 0x00, 0x23, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xE0, 0x27, 0xFF, 0xFF, 0xC0, 0x39, 0xFF, 0xFF, 0x18, 0x3E, 0x00, 0x00, 0x78, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x1E, 0x00, 0x00, 0xF0, 0x0C, 0xFF, 0xFE, 0x60, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 6
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x60, 0x00, 0xFF, 0xFE, 0xF0, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 7
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x60, 0x0C, 0xFF, 0xFE, 0xF0, 0x1E, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3E, 0x00, 0x00, 0x78, 0x39, 0xFF, 0xFE, 0x18, 0x23, 0xFF, 0xFF, 0x88, 0x0F, 0xFF, 0xFF, 0xE0, 0x27, 0xFF, 0xFF, 0xC0, 0x39, 0xFF, 0xFF, 0x18, 0x3E, 0x00, 0x00, 0x78, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x1E, 0x00, 0x00, 0xF0, 0x0C, 0xFF, 0xFE, 0x60, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x60, 0x0C, 0xFF, 0xFE, 0xF0, 0x1E, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3F, 0x00, 0x01, 0xF8, 0x3E, 0x00, 0x00, 0x78, 0x39, 0xFF, 0xFE, 0x18, 0x23, 0xFF, 0xFF, 0x88, 0x0F, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0x18, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xFF, 0xFE, 0x60, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 9
};
diff --git a/discovery/src/font.h b/discovery/src/font.h
index ca0035a..d95d3a1 100644
--- a/discovery/src/font.h
+++ b/discovery/src/font.h
@@ -1,3 +1,16 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: discovery/src/font.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-05-11 aaron@duckpond.ch 21fddc3 Implemented new functions
+*
+**************************************************************************************************************************************/
+
const char small_font[1216];
const char big_font[3236];
const char seven_seg_num_font[2004];
diff --git a/discovery/src/ll_filesystem.c b/discovery/src/ll_filesystem.c
index fda6515..0be8986 100644
--- a/discovery/src/ll_filesystem.c
+++ b/discovery/src/ll_filesystem.c
@@ -1,38 +1,56 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: discovery/src/ll_filesystem.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-05-10 timolang@gmail.com e2bce8f Added filesystem module, tests and implementation for it in emulator.
+*
+**************************************************************************************************************************************/
+
#include "ll_filesystem.h"
#include
-bool ll_filesystem_init() {
- return false;
+bool ll_filesystem_init()
+{
+ return false;
}
-DIRECTORY_STRUCT* ll_filesystem_dir_open(const char* path) {
- return NULL;
+DIRECTORY_STRUCT* ll_filesystem_dir_open(const char* path)
+{
+ return NULL;
}
-void ll_filesystem_dir_close(DIRECTORY_STRUCT* dir) {
-
+void ll_filesystem_dir_close(DIRECTORY_STRUCT* dir)
+{
+
}
-FILE_HANDLE* ll_filesystem_file_open(const char* filename) {
- return NULL;
+FILE_HANDLE* ll_filesystem_file_open(const char* filename)
+{
+ return NULL;
}
-void ll_filesystem_file_close(FILE_HANDLE* handle) {
-
+void ll_filesystem_file_close(FILE_HANDLE* handle)
+{
+
}
-FILE_STATUS ll_filesystem_file_seek(FILE_HANDLE* handle, uint32_t offset) {
- return F_DISKERROR;
+FILE_STATUS ll_filesystem_file_seek(FILE_HANDLE* handle, uint32_t offset)
+{
+ return F_DISKERROR;
}
-FILE_STATUS ll_filesystem_file_read(FILE_HANDLE* handle, uint8_t* buf, uint32_t size) {
- return F_DISKERROR;
+FILE_STATUS ll_filesystem_file_read(FILE_HANDLE* handle, uint8_t* buf, uint32_t size)
+{
+ return F_DISKERROR;
}
-FILE_STATUS ll_filesystem_file_write(FILE_HANDLE* handle, uint8_t* buf, uint32_t size) {
- return F_DISKERROR;
+FILE_STATUS ll_filesystem_file_write(FILE_HANDLE* handle, uint8_t* buf, uint32_t size)
+{
+ return F_DISKERROR;
}
-
-
-
diff --git a/discovery/src/ll_system.c b/discovery/src/ll_system.c
index 3b93a6f..ca91429 100644
--- a/discovery/src/ll_system.c
+++ b/discovery/src/ll_system.c
@@ -1,60 +1,80 @@
-#include "ll_system.h"
-#include "stm32f4xx.h"
-#include "stm32f4_discovery.h"
-#include
-
-#include "usb_hcd_int.h"
-#include "usbh_usr.h"
-#include "usbh_core.h"
-#include "usbh_msc_core.h"
-
-USB_OTG_CORE_HANDLE USB_OTG_Core;
-USBH_HOST USB_Host;
-RCC_ClocksTypeDef RCC_Clocks;
-
-void SysTick_Handler(void)
-{
- USBH_LL_systick();
-}
-
-void TIM2_IRQHandler(void)
-{
- USB_OTG_BSP_TimerIRQ();
-}
-
-void OTG_FS_IRQHandler(void)
-{
- USBH_OTG_ISR_Handler(&USB_OTG_Core);
-}
-
-bool ll_system_init(void)
-{
- /* Initialize LEDS */
- STM_EVAL_LEDInit(LED3);
- STM_EVAL_LEDInit(LED4);
- //LED5 and LED6 can not be used because of pin conflict. See docu
-
- STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_GPIO);
-
-
- /* SysTick end of count event each 1ms */
- RCC_GetClocksFreq(&RCC_Clocks); //we run at 168mhz :)
- SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
-
- /* Init Host Library */
- USBH_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USB_Host, &USBH_MSC_cb, &USR_Callbacks);
-
- return true;
-}
-
-void ll_system_process() {
- USBH_Process(&USB_OTG_Core, &USB_Host);
-}
-
-void ll_system_delay(uint32_t msec) {
- USB_OTG_BSP_mDelay(msec);
-}
-
-void ll_system_toggle_led() {
- //no led's free :(
-}
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: discovery/src/ll_system.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 9a1d12a Refactored discovery, to use new project structure. Almost ready.
+* 2015-04-25 timolang@gmail.com 3d1e4b2 Simplified code a bit. Emulator does not work stable when replugging pixy.
+* 2015-04-25 timolang@gmail.com 0858b0d Fixed some bugs when receiving large data.
+* 2015-04-27 aaron@duckpond.ch 0b61f21 Fixed misplacement of prototypes in ll_tft.h and implemented a propper init function.
+* 2015-06-02 timolang@gmail.com 16bfdad Removed conflicting led usage from usb code.
+*
+**************************************************************************************************************************************/
+
+#include "ll_system.h"
+#include "stm32f4xx.h"
+#include "stm32f4_discovery.h"
+#include
+
+#include "usb_hcd_int.h"
+#include "usbh_usr.h"
+#include "usbh_core.h"
+#include "usbh_msc_core.h"
+
+USB_OTG_CORE_HANDLE USB_OTG_Core;
+USBH_HOST USB_Host;
+RCC_ClocksTypeDef RCC_Clocks;
+
+void SysTick_Handler(void)
+{
+ USBH_LL_systick();
+}
+
+void TIM2_IRQHandler(void)
+{
+ USB_OTG_BSP_TimerIRQ();
+}
+
+void OTG_FS_IRQHandler(void)
+{
+ USBH_OTG_ISR_Handler(&USB_OTG_Core);
+}
+
+bool ll_system_init(void)
+{
+ /* Initialize LEDS */
+ STM_EVAL_LEDInit(LED3);
+ STM_EVAL_LEDInit(LED4);
+ //LED5 and LED6 can not be used because of pin conflict. See docu
+
+ STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_GPIO);
+
+
+ /* SysTick end of count event each 1ms */
+ RCC_GetClocksFreq(&RCC_Clocks); //we run at 168mhz :)
+ SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
+
+ /* Init Host Library */
+ USBH_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USB_Host, &USBH_MSC_cb, &USR_Callbacks);
+
+ return true;
+}
+
+void ll_system_process()
+{
+ USBH_Process(&USB_OTG_Core, &USB_Host);
+}
+
+void ll_system_delay(uint32_t msec)
+{
+ USB_OTG_BSP_mDelay(msec);
+}
+
+void ll_system_toggle_led()
+{
+ //no led's free :(
+}
diff --git a/discovery/src/ll_tft.c b/discovery/src/ll_tft.c
index 0b25998..8d8756a 100644
--- a/discovery/src/ll_tft.c
+++ b/discovery/src/ll_tft.c
@@ -1,5 +1,31 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: discovery/src/ll_tft.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 9a1d12a Refactored discovery, to use new project structure. Almost ready.
+* 2015-04-03 timolang@gmail.com 1aa9194 Fixed Drawing of rects in Emulator. Got frames from pixy to emulator. Slooooow.
+* 2015-04-27 aaron@duckpond.ch aed90ef Drawcircle added (emulator)
+* 2015-04-27 timolang@gmail.com e249fb2 Added font support
+* 2015-04-27 aaron@duckpond.ch f0a6c3b Implemented init functions for gpio, fsmc and display
+* 2015-04-27 aaron@duckpond.ch 0b61f21 Fixed misplacement of prototypes in ll_tft.h and implemented a propper init function.
+* 2015-04-28 aaron@duckpond.ch a413591 Implemented ll_tft_fill_rectange and ll_tft_set_window
+* 2015-05-04 aaron@duckpond.ch c224d40 Changed display init
+* 2015-05-11 aaron@duckpond.ch 21fddc3 Implemented new functions
+* 2015-05-12 aaron@duckpond.ch aec62d4 Added datasheets, updated touchsupport.
+* 2015-06-01 aaron@duckpond.ch caa7b5c Added IRQ for user button, fixed some touchproblems.
+* 2015-06-01 timolang@gmail.com 60c2895 Fixed lowlevel tft discovery functions for draw_char and fill_rect.
+* 2015-06-02 timolang@gmail.com da34bce Fixed all printf related problems on discovery using workarounds and newlib nano-instead of newlib
+* 2015-06-06 aaron@duckpond.ch a04cda9 Refactured comments and implemented a bugfix for the PID controller
+*
+**************************************************************************************************************************************/
+
/* TFT lowlevel functions
- *
+ *
* Pinout:
* ----------------------------------------
* PB0 -> LCD_Backlight PE3 -> LCD_RS
@@ -42,17 +68,18 @@ static void tft_set_backlight(bool state);
static void tft_reset(bool state);
static void tft_write_reg(uint8_t reg_adr, uint16_t reg_value);
static uint16_t tft_read_reg(uint8_t reg_adr);
-static void tft_set_window(uint16_t xstart, uint16_t ystart, uint16_t xend, uint16_t yend);void tft_reset_window();
+static void tft_set_window(uint16_t xstart, uint16_t ystart, uint16_t xend, uint16_t yend);
+void tft_reset_window();
/* draw functions */
void ll_tft_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
-void ll_tft_draw_pixel(uint16_t x,uint16_t y,uint16_t color);
+void ll_tft_draw_pixel(uint16_t x, uint16_t y, uint16_t color);
void ll_tft_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
void ll_tft_draw_bitmap_unscaled(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t* dat);
void ll_tft_draw_circle(uint16_t x, uint16_t y, uint16_t r, uint16_t color);
/* font functions */
-static const char *get_font(uint8_t font);
+static const char* get_font(uint8_t font);
uint8_t ll_tft_num_fonts();
uint8_t ll_tft_font_height(uint8_t fontnum);
uint8_t ll_tft_font_width(uint8_t fontnum);
@@ -73,7 +100,7 @@ void ll_tft_draw_char(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolo
#define DISPLAY_COLOR_YELLOW 0xFFE0
#define DISPLAY_COLOR_GREY 0xF7DE
-// FSMC adresses
+// FSMC adresses
#define TFT_REG (*((volatile unsigned short *) 0x60000000)) // RS = 0
#define TFT_RAM (*((volatile unsigned short *) 0x60100000)) // RS = 1
#define TFT_RAM_ADR 0x60100000 // RAM adress
@@ -115,105 +142,105 @@ bool ll_tft_init()
fsmc = fsmc_init(); // init fsmc
system_delay(TFT_INIT_TIMEOUT); // delay
display = display_init(); // init display
-
+
return (gpio & fsmc & display);
}
-static bool display_init()
+static bool display_init()
{
tft_reset(true); // toggle reset
system_delay(TFT_INIT_TIMEOUT);
tft_reset(false);
- tft_write_reg(0x0007,0x0021);
+ tft_write_reg(0x0007, 0x0021);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0000,0x0001);
+ tft_write_reg(0x0000, 0x0001);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0007,0x0023);
+ tft_write_reg(0x0007, 0x0023);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0010,0x0000);
+ tft_write_reg(0x0010, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0007,0x0033);
+ tft_write_reg(0x0007, 0x0033);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(TFT_SSD1289_REG_11,0x6018); // set mode (landscape, portrait)
+ tft_write_reg(TFT_SSD1289_REG_11, 0x6018); // set mode (landscape, portrait)
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0002,0x0600);
+ tft_write_reg(0x0002, 0x0600);
system_delay(TFT_INIT_TIMEOUT);
//tft_write_reg(0x0012,0x6CEB);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0003,0xA8A4);
+ tft_write_reg(0x0003, 0xA8A4);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x000C,0x0000);
+ tft_write_reg(0x000C, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x000D,0x080C);
+ tft_write_reg(0x000D, 0x080C);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x000E,0x2B00);
+ tft_write_reg(0x000E, 0x2B00);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x001E,0x00B0);
+ tft_write_reg(0x001E, 0x00B0);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0001,0x2b3F);
+ tft_write_reg(0x0001, 0x2b3F);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0005,0x0000);
+ tft_write_reg(0x0005, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0006,0x0000);
+ tft_write_reg(0x0006, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0016,0xEF1C);
+ tft_write_reg(0x0016, 0xEF1C);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0017,0x0103);
+ tft_write_reg(0x0017, 0x0103);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x000B,0x0000);
+ tft_write_reg(0x000B, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x000F,0x0000);
+ tft_write_reg(0x000F, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0041,0x0000);
+ tft_write_reg(0x0041, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0042,0x0000);
+ tft_write_reg(0x0042, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0048,0x0000);
+ tft_write_reg(0x0048, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0049,0x013F);
+ tft_write_reg(0x0049, 0x013F);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x004A,0x0000);
+ tft_write_reg(0x004A, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x004B,0x0000);
+ tft_write_reg(0x004B, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0044,0xEF00); // horizontal start and end
+ tft_write_reg(0x0044, 0xEF00); // horizontal start and end
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0045,0x0000); // vertical start
+ tft_write_reg(0x0045, 0x0000); // vertical start
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0046,0x013F); // vertical end
+ tft_write_reg(0x0046, 0x013F); // vertical end
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0030,0x0707);
+ tft_write_reg(0x0030, 0x0707);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0031,0x0204);
+ tft_write_reg(0x0031, 0x0204);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0032,0x0204);
+ tft_write_reg(0x0032, 0x0204);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0033,0x0502);
+ tft_write_reg(0x0033, 0x0502);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0034,0x0507);
+ tft_write_reg(0x0034, 0x0507);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0035,0x0204);
+ tft_write_reg(0x0035, 0x0204);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0036,0x0204);
+ tft_write_reg(0x0036, 0x0204);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0037,0x0502);
+ tft_write_reg(0x0037, 0x0502);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x003A,0x0302);
+ tft_write_reg(0x003A, 0x0302);
system_delay(TFT_INIT_TIMEOUT);
//tft_write_reg(0x002F,0x12BE);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x003B,0x0302);
+ tft_write_reg(0x003B, 0x0302);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0023,0x0000);
+ tft_write_reg(0x0023, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0024,0x0000);
+ tft_write_reg(0x0024, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x0025,0x8000);
+ tft_write_reg(0x0025, 0x8000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x004f,0x0000);
+ tft_write_reg(0x004f, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
- tft_write_reg(0x004e,0x0000);
+ tft_write_reg(0x004e, 0x0000);
system_delay(TFT_INIT_TIMEOUT);
TFT_REG = TFT_SSD1289_REG_22;
@@ -225,11 +252,11 @@ static bool fsmc_init()
// generate init structures
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef FSMC_NORSRAMTimingInitStructure;
-
- // clock enable
- RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
-
- // prepare timing struct
+
+ // clock enable
+ RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
+
+ // prepare timing struct
FSMC_NORSRAMTimingInitStructure.FSMC_AddressSetupTime = TFT_SSD1289_FSMC_AST;
FSMC_NORSRAMTimingInitStructure.FSMC_AddressHoldTime = 1;
FSMC_NORSRAMTimingInitStructure.FSMC_DataSetupTime = TFT_SSD1289_FSMC_DST;
@@ -237,26 +264,26 @@ static bool fsmc_init()
FSMC_NORSRAMTimingInitStructure.FSMC_CLKDivision = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_DataLatency = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_AccessMode = FSMC_AccessMode_A;
-
+
// bank-1 / PSRAM-1
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
- FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
- FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
- FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
- FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
- FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
- FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
- FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
- FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
- FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTimingInitStructure;
+ FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
+ FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
+ FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
+ FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTimingInitStructure;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &FSMC_NORSRAMTimingInitStructure;
-
+
// config FSMC
- FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
+ FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
// enable Bank-1 / PSRAM-1
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
@@ -269,19 +296,19 @@ static bool gpio_init()
GPIO_InitTypeDef GPIO_InitStructure;
// clock enable PORT_B, PORT_D, PORT_E
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
-
- // PORT_B init
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
+
+ // PORT_B init
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// configure PORT_B
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+
// PORT_D init
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC); // PD0=FSMC_D2 -> DB2
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC); // PD1=FSMC_D3 -> DB3
@@ -290,25 +317,25 @@ static bool gpio_init()
GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_FSMC); // PD7=FSMC_NE1 -> CS
GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC); // PD8=FSMC_D13 -> DB15
GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC); // PD9=FSMC_D14 -> DB16
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC); // PD10=FSMC_D15 -> DB17
+ GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC); // PD10=FSMC_D15 -> DB17
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC); // PD14=FSMC_D0 -> DB0
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC); // PD15=FSMC_D1 -> DB1
// PORT_D struct
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
- GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
- GPIO_Pin_14 | GPIO_Pin_15;
+ GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
+ GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
// configure PORT_D
- GPIO_Init(GPIOD, &GPIO_InitStructure);
-
+ GPIO_Init(GPIOD, &GPIO_InitStructure);
+
// PORT_E init
GPIO_PinAFConfig(GPIOE, GPIO_PinSource3, GPIO_AF_FSMC); // PE3=FSMC_A19 -> RS
GPIO_PinAFConfig(GPIOE, GPIO_PinSource7, GPIO_AF_FSMC); // PE7=FSMC_D4 -> DB4
- GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_FSMC); // PE8=FSMC_D5 -> DB5
+ GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_FSMC); // PE8=FSMC_D5 -> DB5
GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_FSMC); // PE9=FSMC_D6 -> DB6
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_FSMC); // PE10=FSMC_D7 -> DB7
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_FSMC); // PE11=FSMC_D8 -> DB10
@@ -316,17 +343,17 @@ static bool gpio_init()
GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_FSMC); // PE13=FSMC_D10 -> DB12
GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_FSMC); // PE14=FSMC_D11 -> DB13
GPIO_PinAFConfig(GPIOE, GPIO_PinSource15, GPIO_AF_FSMC); // PE15=FSMC_D12 -> DB14
-
+
// PORT_E struct
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 |
- GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 |
- GPIO_Pin_14 | GPIO_Pin_15;
+ GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 |
+ GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
-
+
// configure PORT_E
GPIO_Init(GPIOE, &GPIO_InitStructure);
@@ -338,14 +365,14 @@ static bool gpio_init()
*/
// Clear the whole screen by filling it with a specifig color
-void ll_tft_clear(uint16_t color)
+void ll_tft_clear(uint16_t color)
{
uint32_t n = 0;
-
+
// set cursor to 0
- tft_set_cursor(0,0);
-
- for(n = 0; n < TFT_PIXEL; n++) {
+ tft_set_cursor(0, 0);
+
+ for (n = 0; n < TFT_PIXEL; n++) {
TFT_RAM = color;
}
}
@@ -355,24 +382,24 @@ static void tft_set_cursor(uint16_t xpos, uint16_t ypos)
{
// set cursor
tft_write_reg(TFT_SSD1289_REG_4E, ypos);
- tft_write_reg(TFT_SSD1289_REG_4F, 319-xpos);
+ tft_write_reg(TFT_SSD1289_REG_4F, 319 - xpos);
TFT_REG = TFT_SSD1289_REG_22;
}
// Enable / Disable the backlight
-static void tft_set_backlight(bool state)
+static void tft_set_backlight(bool state)
{
- if(state){ // if state is true
+ if (state) { // if state is true
GPIOB->BSRRH = GPIO_Pin_0; // set the backlight output
} else { // else
- GPIOB->BSRRL = GPIO_Pin_0; // reset the backlight
+ GPIOB->BSRRL = GPIO_Pin_0; // reset the backlight
}
}
// Port operations on the screen RS PIN
-static void tft_reset(bool state)
+static void tft_reset(bool state)
{
- if(state){ // if state is ture
+ if (state) { // if state is ture
GPIOB->BSRRH = GPIO_Pin_0; // Set the reset pin
} else { // else
GPIOB->BSRRL = GPIO_Pin_0; // reset the reset pin
@@ -396,16 +423,16 @@ static uint16_t tft_read_reg(uint8_t reg_adr)
// This sets a window for current draw functions
static void tft_set_window(uint16_t xstart, uint16_t ystart, uint16_t xend, uint16_t yend)
{
- uint16_t start,end;
+ uint16_t start, end;
uint16_t ystart_end;
start = (ystart & 0x00FF); // Start adress of the window
end = ((yend & 0x00FF) << 8); // End adress of the window
- ystart_end = (start | end); // Calculate y endpoint
+ ystart_end = (start | end); // Calculate y endpoint
tft_write_reg(TFT_SSD1289_REG_44, ystart_end); // Send y size
- tft_write_reg(TFT_SSD1289_REG_45, 319-xend); // Send x start
- tft_write_reg(TFT_SSD1289_REG_46, 319-xstart); // Send x end
+ tft_write_reg(TFT_SSD1289_REG_45, 319 - xend); // Send x start
+ tft_write_reg(TFT_SSD1289_REG_46, 319 - xstart); // Send x end
}
// Reset a Window
@@ -422,79 +449,64 @@ void tft_reset_window()
*/
// Draw a line on the given coordinates
-void ll_tft_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
+void ll_tft_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
- if(abs(x2-x1) > abs(y2-y1)) //line has more distance in x than y => iterate over x distance
- {
+ if (abs(x2 - x1) > abs(y2 - y1)) { //line has more distance in x than y => iterate over x distance
//Without floating point!
- int deltax = ((int)x2-(int)x1);
- int deltay = ((int)y2-(int)y1)<<1;
+ int deltax = ((int)x2 - (int)x1);
+ int deltay = ((int)y2 - (int)y1) << 1;
int x = 0;
- if (x1>x2)
- {
- do
- {
- tft_set_cursor(x1+x,y1+ (((long)deltay*(long)x/deltax+1)>>1));
+
+ if (x1 > x2) {
+ do {
+ tft_set_cursor(x1 + x, y1 + (((long)deltay * (long)x / deltax + 1) >> 1));
TFT_RAM = color;
- }
- while(x--!=deltax);
+ } while (x-- != deltax);
+ } else {
+ do {
+ tft_set_cursor(x1 + x, y1 + (((long)deltay * (long)x / deltax + 1) >> 1));
+ TFT_RAM = color;
+ } while (x++ != deltax);
}
- else
- {
- do
- {
- tft_set_cursor(x1+x,y1+ (((long)deltay*(long)x/deltax+1)>>1));
+ } else { // => iterate over y distance
+ int deltax = ((int)x2 - (int)x1) << 1;
+ int deltay = ((int)y2 - (int)y1);
+ int y = 0;
+
+ if (y1 > y2) {
+ do {
+ tft_set_cursor(x1 + (((long)deltax * (long)y / deltay + 1) >> 1), y1 + y);
TFT_RAM = color;
- }
- while(x++!=deltax);
+ } while (y-- != deltay);
+ } else {
+ do {
+ tft_set_cursor(x1 + (((long)deltax * (long)y / deltay + 1) >> 1), y1 + y);
+ TFT_RAM = color;
+ } while (y++ != deltay);
}
}
- else // => iterate over y distance
- {
- int deltax = ((int)x2-(int)x1)<<1;
- int deltay = ((int)y2-(int)y1);
- int y = 0;
- if (y1>y2)
- {
- do
- {
- tft_set_cursor(x1+ (((long)deltax*(long)y/deltay+1)>>1),y1+ y);
- TFT_RAM = color;
- }
- while(y--!=deltay);
- }
- else
- {
- do
- {
- tft_set_cursor(x1+ (((long)deltax*(long)y/deltay+1)>>1),y1+ y);
- TFT_RAM = color;
- }
- while(y++!=deltay);
- }
- }
}
// Draw a single pixel on (x,y) with the given color
-void ll_tft_draw_pixel(uint16_t x,uint16_t y,uint16_t color)
+void ll_tft_draw_pixel(uint16_t x, uint16_t y, uint16_t color)
{
- tft_set_cursor(x,y); // Set the cursor position
+ tft_set_cursor(x, y); // Set the cursor position
TFT_RAM = color; // Draw the pixel
}
// Draw a rectangle at the given coordinates with the given color
-void ll_tft_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
+void ll_tft_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
unsigned int tmp;
unsigned int i;
- if(x1 > x2){
+ if (x1 > x2) {
tmp = x1;
x1 = x2;
x2 = tmp;
}
- if(y1 > y2){
+ if (y1 > y2) {
tmp = y1;
y1 = y2;
y2 = tmp;
@@ -503,13 +515,20 @@ void ll_tft_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, u
i = x1;
//Drawing the two horizontal lines
tft_set_cursor(x1, y1);
- while(i++ != x2) TFT_RAM = color;
- tft_set_cursor(x1,y2);
- while(i-- != x1) TFT_RAM = color;
-
-
+
+ while (i++ != x2) {
+ TFT_RAM = color;
+ }
+
+ tft_set_cursor(x1, y2);
+
+ while (i-- != x1) {
+ TFT_RAM = color;
+ }
+
+
/*
- //uncommented because tft_write_reg seems to fail sometimes so it's safer to use draw line instead (below)
+ //uncommented because tft_write_reg seems to fail sometimes so it's safer to use draw line instead (below)
i = y1;
tft_write_reg(0x11,0x6030); // Change adresspointer direction
tft_set_cursor(x2, y1);
@@ -518,42 +537,42 @@ void ll_tft_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, u
while(i-- != y1) TFT_RAM = color;
tft_write_reg(0x11,0x6018); // Set adresspointer direction normal again
*/
- tft_draw_line(x1,y1,x1,y2,color);
- tft_draw_line(x2,y1,x2,y2,color);
-
+ tft_draw_line(x1, y1, x1, y2, color);
+ tft_draw_line(x2, y1, x2, y2, color);
+
}
// Draw a filled rectangle at the given coordinates with the given color
-void ll_tft_fill_rectangle(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2, uint16_t color)
+void ll_tft_fill_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
uint16_t area;
uint32_t n;
unsigned int tmp;
- if(x1 > x2){
+ if (x1 > x2) {
tmp = x1;
x1 = x2;
x2 = tmp;
}
- if(y1 > y2){
+ if (y1 > y2) {
tmp = y1;
y1 = y2;
y2 = tmp;
- }
+ }
- // set window
+ // set window
tft_set_window(x1, y1, x2, y2);
tft_set_cursor(x1, y1);
// calculate area
- area = (x2 - x1 + 1) * (y2 - y1 + 1);
+ area = (x2 - x1 + 1) * (y2 - y1 + 1);
// fill area
- for(n = 0; n < area; n++) {
+ for (n = 0; n < area; n++) {
TFT_RAM = color;
}
-
+
tft_reset_window();
}
@@ -571,77 +590,82 @@ void ll_tft_draw_circle(uint16_t x, uint16_t y, uint16_t r, uint16_t color)
* ---------------------- font functions -----------------------------------------------------------
*/
-static const char *get_font(uint8_t font)
+static const char* get_font(uint8_t font)
{
- switch(font){
- case 0: return small_font;
- case 1: return big_font;
- case 2: return seven_seg_num_font;
+ switch (font) {
+ case 0:
+ return small_font;
+
+ case 1:
+ return big_font;
+
+ case 2:
+ return seven_seg_num_font;
}
}
-uint8_t ll_tft_num_fonts()
+uint8_t ll_tft_num_fonts()
{
- return 3;
+ return 3;
}
-uint8_t ll_tft_font_height(uint8_t fontnum)
+uint8_t ll_tft_font_height(uint8_t fontnum)
{
- const char *font = get_font(fontnum);
+ const char* font = get_font(fontnum);
return (uint8_t) font[1];
}
-uint8_t ll_tft_font_width(uint8_t fontnum)
+uint8_t ll_tft_font_width(uint8_t fontnum)
{
- const char *font = get_font(fontnum);
+ const char* font = get_font(fontnum);
return (uint8_t) font[0];
}
-void ll_tft_draw_char(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t fontnum, char c)
+void ll_tft_draw_char(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t fontnum, char c)
{
- const char *font = get_font(fontnum);
+ const char* font = get_font(fontnum);
unsigned char width = (uint8_t) font[0];
unsigned char height = (uint8_t) font[1];
unsigned char offset = (uint8_t) font[2];
- unsigned int ind = ((c-offset) * ((width / 8) * height)) + 4;
+ unsigned int ind = ((c - offset) * ((width / 8) * height)) + 4;
unsigned int cnt = 0;
unsigned char bitm = 0;
bool bgIsTrans = (bgcolor == TRANSPARENT);
- unsigned char xadd=0;
- unsigned char yadd=0;
+ unsigned char xadd = 0;
+ unsigned char yadd = 0;
tft_set_window(x, y, x + width - 1, y + height - 1);
- tft_set_cursor(x, y);
-
- for(cnt = (width / 8) * height; cnt > 0; cnt--){
- for(bitm = 0x80; bitm > 0; bitm >>= 1){
- if((font[ind]) & bitm){
- if(bgIsTrans) {
- tft_set_cursor(x+xadd,y+yadd);
+ tft_set_cursor(x, y);
+
+ for (cnt = (width / 8) * height; cnt > 0; cnt--) {
+ for (bitm = 0x80; bitm > 0; bitm >>= 1) {
+ if ((font[ind]) & bitm) {
+ if (bgIsTrans) {
+ tft_set_cursor(x + xadd, y + yadd);
}
+
TFT_RAM = color;
-
+
} else {
- if(!bgIsTrans) {
+ if (!bgIsTrans) {
TFT_RAM = bgcolor;
- }
+ }
+ }
+
+ if (bgIsTrans) {
+ xadd++;
+
+ if (xadd == width) {
+ xadd = 0;
+ yadd++;
+ }
}
-
- if(bgIsTrans)
- {
- xadd++;
- if(xadd==width)
- {
- xadd=0;
- yadd++;
- }
- }
}
-
+
ind++;
}
-
+
tft_reset_window();
}
diff --git a/discovery/src/ll_touch.c b/discovery/src/ll_touch.c
index 7d5d21a..9370d24 100644
--- a/discovery/src/ll_touch.c
+++ b/discovery/src/ll_touch.c
@@ -1,3 +1,28 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: discovery/src/ll_touch.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com 259d446 Added touch support to emulator. Implemented basic touch function.
+* 2015-05-12 aaron@duckpond.ch 3b2ef30 Added PID source code and Pinmap
+* 2015-05-12 aaron@duckpond.ch 5e374f4 Added datasheet and touch template
+* 2015-05-12 aaron@duckpond.ch aec62d4 Added datasheets, updated touchsupport.
+* 2015-05-13 aaron@duckpond.ch 1396d24 Working touchcontroller communication
+* 2015-05-28 aaron@duckpond.ch 5bda699 implemented functions to get x and y coordinates and a test function
+* 2015-05-28 aaron@duckpond.ch 9b1020c Working PENIRQ
+* 2015-05-28 aaron@duckpond.ch 30197bf recent changes
+* 2015-05-29 aaron@duckpond.ch 7d2d1a1 Implemented basic sampling and averaging of touch coordinates using timer7
+* 2015-06-01 aaron@duckpond.ch dff2e76 Touch recognition working
+* 2015-06-01 aaron@duckpond.ch caa7b5c Added IRQ for user button, fixed some touchproblems.
+* 2015-06-01 timolang@gmail.com eb573bc Finalized calibration. Fixed a bug in screen module.
+* 2015-06-03 timolang@gmail.com 74aa186 Made pixy_test screen working again. Had to disable pixy_service. Recalibrated initial touch values.
+*
+**************************************************************************************************************************************/
+
#include "ll_touch.h"
#include "screen.h"
#include "screen_calibrate.h"
@@ -22,8 +47,8 @@
/* Globals ----------------------------------------------------------- */
volatile bool pen_state = false; // PenDown = True; PenUp = False;
volatile bool tim_flag = false;
-volatile uint16_t x_samples[NSAMPLE-1];
-volatile uint16_t y_samples[NSAMPLE-1];
+volatile uint16_t x_samples[NSAMPLE - 1];
+volatile uint16_t y_samples[NSAMPLE - 1];
volatile int i;
/* Prototypes -------------------------------------------------------- */
@@ -42,11 +67,11 @@ static uint16_t avg_vals(volatile uint16_t samples[], uint16_t len)
uint16_t j = 0;
uint32_t tmp = 0;
- for(j = 0; j < len; j++){
- tmp += samples[j];
+ for (j = 0; j < len; j++) {
+ tmp += samples[j];
}
- return (uint16_t)(tmp/len);
+ return (uint16_t)(tmp / len);
}
static uint16_t touch_get_x_coord()
@@ -54,8 +79,8 @@ static uint16_t touch_get_x_coord()
uint16_t buf_x = 0;
CLEAR_CS; // clear chipselect
touch_send(REQ_X_COORD); // request x coordinate
-
- buf_x = ((uint16_t) touch_send(REQ_1_DATAB)) << 5;
+
+ buf_x = ((uint16_t) touch_send(REQ_1_DATAB)) << 5;
buf_x |= touch_send(REQ_1_DATAB) >> 3;
SET_CS; // set chipselect
@@ -69,7 +94,7 @@ static uint16_t touch_get_y_coord()
CLEAR_CS; // clear chipselect
touch_send(REQ_Y_COORD); // request y coordinate
-
+
buf_y = ((uint16_t) touch_send(REQ_1_DATAB)) << 5;
buf_y |= touch_send(REQ_1_DATAB) >> 3;
@@ -80,10 +105,13 @@ static uint16_t touch_get_y_coord()
static uint8_t touch_send(uint8_t dat)
{
- SPI_I2S_SendData(SPI2, dat);
- while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) != RESET);
- while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
- return SPI_I2S_ReceiveData(SPI2);
+ SPI_I2S_SendData(SPI2, dat);
+
+ while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) != RESET);
+
+ while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
+
+ return SPI_I2S_ReceiveData(SPI2);
}
void touch_test(uint16_t x, uint16_t y)
@@ -100,12 +128,12 @@ void touch_test(uint16_t x, uint16_t y)
tft_print_line(10, 30, WHITE, TRANSPARENT, 0, (const char*)ys);
}
-bool ll_touch_init()
+bool ll_touch_init()
{
touch_set_value_convert_mode(true); //Tell the touch module that we need converted values and display calibration
touch_set_calibration_values(526, 2922, 588, 2736); //set calibration values (copied from memory using the debugger)
-
-
+
+
//We have a ADS7843 Touch controller
//Datasheet: http://www.ti.com/lit/ds/symlink/ads7843.pdf
@@ -124,13 +152,13 @@ bool ll_touch_init()
GPIO_SPI2_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_SPI2_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_SPI2_InitStructure);
-
+
SET_CS; // set chip select
/* fill gpio init struct and init gpio */
GPIO_StructInit(&GPIO_SPI2_InitStructure);
GPIO_SPI2_InitStructure.GPIO_Pin = GPIO_Pin_9; // 9 = SPI2_CS
- GPIO_SPI2_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_SPI2_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_SPI2_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_SPI2_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_SPI2_InitStructure);
@@ -139,7 +167,7 @@ bool ll_touch_init()
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
-
+
SPI_I2S_DeInit(SPI2); // Clear spi initialisation
/* fill spi init structure */
@@ -184,9 +212,9 @@ static void init_exti()
gpio.GPIO_PuPd = GPIO_PuPd_UP;
gpio.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOC, &gpio);
-
+
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource1); // Bind Exti_line1 to PC1
-
+
/* Set GPIOA0 as input */
gpio.GPIO_Mode = GPIO_Mode_IN;
gpio.GPIO_OType = GPIO_OType_OD;
@@ -201,10 +229,10 @@ static void init_exti()
EXTI_StructInit(&exti);
exti.EXTI_Line = EXTI_Line1;
exti.EXTI_Mode = EXTI_Mode_Interrupt;
- exti.EXTI_Trigger = EXTI_Trigger_Falling; // Trigger on falling edge (PENIRQ)
+ exti.EXTI_Trigger = EXTI_Trigger_Falling; // Trigger on falling edge (PENIRQ)
exti.EXTI_LineCmd = ENABLE;
EXTI_Init(&exti);
-
+
/* EXTI on PA0 */
EXTI_StructInit(&exti);
exti.EXTI_Line = EXTI_Line0;
@@ -219,7 +247,7 @@ static void init_exti()
nvic.NVIC_IRQChannelSubPriority = 0x00; // Set sub priority
nvic.NVIC_IRQChannelCmd = ENABLE; // Enable interrupt
NVIC_Init(&nvic); // Config NVIC
-
+
/* Add IRQ vector to NVIC */
nvic.NVIC_IRQChannel = EXTI0_IRQn; // PA0 -> EXTI_Line0 -> EXTI0_IRQn vector
nvic.NVIC_IRQChannelPreemptionPriority = 0x00; // Set priority
@@ -232,7 +260,7 @@ static void init_timer()
{
TIM_TimeBaseInitTypeDef t;
const int APB1_CLK = 42E6;
-
+
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE); // Enable clock for TIM6
/* Timer 7 configuration */
@@ -263,16 +291,16 @@ void EXTI1_IRQHandler()
void TIM7_IRQHandler()
{
- if(TIM_GetFlagStatus(TIM7, TIM_IT_Update) == SET){ // Make sure the interrupt flag is set
-
+ if (TIM_GetFlagStatus(TIM7, TIM_IT_Update) == SET) { // Make sure the interrupt flag is set
+
TIM_Cmd(TIM7, DISABLE); // Disable the timer during the measuring
- if(PENIRQ){ // Only do this if the PENIRQ line is still low
- for(i = 0; i < (NSAMPLE-1); i++){ // Sample 16 times
+ if (PENIRQ) { // Only do this if the PENIRQ line is still low
+ for (i = 0; i < (NSAMPLE - 1); i++) { // Sample 16 times
x_samples[i] = touch_get_x_coord();
y_samples[i] = touch_get_y_coord();
}
-
+
touch_add_raw_event(avg_vals(x_samples, NSAMPLE), avg_vals(y_samples, NSAMPLE), TOUCH_DOWN); // Update position
//tft_draw_pixel(avg_vals(x_samples, NSAMPLE), avg_vals(y_samples, NSAMPLE), RED);
TIM_Cmd(TIM7, ENABLE); // Reenable timer
@@ -281,8 +309,8 @@ void TIM7_IRQHandler()
touch_add_raw_event(avg_vals(x_samples, NSAMPLE), avg_vals(y_samples, NSAMPLE), TOUCH_UP); // Update position one last time
//tft_draw_pixel(avg_vals(x_samples, NSAMPLE), avg_vals(y_samples, NSAMPLE), RED);
TIM_Cmd(TIM7, DISABLE); // Disable timer
- }
+ }
TIM_ClearFlag(TIM7, TIM_IT_Update); // Clear timer interrupt flag
- }
+ }
}
diff --git a/discovery/src/main.c b/discovery/src/main.c
index 4429e45..98ada12 100644
--- a/discovery/src/main.c
+++ b/discovery/src/main.c
@@ -1,12 +1,27 @@
-#include "app.h"
-
-int main(void)
-{
- app_init();
-
- while (1)
- {
- app_process();
- }
-
-}
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: discovery/src/main.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 21dd1e2 Starting to integrate usb branch. Optimized Makefiles
+* 2015-04-03 timolang@gmail.com 9a1d12a Refactored discovery, to use new project structure. Almost ready.
+* 2015-04-25 timolang@gmail.com 416883c Pixy&Usb work with the new folder structure now.
+* 2015-04-25 timolang@gmail.com 3d1e4b2 Simplified code a bit. Emulator does not work stable when replugging pixy.
+*
+**************************************************************************************************************************************/
+
+#include "app.h"
+
+int main(void)
+{
+ app_init();
+
+ while (1) {
+ app_process();
+ }
+
+}
diff --git a/discovery/src/newlib_stubs.c b/discovery/src/newlib_stubs.c
index a936be2..b46cb47 100644
--- a/discovery/src/newlib_stubs.c
+++ b/discovery/src/newlib_stubs.c
@@ -1,3 +1,16 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: discovery/src/newlib_stubs.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 21dd1e2 Starting to integrate usb branch. Optimized Makefiles
+*
+**************************************************************************************************************************************/
+
/*
* newlib_stubs.c
*
@@ -32,26 +45,30 @@ extern int errno;
A pointer to a list of environment variables and their values.
For a minimal environment, this empty list is adequate:
*/
-char *__env[1] = { 0 };
-char **environ = __env;
+char* __env[1] = { 0 };
+char** environ = __env;
-int _write(int file, char *ptr, int len);
+int _write(int file, char* ptr, int len);
-void _exit(int status) {
+void _exit(int status)
+{
_write(1, "exit", 4);
+
while (1) {
;
}
}
-int _close(int file) {
+int _close(int file)
+{
return -1;
}
/*
execve
Transfer control to a new process. Minimal implementation (for a system without processes):
*/
-int _execve(char *name, char **argv, char **env) {
+int _execve(char* name, char** argv, char** env)
+{
errno = ENOMEM;
return -1;
}
@@ -60,7 +77,8 @@ int _execve(char *name, char **argv, char **env) {
Create a new process. Minimal implementation (for a system without processes):
*/
-int _fork() {
+int _fork()
+{
errno = EAGAIN;
return -1;
}
@@ -70,7 +88,8 @@ int _fork() {
all files are regarded as character special devices.
The `sys/stat.h' header file required is distributed in the `include' subdirectory for this C library.
*/
-int _fstat(int file, struct stat *st) {
+int _fstat(int file, struct stat* st)
+{
st->st_mode = S_IFCHR;
return 0;
}
@@ -80,7 +99,8 @@ int _fstat(int file, struct stat *st) {
Process-ID; this is sometimes used to generate strings unlikely to conflict with other processes. Minimal implementation, for a system without processes:
*/
-int _getpid() {
+int _getpid()
+{
return 1;
}
@@ -88,12 +108,14 @@ int _getpid() {
isatty
Query whether output stream is a terminal. For consistency with the other minimal implementations,
*/
-int _isatty(int file) {
- switch (file){
+int _isatty(int file)
+{
+ switch (file) {
case STDOUT_FILENO:
case STDERR_FILENO:
case STDIN_FILENO:
return 1;
+
default:
//errno = ENOTTY;
errno = EBADF;
@@ -106,7 +128,8 @@ int _isatty(int file) {
kill
Send a signal. Minimal implementation:
*/
-int _kill(int pid, int sig) {
+int _kill(int pid, int sig)
+{
errno = EINVAL;
return (-1);
}
@@ -116,7 +139,8 @@ int _kill(int pid, int sig) {
Establish a new name for an existing file. Minimal implementation:
*/
-int _link(char *old, char *new) {
+int _link(char* old, char* new)
+{
errno = EMLINK;
return -1;
}
@@ -125,7 +149,8 @@ int _link(char *old, char *new) {
lseek
Set position in a file. Minimal implementation:
*/
-int _lseek(int file, int ptr, int dir) {
+int _lseek(int file, int ptr, int dir)
+{
return 0;
}
@@ -134,25 +159,27 @@ int _lseek(int file, int ptr, int dir) {
Increase program data space.
Malloc and related functions depend on this
*/
-caddr_t _sbrk(int incr) {
+caddr_t _sbrk(int incr)
+{
extern char _ebss; // Defined by the linker
- static char *heap_end;
- char *prev_heap_end;
+ static char* heap_end;
+ char* prev_heap_end;
if (heap_end == 0) {
heap_end = &_ebss;
}
+
prev_heap_end = heap_end;
-char * stack = (char*) __get_MSP();
- if (heap_end + incr > stack)
- {
- _write (STDERR_FILENO, "Heap and stack collision\n", 25);
- errno = ENOMEM;
- return (caddr_t) -1;
- //abort ();
- }
+ char* stack = (char*) __get_MSP();
+
+ if (heap_end + incr > stack) {
+ _write(STDERR_FILENO, "Heap and stack collision\n", 25);
+ errno = ENOMEM;
+ return (caddr_t) - 1;
+ //abort ();
+ }
heap_end += incr;
return (caddr_t) prev_heap_end;
@@ -161,10 +188,10 @@ char * stack = (char*) __get_MSP();
-int _open(char *path, int flags, ...)
+int _open(char* path, int flags, ...)
{
- /* Pretend like we always fail */
- return -1;
+ /* Pretend like we always fail */
+ return -1;
}
/*
@@ -174,30 +201,33 @@ int _open(char *path, int flags, ...)
*/
-int _read(int file, char *ptr, int len) {
+int _read(int file, char* ptr, int len)
+{
int n;
int num = 0;
+
switch (file) {
- /*case STDIN_FILENO:
- for (n = 0; n < len; n++) {
-#if STDIN_USART == 1
- while ((USART1->SR & USART_FLAG_RXNE) == (uint16_t)RESET) {}
- char c = (char)(USART1->DR & (uint16_t)0x01FF);
-#elif STDIN_USART == 2
- while ((USART2->SR & USART_FLAG_RXNE) == (uint16_t) RESET) {}
- char c = (char) (USART2->DR & (uint16_t) 0x01FF);
-#elif STDIN_USART == 3
- while ((USART3->SR & USART_FLAG_RXNE) == (uint16_t)RESET) {}
- char c = (char)(USART3->DR & (uint16_t)0x01FF);
-#endif
- *ptr++ = c;
- num++;
- }
- break;
- default:*/
+ /*case STDIN_FILENO:
+ for (n = 0; n < len; n++) {
+ #if STDIN_USART == 1
+ while ((USART1->SR & USART_FLAG_RXNE) == (uint16_t)RESET) {}
+ char c = (char)(USART1->DR & (uint16_t)0x01FF);
+ #elif STDIN_USART == 2
+ while ((USART2->SR & USART_FLAG_RXNE) == (uint16_t) RESET) {}
+ char c = (char) (USART2->DR & (uint16_t) 0x01FF);
+ #elif STDIN_USART == 3
+ while ((USART3->SR & USART_FLAG_RXNE) == (uint16_t)RESET) {}
+ char c = (char)(USART3->DR & (uint16_t)0x01FF);
+ #endif
+ *ptr++ = c;
+ num++;
+ }
+ break;
+ default:*/
errno = EBADF;
return -1;
}
+
return num;
}
@@ -207,7 +237,8 @@ int _read(int file, char *ptr, int len) {
int _EXFUN(stat,( const char *__path, struct stat *__sbuf ));
*/
-int _stat(const char *filepath, struct stat *st) {
+int _stat(const char* filepath, struct stat* st)
+{
st->st_mode = S_IFCHR;
return 0;
}
@@ -217,7 +248,8 @@ int _stat(const char *filepath, struct stat *st) {
Timing information for current process. Minimal implementation:
*/
-clock_t _times(struct tms *buf) {
+clock_t _times(struct tms* buf)
+{
return -1;
}
@@ -225,7 +257,8 @@ clock_t _times(struct tms *buf) {
unlink
Remove a file's directory entry. Minimal implementation:
*/
-int _unlink(char *name) {
+int _unlink(char* name)
+{
errno = ENOENT;
return -1;
}
@@ -234,7 +267,8 @@ int _unlink(char *name) {
wait
Wait for a child process. Minimal implementation:
*/
-int _wait(int *status) {
+int _wait(int* status)
+{
errno = ECHILD;
return -1;
}
@@ -244,42 +278,61 @@ int _wait(int *status) {
Write a character to a file. `libc' subroutines will use this system routine for output to all files, including stdout
Returns -1 on error or number of bytes sent
*/
-int _write(int file, char *ptr, int len) {
+int _write(int file, char* ptr, int len)
+{
int n;
+
switch (file) {
case STDOUT_FILENO: /*stdout*/
for (n = 0; n < len; n++) {
#if STDOUT_USART == 1
+
while ((USART1->SR & USART_FLAG_TC) == (uint16_t)RESET) {}
+
USART1->DR = (*ptr++ & (uint16_t)0x01FF);
#elif STDOUT_USART == 2
+
while ((USART2->SR & USART_FLAG_TC) == (uint16_t) RESET) {
}
+
USART2->DR = (*ptr++ & (uint16_t) 0x01FF);
#elif STDOUT_USART == 3
+
while ((USART3->SR & USART_FLAG_TC) == (uint16_t)RESET) {}
+
USART3->DR = (*ptr++ & (uint16_t)0x01FF);
#endif
}
+
break;
+
case STDERR_FILENO: /* stderr */
for (n = 0; n < len; n++) {
#if STDERR_USART == 1
+
while ((USART1->SR & USART_FLAG_TC) == (uint16_t)RESET) {}
+
USART1->DR = (*ptr++ & (uint16_t)0x01FF);
#elif STDERR_USART == 2
+
while ((USART2->SR & USART_FLAG_TC) == (uint16_t) RESET) {
}
+
USART2->DR = (*ptr++ & (uint16_t) 0x01FF);
#elif STDERR_USART == 3
+
while ((USART3->SR & USART_FLAG_TC) == (uint16_t)RESET) {}
+
USART3->DR = (*ptr++ & (uint16_t)0x01FF);
#endif
}
+
break;
+
default:
errno = EBADF;
return -1;
}
+
return len;
}
diff --git a/discovery/src/system_stm32f4xx.c b/discovery/src/system_stm32f4xx.c
index 429d56b..6520543 100644
--- a/discovery/src/system_stm32f4xx.c
+++ b/discovery/src/system_stm32f4xx.c
@@ -1,545 +1,551 @@
-/**
- ******************************************************************************
- * @file system_stm32f4xx.c
- * @author MCD Application Team
- * @version V1.0.0
- * @date 19-September-2011
- * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
- * This file contains the system clock configuration for STM32F4xx devices,
- * and is generated by the clock configuration tool
- * stm32f4xx_Clock_Configuration_V1.0.0.xls
- *
- * 1. This file provides two functions and one global variable to be called from
- * user application:
- * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
- * and Divider factors, AHB/APBx prescalers and Flash settings),
- * depending on the configuration made in the clock xls tool.
- * This function is called at startup just after reset and
- * before branch to main program. This call is made inside
- * the "startup_stm32f4xx.s" file.
- *
- * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
- * by the user application to setup the SysTick
- * timer or configure other parameters.
- *
- * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
- * be called whenever the core clock is changed
- * during program execution.
- *
- * 2. After each device reset the HSI (16 MHz) is used as system clock source.
- * Then SystemInit() function is called, in "startup_stm32f4xx.s" file, to
- * configure the system clock before to branch to main program.
- *
- * 3. If the system clock source selected by user fails to startup, the SystemInit()
- * function will do nothing and HSI still used as system clock source. User can
- * add some code to deal with this issue inside the SetSysClock() function.
- *
- * 4. The default value of HSE crystal is set to 8 MHz, refer to "HSE_VALUE" define
- * in "stm32f4xx.h" file. When HSE is used as system clock source, directly or
- * through PLL, and you are using different crystal you have to adapt the HSE
- * value to your own configuration.
- *
- * 5. This file configures the system clock as follows:
- *=============================================================================
- *=============================================================================
- * Supported STM32F4xx device revision | Rev A
- *-----------------------------------------------------------------------------
- * System Clock source | PLL (HSE)
- *-----------------------------------------------------------------------------
- * SYSCLK(Hz) | 168000000
- *-----------------------------------------------------------------------------
- * HCLK(Hz) | 168000000
- *-----------------------------------------------------------------------------
- * AHB Prescaler | 1
- *-----------------------------------------------------------------------------
- * APB1 Prescaler | 4
- *-----------------------------------------------------------------------------
- * APB2 Prescaler | 2
- *-----------------------------------------------------------------------------
- * HSE Frequency(Hz) | 8000000
- *-----------------------------------------------------------------------------
- * PLL_M | 8
- *-----------------------------------------------------------------------------
- * PLL_N | 336
- *-----------------------------------------------------------------------------
- * PLL_P | 2
- *-----------------------------------------------------------------------------
- * PLL_Q | 7
- *-----------------------------------------------------------------------------
- * PLLI2S_N | NA
- *-----------------------------------------------------------------------------
- * PLLI2S_R | NA
- *-----------------------------------------------------------------------------
- * I2S input clock | NA
- *-----------------------------------------------------------------------------
- * VDD(V) | 3.3
- *-----------------------------------------------------------------------------
- * High Performance mode | Enabled
- *-----------------------------------------------------------------------------
- * Flash Latency(WS) | 5
- *-----------------------------------------------------------------------------
- * Prefetch Buffer | OFF
- *-----------------------------------------------------------------------------
- * Instruction cache | ON
- *-----------------------------------------------------------------------------
- * Data cache | ON
- *-----------------------------------------------------------------------------
- * Require 48MHz for USB OTG FS, | Enabled
- * SDIO and RNG clock |
- *-----------------------------------------------------------------------------
- *=============================================================================
- ******************************************************************************
- * @attention
- *
- * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
- * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
- * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
- * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
- * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
- * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
- *
- * © COPYRIGHT 2011 STMicroelectronics
- ******************************************************************************
- */
-
-/** @addtogroup CMSIS
- * @{
- */
-
-/** @addtogroup stm32f4xx_system
- * @{
- */
-
-/** @addtogroup STM32F4xx_System_Private_Includes
- * @{
- */
-
-#include "stm32f4xx.h"
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F4xx_System_Private_TypesDefinitions
- * @{
- */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F4xx_System_Private_Defines
- * @{
- */
-
-/*!< Uncomment the following line if you need to use external SRAM mounted
- on STM324xG_EVAL board as data memory */
-/* #define DATA_IN_ExtSRAM */
-
-/*!< Uncomment the following line if you need to relocate your vector Table in
- Internal SRAM. */
-/* #define VECT_TAB_SRAM */
-#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
- This value must be a multiple of 0x200. */
-
-
-/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
-#define PLL_M 8
-#define PLL_N 336
-
-/* SYSCLK = PLL_VCO / PLL_P */
-#define PLL_P 2
-
-/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
-#define PLL_Q 7
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F4xx_System_Private_Macros
- * @{
- */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F4xx_System_Private_Variables
- * @{
- */
-
- uint32_t SystemCoreClock = 168000000;
-
- __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
- * @{
- */
-
-static void SetSysClock(void);
-#ifdef DATA_IN_ExtSRAM
- static void SystemInit_ExtMemCtl(void);
-#endif /* DATA_IN_ExtSRAM */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F4xx_System_Private_Functions
- * @{
- */
-
-/**
- * @brief Setup the microcontroller system
- * Initialize the Embedded Flash Interface, the PLL and update the
- * SystemFrequency variable.
- * @param None
- * @retval None
- */
-void SystemInit(void)
-{
- /* Reset the RCC clock configuration to the default reset state ------------*/
- /* Set HSION bit */
- RCC->CR |= (uint32_t)0x00000001;
-
- /* Reset CFGR register */
- RCC->CFGR = 0x00000000;
-
- /* Reset HSEON, CSSON and PLLON bits */
- RCC->CR &= (uint32_t)0xFEF6FFFF;
-
- /* Reset PLLCFGR register */
- RCC->PLLCFGR = 0x24003010;
-
- /* Reset HSEBYP bit */
- RCC->CR &= (uint32_t)0xFFFBFFFF;
-
- /* Disable all interrupts */
- RCC->CIR = 0x00000000;
-
-#ifdef DATA_IN_ExtSRAM
- SystemInit_ExtMemCtl();
-#endif /* DATA_IN_ExtSRAM */
-
- /* Configure the System clock source, PLL Multiplier and Divider factors,
- AHB/APBx prescalers and Flash settings ----------------------------------*/
- SetSysClock();
-
- /* Configure the Vector Table location add offset address ------------------*/
-#ifdef VECT_TAB_SRAM
- SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
-#else
- SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
-#endif
-}
-
-/**
- * @brief Update SystemCoreClock variable according to Clock Register Values.
- * The SystemCoreClock variable contains the core clock (HCLK), it can
- * be used by the user application to setup the SysTick timer or configure
- * other parameters.
- *
- * @note Each time the core clock (HCLK) changes, this function must be called
- * to update SystemCoreClock variable value. Otherwise, any configuration
- * based on this variable will be incorrect.
- *
- * @note - The system frequency computed by this function is not the real
- * frequency in the chip. It is calculated based on the predefined
- * constant and the selected clock source:
- *
- * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
- *
- * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
- *
- * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
- * or HSI_VALUE(*) multiplied/divided by the PLL factors.
- *
- * (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value
- * 16 MHz) but the real value may vary depending on the variations
- * in voltage and temperature.
- *
- * (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value
- * 25 MHz), user has to ensure that HSE_VALUE is same as the real
- * frequency of the crystal used. Otherwise, this function may
- * have wrong result.
- *
- * - The result of this function could be not correct when using fractional
- * value for HSE crystal.
- *
- * @param None
- * @retval None
- */
-void SystemCoreClockUpdate(void)
-{
- uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
-
- /* Get SYSCLK source -------------------------------------------------------*/
- tmp = RCC->CFGR & RCC_CFGR_SWS;
-
- switch (tmp)
- {
- case 0x00: /* HSI used as system clock source */
- SystemCoreClock = HSI_VALUE;
- break;
- case 0x04: /* HSE used as system clock source */
- SystemCoreClock = HSE_VALUE;
- break;
- case 0x08: /* PLL used as system clock source */
-
- /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
- SYSCLK = PLL_VCO / PLL_P
- */
- pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
- pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
-
- if (pllsource != 0)
- {
- /* HSE used as PLL clock source */
- pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
- }
- else
- {
- /* HSI used as PLL clock source */
- pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
- }
-
- pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
- SystemCoreClock = pllvco/pllp;
- break;
- default:
- SystemCoreClock = HSI_VALUE;
- break;
- }
- /* Compute HCLK frequency --------------------------------------------------*/
- /* Get HCLK prescaler */
- tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
- /* HCLK frequency */
- SystemCoreClock >>= tmp;
-}
-
-/**
- * @brief Configures the System clock source, PLL Multiplier and Divider factors,
- * AHB/APBx prescalers and Flash settings
- * @Note This function should be called only once the RCC clock configuration
- * is reset to the default reset state (done in SystemInit() function).
- * @param None
- * @retval None
- */
-static void SetSysClock(void)
-{
-/******************************************************************************/
-/* PLL (clocked by HSE) used as System clock source */
-/******************************************************************************/
- __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
-
- /* Enable HSE */
- RCC->CR |= ((uint32_t)RCC_CR_HSEON);
-
- /* Wait till HSE is ready and if Time out is reached exit */
- do
- {
- HSEStatus = RCC->CR & RCC_CR_HSERDY;
- StartUpCounter++;
- } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
-
- if ((RCC->CR & RCC_CR_HSERDY) != RESET)
- {
- HSEStatus = (uint32_t)0x01;
- }
- else
- {
- HSEStatus = (uint32_t)0x00;
- }
-
- if (HSEStatus == (uint32_t)0x01)
- {
- /* Enable high performance mode, System frequency up to 168 MHz */
- RCC->APB1ENR |= RCC_APB1ENR_PWREN;
- PWR->CR |= PWR_CR_PMODE;
-
- /* HCLK = SYSCLK / 1*/
- RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
-
- /* PCLK2 = HCLK / 2*/
- RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
-
- /* PCLK1 = HCLK / 4*/
- RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
-
- /* Configure the main PLL */
- RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
- (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
-
- /* Enable the main PLL */
- RCC->CR |= RCC_CR_PLLON;
-
- /* Wait till the main PLL is ready */
- while((RCC->CR & RCC_CR_PLLRDY) == 0)
- {
- }
-
- /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
- FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
-
- /* Select the main PLL as system clock source */
- RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
- RCC->CFGR |= RCC_CFGR_SW_PLL;
-
- /* Wait till the main PLL is used as system clock source */
- while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
- {
- }
- }
- else
- { /* If HSE fails to start-up, the application will have wrong clock
- configuration. User can add here some code to deal with this error */
- }
-
-}
-
-/**
- * @brief Setup the external memory controller. Called in startup_stm32f4xx.s
- * before jump to __main
- * @param None
- * @retval None
- */
-#ifdef DATA_IN_ExtSRAM
-/**
- * @brief Setup the external memory controller.
- * Called in startup_stm32f4xx.s before jump to main.
- * This function configures the external SRAM mounted on STM324xG_EVAL board
- * This SRAM will be used as program data memory (including heap and stack).
- * @param None
- * @retval None
- */
-void SystemInit_ExtMemCtl(void)
-{
-/*-- GPIOs Configuration -----------------------------------------------------*/
-/*
- +-------------------+--------------------+------------------+------------------+
- + SRAM pins assignment +
- +-------------------+--------------------+------------------+------------------+
- | PD0 <-> FSMC_D2 | PE0 <-> FSMC_NBL0 | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 |
- | PD1 <-> FSMC_D3 | PE1 <-> FSMC_NBL1 | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 |
- | PD4 <-> FSMC_NOE | PE3 <-> FSMC_A19 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 |
- | PD5 <-> FSMC_NWE | PE4 <-> FSMC_A20 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 |
- | PD8 <-> FSMC_D13 | PE7 <-> FSMC_D4 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 |
- | PD9 <-> FSMC_D14 | PE8 <-> FSMC_D5 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 |
- | PD10 <-> FSMC_D15 | PE9 <-> FSMC_D6 | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 |
- | PD11 <-> FSMC_A16 | PE10 <-> FSMC_D7 | PF13 <-> FSMC_A7 |------------------+
- | PD12 <-> FSMC_A17 | PE11 <-> FSMC_D8 | PF14 <-> FSMC_A8 |
- | PD13 <-> FSMC_A18 | PE12 <-> FSMC_D9 | PF15 <-> FSMC_A9 |
- | PD14 <-> FSMC_D0 | PE13 <-> FSMC_D10 |------------------+
- | PD15 <-> FSMC_D1 | PE14 <-> FSMC_D11 |
- | | PE15 <-> FSMC_D12 |
- +-------------------+--------------------+
-*/
- /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
- RCC->AHB1ENR = 0x00000078;
-
- /* Connect PDx pins to FSMC Alternate function */
- GPIOD->AFR[0] = 0x00cc00cc;
- GPIOD->AFR[1] = 0xcc0ccccc;
- /* Configure PDx pins in Alternate function mode */
- GPIOD->MODER = 0xaaaa0a0a;
- /* Configure PDx pins speed to 100 MHz */
- GPIOD->OSPEEDR = 0xffff0f0f;
- /* Configure PDx pins Output type to push-pull */
- GPIOD->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PDx pins */
- GPIOD->PUPDR = 0x00000000;
-
- /* Connect PEx pins to FSMC Alternate function */
- GPIOE->AFR[0] = 0xc00cc0cc;
- GPIOE->AFR[1] = 0xcccccccc;
- /* Configure PEx pins in Alternate function mode */
- GPIOE->MODER = 0xaaaa828a;
- /* Configure PEx pins speed to 100 MHz */
- GPIOE->OSPEEDR = 0xffffc3cf;
- /* Configure PEx pins Output type to push-pull */
- GPIOE->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PEx pins */
- GPIOE->PUPDR = 0x00000000;
-
- /* Connect PFx pins to FSMC Alternate function */
- GPIOF->AFR[0] = 0x00cccccc;
- GPIOF->AFR[1] = 0xcccc0000;
- /* Configure PFx pins in Alternate function mode */
- GPIOF->MODER = 0xaa000aaa;
- /* Configure PFx pins speed to 100 MHz */
- GPIOF->OSPEEDR = 0xff000fff;
- /* Configure PFx pins Output type to push-pull */
- GPIOF->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PFx pins */
- GPIOF->PUPDR = 0x00000000;
-
- /* Connect PGx pins to FSMC Alternate function */
- GPIOG->AFR[0] = 0x00cccccc;
- GPIOG->AFR[1] = 0x000000c0;
- /* Configure PGx pins in Alternate function mode */
- GPIOG->MODER = 0x00080aaa;
- /* Configure PGx pins speed to 100 MHz */
- GPIOG->OSPEEDR = 0x000c0fff;
- /* Configure PGx pins Output type to push-pull */
- GPIOG->OTYPER = 0x00000000;
- /* No pull-up, pull-down for PGx pins */
- GPIOG->PUPDR = 0x00000000;
-
-/*-- FSMC Configuration ------------------------------------------------------*/
- /* Enable the FSMC interface clock */
- RCC->AHB3ENR = 0x00000001;
-
- /* Configure and enable Bank1_SRAM2 */
- FSMC_Bank1->BTCR[2] = 0x00001015;
- FSMC_Bank1->BTCR[3] = 0x00010603;//0x00010400;
- FSMC_Bank1E->BWTR[2] = 0x0fffffff;
-/*
- Bank1_SRAM2 is configured as follow:
-
- p.FSMC_AddressSetupTime = 3;//0;
- p.FSMC_AddressHoldTime = 0;
- p.FSMC_DataSetupTime = 6;//4;
- p.FSMC_BusTurnAroundDuration = 1;
- p.FSMC_CLKDivision = 0;
- p.FSMC_DataLatency = 0;
- p.FSMC_AccessMode = FSMC_AccessMode_A;
-
- FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
- FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
- FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM;
- FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
- FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
- FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
- FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
- FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
- FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
- FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
- FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
- FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
- FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
- FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
- FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
-*/
-
-}
-#endif /* DATA_IN_ExtSRAM */
-
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
-
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: discovery/src/system_stm32f4xx.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 21dd1e2 Starting to integrate usb branch. Optimized Makefiles
+*
+**************************************************************************************************************************************/
+
+/**
+ ******************************************************************************
+ * @file system_stm32f4xx.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 19-September-2011
+ * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
+ * This file contains the system clock configuration for STM32F4xx devices,
+ * and is generated by the clock configuration tool
+ * stm32f4xx_Clock_Configuration_V1.0.0.xls
+ *
+ * 1. This file provides two functions and one global variable to be called from
+ * user application:
+ * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
+ * and Divider factors, AHB/APBx prescalers and Flash settings),
+ * depending on the configuration made in the clock xls tool.
+ * This function is called at startup just after reset and
+ * before branch to main program. This call is made inside
+ * the "startup_stm32f4xx.s" file.
+ *
+ * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+ * by the user application to setup the SysTick
+ * timer or configure other parameters.
+ *
+ * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+ * be called whenever the core clock is changed
+ * during program execution.
+ *
+ * 2. After each device reset the HSI (16 MHz) is used as system clock source.
+ * Then SystemInit() function is called, in "startup_stm32f4xx.s" file, to
+ * configure the system clock before to branch to main program.
+ *
+ * 3. If the system clock source selected by user fails to startup, the SystemInit()
+ * function will do nothing and HSI still used as system clock source. User can
+ * add some code to deal with this issue inside the SetSysClock() function.
+ *
+ * 4. The default value of HSE crystal is set to 8 MHz, refer to "HSE_VALUE" define
+ * in "stm32f4xx.h" file. When HSE is used as system clock source, directly or
+ * through PLL, and you are using different crystal you have to adapt the HSE
+ * value to your own configuration.
+ *
+ * 5. This file configures the system clock as follows:
+ *=============================================================================
+ *=============================================================================
+ * Supported STM32F4xx device revision | Rev A
+ *-----------------------------------------------------------------------------
+ * System Clock source | PLL (HSE)
+ *-----------------------------------------------------------------------------
+ * SYSCLK(Hz) | 168000000
+ *-----------------------------------------------------------------------------
+ * HCLK(Hz) | 168000000
+ *-----------------------------------------------------------------------------
+ * AHB Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB1 Prescaler | 4
+ *-----------------------------------------------------------------------------
+ * APB2 Prescaler | 2
+ *-----------------------------------------------------------------------------
+ * HSE Frequency(Hz) | 8000000
+ *-----------------------------------------------------------------------------
+ * PLL_M | 8
+ *-----------------------------------------------------------------------------
+ * PLL_N | 336
+ *-----------------------------------------------------------------------------
+ * PLL_P | 2
+ *-----------------------------------------------------------------------------
+ * PLL_Q | 7
+ *-----------------------------------------------------------------------------
+ * PLLI2S_N | NA
+ *-----------------------------------------------------------------------------
+ * PLLI2S_R | NA
+ *-----------------------------------------------------------------------------
+ * I2S input clock | NA
+ *-----------------------------------------------------------------------------
+ * VDD(V) | 3.3
+ *-----------------------------------------------------------------------------
+ * High Performance mode | Enabled
+ *-----------------------------------------------------------------------------
+ * Flash Latency(WS) | 5
+ *-----------------------------------------------------------------------------
+ * Prefetch Buffer | OFF
+ *-----------------------------------------------------------------------------
+ * Instruction cache | ON
+ *-----------------------------------------------------------------------------
+ * Data cache | ON
+ *-----------------------------------------------------------------------------
+ * Require 48MHz for USB OTG FS, | Enabled
+ * SDIO and RNG clock |
+ *-----------------------------------------------------------------------------
+ *=============================================================================
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * © COPYRIGHT 2011 STMicroelectronics
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32f4xx_system
+ * @{
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Includes
+ * @{
+ */
+
+#include "stm32f4xx.h"
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Defines
+ * @{
+ */
+
+/*!< Uncomment the following line if you need to use external SRAM mounted
+ on STM324xG_EVAL board as data memory */
+/* #define DATA_IN_ExtSRAM */
+
+/*!< Uncomment the following line if you need to relocate your vector Table in
+ Internal SRAM. */
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+
+
+/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
+#define PLL_M 8
+#define PLL_N 336
+
+/* SYSCLK = PLL_VCO / PLL_P */
+#define PLL_P 2
+
+/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
+#define PLL_Q 7
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Variables
+ * @{
+ */
+
+uint32_t SystemCoreClock = 168000000;
+
+__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
+ * @{
+ */
+
+static void SetSysClock(void);
+#ifdef DATA_IN_ExtSRAM
+static void SystemInit_ExtMemCtl(void);
+#endif /* DATA_IN_ExtSRAM */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Setup the microcontroller system
+ * Initialize the Embedded Flash Interface, the PLL and update the
+ * SystemFrequency variable.
+ * @param None
+ * @retval None
+ */
+void SystemInit(void)
+{
+ /* Reset the RCC clock configuration to the default reset state ------------*/
+ /* Set HSION bit */
+ RCC->CR |= (uint32_t)0x00000001;
+
+ /* Reset CFGR register */
+ RCC->CFGR = 0x00000000;
+
+ /* Reset HSEON, CSSON and PLLON bits */
+ RCC->CR &= (uint32_t)0xFEF6FFFF;
+
+ /* Reset PLLCFGR register */
+ RCC->PLLCFGR = 0x24003010;
+
+ /* Reset HSEBYP bit */
+ RCC->CR &= (uint32_t)0xFFFBFFFF;
+
+ /* Disable all interrupts */
+ RCC->CIR = 0x00000000;
+
+#ifdef DATA_IN_ExtSRAM
+ SystemInit_ExtMemCtl();
+#endif /* DATA_IN_ExtSRAM */
+
+ /* Configure the System clock source, PLL Multiplier and Divider factors,
+ AHB/APBx prescalers and Flash settings ----------------------------------*/
+ SetSysClock();
+
+ /* Configure the Vector Table location add offset address ------------------*/
+#ifdef VECT_TAB_SRAM
+ SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
+#else
+ SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
+#endif
+}
+
+/**
+ * @brief Update SystemCoreClock variable according to Clock Register Values.
+ * The SystemCoreClock variable contains the core clock (HCLK), it can
+ * be used by the user application to setup the SysTick timer or configure
+ * other parameters.
+ *
+ * @note Each time the core clock (HCLK) changes, this function must be called
+ * to update SystemCoreClock variable value. Otherwise, any configuration
+ * based on this variable will be incorrect.
+ *
+ * @note - The system frequency computed by this function is not the real
+ * frequency in the chip. It is calculated based on the predefined
+ * constant and the selected clock source:
+ *
+ * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+ *
+ * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+ *
+ * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
+ * or HSI_VALUE(*) multiplied/divided by the PLL factors.
+ *
+ * (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value
+ * 16 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ *
+ * (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value
+ * 25 MHz), user has to ensure that HSE_VALUE is same as the real
+ * frequency of the crystal used. Otherwise, this function may
+ * have wrong result.
+ *
+ * - The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ *
+ * @param None
+ * @retval None
+ */
+void SystemCoreClockUpdate(void)
+{
+ uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+ switch (tmp) {
+ case 0x00: /* HSI used as system clock source */
+ SystemCoreClock = HSI_VALUE;
+ break;
+
+ case 0x04: /* HSE used as system clock source */
+ SystemCoreClock = HSE_VALUE;
+ break;
+
+ case 0x08: /* PLL used as system clock source */
+
+ /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
+ SYSCLK = PLL_VCO / PLL_P
+ */
+ pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
+ pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
+
+ if (pllsource != 0) {
+ /* HSE used as PLL clock source */
+ pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
+ } else {
+ /* HSI used as PLL clock source */
+ pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
+ }
+
+ pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> 16) + 1) * 2;
+ SystemCoreClock = pllvco / pllp;
+ break;
+
+ default:
+ SystemCoreClock = HSI_VALUE;
+ break;
+ }
+
+ /* Compute HCLK frequency --------------------------------------------------*/
+ /* Get HCLK prescaler */
+ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
+ /* HCLK frequency */
+ SystemCoreClock >>= tmp;
+}
+
+/**
+ * @brief Configures the System clock source, PLL Multiplier and Divider factors,
+ * AHB/APBx prescalers and Flash settings
+ * @Note This function should be called only once the RCC clock configuration
+ * is reset to the default reset state (done in SystemInit() function).
+ * @param None
+ * @retval None
+ */
+static void SetSysClock(void)
+{
+ /******************************************************************************/
+ /* PLL (clocked by HSE) used as System clock source */
+ /******************************************************************************/
+ __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
+
+ /* Enable HSE */
+ RCC->CR |= ((uint32_t)RCC_CR_HSEON);
+
+ /* Wait till HSE is ready and if Time out is reached exit */
+ do {
+ HSEStatus = RCC->CR & RCC_CR_HSERDY;
+ StartUpCounter++;
+ } while ((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
+
+ if ((RCC->CR & RCC_CR_HSERDY) != RESET) {
+ HSEStatus = (uint32_t)0x01;
+ } else {
+ HSEStatus = (uint32_t)0x00;
+ }
+
+ if (HSEStatus == (uint32_t)0x01) {
+ /* Enable high performance mode, System frequency up to 168 MHz */
+ RCC->APB1ENR |= RCC_APB1ENR_PWREN;
+ PWR->CR |= PWR_CR_PMODE;
+
+ /* HCLK = SYSCLK / 1*/
+ RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
+
+ /* PCLK2 = HCLK / 2*/
+ RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
+
+ /* PCLK1 = HCLK / 4*/
+ RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
+
+ /* Configure the main PLL */
+ RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) - 1) << 16) |
+ (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
+
+ /* Enable the main PLL */
+ RCC->CR |= RCC_CR_PLLON;
+
+ /* Wait till the main PLL is ready */
+ while ((RCC->CR & RCC_CR_PLLRDY) == 0) {
+ }
+
+ /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
+ FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS;
+
+ /* Select the main PLL as system clock source */
+ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+ RCC->CFGR |= RCC_CFGR_SW_PLL;
+
+ /* Wait till the main PLL is used as system clock source */
+ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
+
+ {
+ }
+ } else {
+ /* If HSE fails to start-up, the application will have wrong clock
+ configuration. User can add here some code to deal with this error */
+ }
+
+}
+
+/**
+ * @brief Setup the external memory controller. Called in startup_stm32f4xx.s
+ * before jump to __main
+ * @param None
+ * @retval None
+ */
+#ifdef DATA_IN_ExtSRAM
+/**
+ * @brief Setup the external memory controller.
+ * Called in startup_stm32f4xx.s before jump to main.
+ * This function configures the external SRAM mounted on STM324xG_EVAL board
+ * This SRAM will be used as program data memory (including heap and stack).
+ * @param None
+ * @retval None
+ */
+void SystemInit_ExtMemCtl(void)
+{
+ /*-- GPIOs Configuration -----------------------------------------------------*/
+ /*
+ +-------------------+--------------------+------------------+------------------+
+ + SRAM pins assignment +
+ +-------------------+--------------------+------------------+------------------+
+ | PD0 <-> FSMC_D2 | PE0 <-> FSMC_NBL0 | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 |
+ | PD1 <-> FSMC_D3 | PE1 <-> FSMC_NBL1 | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 |
+ | PD4 <-> FSMC_NOE | PE3 <-> FSMC_A19 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 |
+ | PD5 <-> FSMC_NWE | PE4 <-> FSMC_A20 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 |
+ | PD8 <-> FSMC_D13 | PE7 <-> FSMC_D4 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 |
+ | PD9 <-> FSMC_D14 | PE8 <-> FSMC_D5 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 |
+ | PD10 <-> FSMC_D15 | PE9 <-> FSMC_D6 | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 |
+ | PD11 <-> FSMC_A16 | PE10 <-> FSMC_D7 | PF13 <-> FSMC_A7 |------------------+
+ | PD12 <-> FSMC_A17 | PE11 <-> FSMC_D8 | PF14 <-> FSMC_A8 |
+ | PD13 <-> FSMC_A18 | PE12 <-> FSMC_D9 | PF15 <-> FSMC_A9 |
+ | PD14 <-> FSMC_D0 | PE13 <-> FSMC_D10 |------------------+
+ | PD15 <-> FSMC_D1 | PE14 <-> FSMC_D11 |
+ | | PE15 <-> FSMC_D12 |
+ +-------------------+--------------------+
+ */
+ /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
+ RCC->AHB1ENR = 0x00000078;
+
+ /* Connect PDx pins to FSMC Alternate function */
+ GPIOD->AFR[0] = 0x00cc00cc;
+ GPIOD->AFR[1] = 0xcc0ccccc;
+ /* Configure PDx pins in Alternate function mode */
+ GPIOD->MODER = 0xaaaa0a0a;
+ /* Configure PDx pins speed to 100 MHz */
+ GPIOD->OSPEEDR = 0xffff0f0f;
+ /* Configure PDx pins Output type to push-pull */
+ GPIOD->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PDx pins */
+ GPIOD->PUPDR = 0x00000000;
+
+ /* Connect PEx pins to FSMC Alternate function */
+ GPIOE->AFR[0] = 0xc00cc0cc;
+ GPIOE->AFR[1] = 0xcccccccc;
+ /* Configure PEx pins in Alternate function mode */
+ GPIOE->MODER = 0xaaaa828a;
+ /* Configure PEx pins speed to 100 MHz */
+ GPIOE->OSPEEDR = 0xffffc3cf;
+ /* Configure PEx pins Output type to push-pull */
+ GPIOE->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PEx pins */
+ GPIOE->PUPDR = 0x00000000;
+
+ /* Connect PFx pins to FSMC Alternate function */
+ GPIOF->AFR[0] = 0x00cccccc;
+ GPIOF->AFR[1] = 0xcccc0000;
+ /* Configure PFx pins in Alternate function mode */
+ GPIOF->MODER = 0xaa000aaa;
+ /* Configure PFx pins speed to 100 MHz */
+ GPIOF->OSPEEDR = 0xff000fff;
+ /* Configure PFx pins Output type to push-pull */
+ GPIOF->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PFx pins */
+ GPIOF->PUPDR = 0x00000000;
+
+ /* Connect PGx pins to FSMC Alternate function */
+ GPIOG->AFR[0] = 0x00cccccc;
+ GPIOG->AFR[1] = 0x000000c0;
+ /* Configure PGx pins in Alternate function mode */
+ GPIOG->MODER = 0x00080aaa;
+ /* Configure PGx pins speed to 100 MHz */
+ GPIOG->OSPEEDR = 0x000c0fff;
+ /* Configure PGx pins Output type to push-pull */
+ GPIOG->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PGx pins */
+ GPIOG->PUPDR = 0x00000000;
+
+ /*-- FSMC Configuration ------------------------------------------------------*/
+ /* Enable the FSMC interface clock */
+ RCC->AHB3ENR = 0x00000001;
+
+ /* Configure and enable Bank1_SRAM2 */
+ FSMC_Bank1->BTCR[2] = 0x00001015;
+ FSMC_Bank1->BTCR[3] = 0x00010603;//0x00010400;
+ FSMC_Bank1E->BWTR[2] = 0x0fffffff;
+ /*
+ Bank1_SRAM2 is configured as follow:
+
+ p.FSMC_AddressSetupTime = 3;//0;
+ p.FSMC_AddressHoldTime = 0;
+ p.FSMC_DataSetupTime = 6;//4;
+ p.FSMC_BusTurnAroundDuration = 1;
+ p.FSMC_CLKDivision = 0;
+ p.FSMC_DataLatency = 0;
+ p.FSMC_AccessMode = FSMC_AccessMode_A;
+
+ FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
+ FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM;
+ FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
+ FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
+ FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
+ FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
+ FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
+ FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
+ */
+
+}
+#endif /* DATA_IN_ExtSRAM */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/discovery/src/usb_bsp.c b/discovery/src/usb_bsp.c
index 6d4ed62..bcd8ed8 100644
--- a/discovery/src/usb_bsp.c
+++ b/discovery/src/usb_bsp.c
@@ -1,460 +1,468 @@
-
-/* Includes ------------------------------------------------------------------*/
-#include "usb_bsp.h"
-#include "stm32f4_discovery.h"
-
-#define USE_ACCURATE_TIME
-#define TIM_MSEC_DELAY 0x01
-#define TIM_USEC_DELAY 0x02
-#define HOST_OVRCURR_PORT GPIOD
-#define HOST_OVRCURR_LINE GPIO_Pin_5
-#define HOST_OVRCURR_PORT_SOURCE GPIO_PortSourceGPIOD
-#define HOST_OVRCURR_PIN_SOURCE GPIO_PinSourceD
-#define HOST_OVRCURR_PORT_RCC RCC_APB2Periph_GPIOD
-#define HOST_OVRCURR_EXTI_LINE EXTI_Line5
-#define HOST_OVRCURR_IRQn EXTI9_5_IRQn
-
-
-#define HOST_POWERSW_PORT_RCC RCC_AHB1Periph_GPIOC
-#define HOST_POWERSW_PORT GPIOC
-#define HOST_POWERSW_VBUS GPIO_Pin_0
-
-/* Private macros ------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-ErrorStatus HSEStartUpStatus;
-#ifdef USE_ACCURATE_TIME
- __IO uint32_t BSP_delay = 0;
-#endif
-
-/* Private function prototypes -----------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-#ifdef USE_ACCURATE_TIME
- static void BSP_SetTime(uint8_t Unit);
- static void BSP_Delay(uint32_t nTime, uint8_t Unit);
- static void USB_OTG_BSP_TimeInit ( void );
-#endif
-
-/**
- * @brief BSP_Init
- * board user initializations
- * @param None
- * @retval None
- */
-void BSP_Init(void)
-{
- /* Configure PA0 pin: User Key pin */
-}
-
-
-/**
- * @brief USB_OTG_BSP_Init
- * Initilizes BSP configurations
- * @param None
- * @retval None
- */
-void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev)
-{
- /* Note: On STM32F4-Discovery board only USB OTG FS core is supported. */
-
- GPIO_InitTypeDef GPIO_InitStructure;
- #ifdef USE_USB_OTG_FS
-
- RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA , ENABLE);
-
- /* Configure SOF VBUS ID DM DP Pins */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 |
- GPIO_Pin_11 |
- GPIO_Pin_12;
-
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_OTG1_FS) ;
- GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_OTG1_FS) ;
- GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_OTG1_FS) ;
-
- /* this for ID line debug */
-
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_OTG1_FS) ;
-
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
- RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, ENABLE) ;
- #else // USE_USB_OTG_HS
-
- #ifdef USE_ULPI_PHY // ULPI
- RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |
- RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOH |
- RCC_AHB1Periph_GPIOI, ENABLE);
-
-
- GPIO_PinAFConfig(GPIOA,GPIO_PinSource3, GPIO_AF_OTG2_HS) ; // D0
- GPIO_PinAFConfig(GPIOA,GPIO_PinSource5, GPIO_AF_OTG2_HS) ; // CLK
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource0, GPIO_AF_OTG2_HS) ; // D1
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource1, GPIO_AF_OTG2_HS) ; // D2
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource5, GPIO_AF_OTG2_HS) ; // D7
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_OTG2_HS) ; // D3
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_OTG2_HS) ; // D4
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_OTG2_HS) ; // D5
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_OTG2_HS) ; // D6
- GPIO_PinAFConfig(GPIOH,GPIO_PinSource4, GPIO_AF_OTG2_HS) ; // NXT
- GPIO_PinAFConfig(GPIOI,GPIO_PinSource11,GPIO_AF_OTG2_HS) ; // DIR
- GPIO_PinAFConfig(GPIOC,GPIO_PinSource0, GPIO_AF_OTG2_HS) ; // STP
-
- // CLK
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- // D0
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 ;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
-
-
- // D1 D2 D3 D4 D5 D6 D7
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 |
- GPIO_Pin_5 | GPIO_Pin_10 |
- GPIO_Pin_11| GPIO_Pin_12 |
- GPIO_Pin_13 ;
-
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
-
- // STP
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
-
- //NXT
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_Init(GPIOH, &GPIO_InitStructure);
-
-
- //DIR
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_Init(GPIOI, &GPIO_InitStructure);
-
-
- RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS |
- RCC_AHB1Periph_OTG_HS_ULPI, ENABLE) ;
-
- #else
-
- #ifdef USE_I2C_PHY
- RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB , ENABLE);
- /* Configure RESET INTN SCL SDA (Phy/I2C) Pins */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |
- GPIO_Pin_1 |
- GPIO_Pin_10 |
- GPIO_Pin_11;
-
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource0,GPIO_AF_OTG2_FS) ;
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource1,GPIO_AF_OTG2_FS) ;
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_OTG2_FS) ;
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_OTG2_FS);
- RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS, ENABLE) ;
-
- #else
-
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB , ENABLE);
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 |
- GPIO_Pin_13 |
- GPIO_Pin_14 |
- GPIO_Pin_15;
-
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource12, GPIO_AF_OTG2_FS) ;
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_OTG2_FS) ;
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_OTG2_FS) ;
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_OTG2_FS) ;
- RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS, ENABLE) ;
- #endif
- #endif
- #endif //USB_OTG_HS
-
- /* Intialize Timer for delay function */
- USB_OTG_BSP_TimeInit();
-}
-
-/**
- * @brief USB_OTG_BSP_EnableInterrupt
- * Configures USB Global interrupt
- * @param None
- * @retval None
- */
-void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE *pdev)
-{
-
- NVIC_InitTypeDef NVIC_InitStructure;
- /* Enable USB Interrupt */
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
-
- NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
-
- /* Enable the Overcurrent Interrupt */
- NVIC_InitStructure.NVIC_IRQChannel = HOST_OVRCURR_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-
- NVIC_Init(&NVIC_InitStructure);
-}
-
-/**
- * @brief BSP_Drive_VBUS
- * Drives the Vbus signal through IO
- * @param state : VBUS states
- * @retval None
- */
-void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev, uint8_t state)
-{
- /*
- On-chip 5 V VBUS generation is not supported. For this reason, a charge pump
- or, if 5 V are available on the application board, a basic power switch, must
- be added externally to drive the 5 V VBUS line. The external charge pump can
- be driven by any GPIO output. When the application decides to power on VBUS
- using the chosen GPIO, it must also set the port power bit in the host port
- control and status register (PPWR bit in OTG_FS_HPRT).
-
- Bit 12 PPWR: Port power
- The application uses this field to control power to this port, and the core
- clears this bit on an overcurrent condition.
- */
- if (0 == state)
- {
- /* DISABLE is needed on output of the Power Switch */
- GPIO_SetBits(HOST_POWERSW_PORT, HOST_POWERSW_VBUS);
- }
- else
- {
- /*ENABLE the Power Switch by driving the Enable LOW */
- GPIO_ResetBits(HOST_POWERSW_PORT, HOST_POWERSW_VBUS);
- }
-}
-
-/**
- * @brief USB_OTG_BSP_ConfigVBUS
- * Configures the IO for the Vbus and OverCurrent
- * @param None
- * @retval None
- */
-void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev)
-{
- GPIO_InitTypeDef GPIO_InitStructure;
-
-
- RCC_AHB1PeriphClockCmd(HOST_POWERSW_PORT_RCC, ENABLE);
-
-
- /* Configure Power Switch Vbus Pin */
- GPIO_InitStructure.GPIO_Pin = HOST_POWERSW_VBUS;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
-
- GPIO_Init(HOST_POWERSW_PORT, &GPIO_InitStructure);
-
- /* By Default, DISABLE is needed on output of the Power Switch */
- GPIO_SetBits(HOST_POWERSW_PORT, HOST_POWERSW_VBUS);
-
- USB_OTG_BSP_mDelay(200); /* Delay is need for stabilising the Vbus Low
- in Reset Condition, when Vbus=1 and Reset-button is pressed by user */
-
-}
-
-/**
- * @brief USB_OTG_BSP_TimeInit
- * Initializes delay unit using Timer2
- * @param None
- * @retval None
- */
-static void USB_OTG_BSP_TimeInit (void)
-{
-#ifdef USE_ACCURATE_TIME
- NVIC_InitTypeDef NVIC_InitStructure;
-
- /* Set the Vector Table base address at 0x08000000 */
-// NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x00);
-
- /* Configure the Priority Group to 2 bits */
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
-
- /* Enable the TIM2 gloabal Interrupt */
- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-
- NVIC_Init(&NVIC_InitStructure);
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
-#endif
-}
-
-/**
- * @brief USB_OTG_BSP_uDelay
- * This function provides delay time in micro sec
- * @param usec : Value of delay required in micro sec
- * @retval None
- */
-void USB_OTG_BSP_uDelay (const uint32_t usec)
-{
-
-#ifdef USE_ACCURATE_TIME
- BSP_Delay(usec, TIM_USEC_DELAY);
-#else
- __IO uint32_t count = 0;
- const uint32_t utime = (120 * usec / 7);
- do
- {
- if ( ++count > utime )
- {
- return ;
- }
- }
- while (1);
-#endif
-
-}
-
-/**
- * @brief USB_OTG_BSP_mDelay
- * This function provides delay time in milli sec
- * @param msec : Value of delay required in milli sec
- * @retval None
- */
-void USB_OTG_BSP_mDelay (const uint32_t msec)
-{
-#ifdef USE_ACCURATE_TIME
- BSP_Delay(msec, TIM_MSEC_DELAY);
-#else
- USB_OTG_BSP_uDelay(msec * 1000);
-#endif
-
-}
-
-/**
- * @brief USB_OTG_BSP_TimerIRQ
- * Time base IRQ
- * @param None
- * @retval None
- */
-void USB_OTG_BSP_TimerIRQ (void)
-{
-#ifdef USE_ACCURATE_TIME
- if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
- {
- TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
- if (BSP_delay > 0x00)
- {
- BSP_delay--;
- }
- else
- {
- TIM_Cmd(TIM2, DISABLE);
- }
- }
-#endif
-}
-
-#ifdef USE_ACCURATE_TIME
-
-/**
- * @brief BSP_Delay
- * Delay routine based on TIM2
- * @param nTime : Delay Time
- * @param unit : Delay Time unit : mili sec / micro sec
- * @retval None
- */
-static void BSP_Delay(uint32_t nTime, uint8_t unit)
-{
-
- BSP_delay = nTime;
- BSP_SetTime(unit);
- while (BSP_delay != 0);
- TIM_Cmd(TIM2, DISABLE);
-}
-
-/**
- * @brief BSP_SetTime
- * Configures TIM2 for delay routine based on TIM2
- * @param unit : msec /usec
- * @retval None
- */
-static void BSP_SetTime(uint8_t unit)
-{
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
-
- TIM_Cmd(TIM2, DISABLE);
- TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);
-
-
- if (unit == TIM_USEC_DELAY)
- {
- TIM_TimeBaseStructure.TIM_Period = 11;
- }
- else if (unit == TIM_MSEC_DELAY)
- {
- TIM_TimeBaseStructure.TIM_Period = 11999;
- }
- TIM_TimeBaseStructure.TIM_Prescaler = 5;
- TIM_TimeBaseStructure.TIM_ClockDivision = 0;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
-
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
- TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
-
- TIM_ARRPreloadConfig(TIM2, ENABLE);
-
- /* TIM IT enable */
- TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
-
- /* TIM2 enable counter */
- TIM_Cmd(TIM2, ENABLE);
-}
-
-#endif
-
-/**
-* @}
-*/
-
-
-/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: discovery/src/usb_bsp.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 21dd1e2 Starting to integrate usb branch. Optimized Makefiles
+*
+**************************************************************************************************************************************/
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_bsp.h"
+#include "stm32f4_discovery.h"
+
+#define USE_ACCURATE_TIME
+#define TIM_MSEC_DELAY 0x01
+#define TIM_USEC_DELAY 0x02
+#define HOST_OVRCURR_PORT GPIOD
+#define HOST_OVRCURR_LINE GPIO_Pin_5
+#define HOST_OVRCURR_PORT_SOURCE GPIO_PortSourceGPIOD
+#define HOST_OVRCURR_PIN_SOURCE GPIO_PinSourceD
+#define HOST_OVRCURR_PORT_RCC RCC_APB2Periph_GPIOD
+#define HOST_OVRCURR_EXTI_LINE EXTI_Line5
+#define HOST_OVRCURR_IRQn EXTI9_5_IRQn
+
+
+#define HOST_POWERSW_PORT_RCC RCC_AHB1Periph_GPIOC
+#define HOST_POWERSW_PORT GPIOC
+#define HOST_POWERSW_VBUS GPIO_Pin_0
+
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+ErrorStatus HSEStartUpStatus;
+#ifdef USE_ACCURATE_TIME
+__IO uint32_t BSP_delay = 0;
+#endif
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+#ifdef USE_ACCURATE_TIME
+static void BSP_SetTime(uint8_t Unit);
+static void BSP_Delay(uint32_t nTime, uint8_t Unit);
+static void USB_OTG_BSP_TimeInit(void);
+#endif
+
+/**
+ * @brief BSP_Init
+ * board user initializations
+ * @param None
+ * @retval None
+ */
+void BSP_Init(void)
+{
+ /* Configure PA0 pin: User Key pin */
+}
+
+
+/**
+ * @brief USB_OTG_BSP_Init
+ * Initilizes BSP configurations
+ * @param None
+ * @retval None
+ */
+void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE* pdev)
+{
+ /* Note: On STM32F4-Discovery board only USB OTG FS core is supported. */
+
+ GPIO_InitTypeDef GPIO_InitStructure;
+#ifdef USE_USB_OTG_FS
+
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE);
+
+ /* Configure SOF VBUS ID DM DP Pins */
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 |
+ GPIO_Pin_11 |
+ GPIO_Pin_12;
+
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_OTG1_FS) ;
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_OTG1_FS) ;
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_OTG1_FS) ;
+
+ /* this for ID line debug */
+
+
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_OTG1_FS) ;
+
+
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
+ RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, ENABLE) ;
+#else // USE_USB_OTG_HS
+
+#ifdef USE_ULPI_PHY // ULPI
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |
+ RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOH |
+ RCC_AHB1Periph_GPIOI, ENABLE);
+
+
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_OTG2_HS) ; // D0
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_OTG2_HS) ; // CLK
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_OTG2_HS) ; // D1
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_OTG2_HS) ; // D2
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_OTG2_HS) ; // D7
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_OTG2_HS) ; // D3
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_OTG2_HS) ; // D4
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_OTG2_HS) ; // D5
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_OTG2_HS) ; // D6
+ GPIO_PinAFConfig(GPIOH, GPIO_PinSource4, GPIO_AF_OTG2_HS) ; // NXT
+ GPIO_PinAFConfig(GPIOI, GPIO_PinSource11, GPIO_AF_OTG2_HS) ; // DIR
+ GPIO_PinAFConfig(GPIOC, GPIO_PinSource0, GPIO_AF_OTG2_HS) ; // STP
+
+ // CLK
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+ // D0
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 ;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+
+
+ // D1 D2 D3 D4 D5 D6 D7
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 |
+ GPIO_Pin_5 | GPIO_Pin_10 |
+ GPIO_Pin_11 | GPIO_Pin_12 |
+ GPIO_Pin_13 ;
+
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+
+ // STP
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_Init(GPIOC, &GPIO_InitStructure);
+
+ //NXT
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_Init(GPIOH, &GPIO_InitStructure);
+
+
+ //DIR
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_Init(GPIOI, &GPIO_InitStructure);
+
+
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_OTG_HS |
+ RCC_AHB1Periph_OTG_HS_ULPI, ENABLE) ;
+
+#else
+
+#ifdef USE_I2C_PHY
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB , ENABLE);
+ /* Configure RESET INTN SCL SDA (Phy/I2C) Pins */
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |
+ GPIO_Pin_1 |
+ GPIO_Pin_10 |
+ GPIO_Pin_11;
+
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_OTG2_FS) ;
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_OTG2_FS) ;
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_OTG2_FS) ;
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_OTG2_FS);
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_OTG_HS, ENABLE) ;
+
+#else
+
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB , ENABLE);
+
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 |
+ GPIO_Pin_13 |
+ GPIO_Pin_14 |
+ GPIO_Pin_15;
+
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_OTG2_FS) ;
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_OTG2_FS) ;
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_OTG2_FS) ;
+ GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_OTG2_FS) ;
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_OTG_HS, ENABLE) ;
+#endif
+#endif
+#endif //USB_OTG_HS
+
+ /* Intialize Timer for delay function */
+ USB_OTG_BSP_TimeInit();
+}
+
+/**
+ * @brief USB_OTG_BSP_EnableInterrupt
+ * Configures USB Global interrupt
+ * @param None
+ * @retval None
+ */
+void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE* pdev)
+{
+
+ NVIC_InitTypeDef NVIC_InitStructure;
+ /* Enable USB Interrupt */
+ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
+
+ NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStructure);
+
+ /* Enable the Overcurrent Interrupt */
+ NVIC_InitStructure.NVIC_IRQChannel = HOST_OVRCURR_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+
+ NVIC_Init(&NVIC_InitStructure);
+}
+
+/**
+ * @brief BSP_Drive_VBUS
+ * Drives the Vbus signal through IO
+ * @param state : VBUS states
+ * @retval None
+ */
+void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE* pdev, uint8_t state)
+{
+ /*
+ On-chip 5 V VBUS generation is not supported. For this reason, a charge pump
+ or, if 5 V are available on the application board, a basic power switch, must
+ be added externally to drive the 5 V VBUS line. The external charge pump can
+ be driven by any GPIO output. When the application decides to power on VBUS
+ using the chosen GPIO, it must also set the port power bit in the host port
+ control and status register (PPWR bit in OTG_FS_HPRT).
+
+ Bit 12 PPWR: Port power
+ The application uses this field to control power to this port, and the core
+ clears this bit on an overcurrent condition.
+ */
+ if (0 == state) {
+ /* DISABLE is needed on output of the Power Switch */
+ GPIO_SetBits(HOST_POWERSW_PORT, HOST_POWERSW_VBUS);
+ } else {
+ /*ENABLE the Power Switch by driving the Enable LOW */
+ GPIO_ResetBits(HOST_POWERSW_PORT, HOST_POWERSW_VBUS);
+ }
+}
+
+/**
+ * @brief USB_OTG_BSP_ConfigVBUS
+ * Configures the IO for the Vbus and OverCurrent
+ * @param None
+ * @retval None
+ */
+void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE* pdev)
+{
+ GPIO_InitTypeDef GPIO_InitStructure;
+
+
+ RCC_AHB1PeriphClockCmd(HOST_POWERSW_PORT_RCC, ENABLE);
+
+
+ /* Configure Power Switch Vbus Pin */
+ GPIO_InitStructure.GPIO_Pin = HOST_POWERSW_VBUS;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+
+ GPIO_Init(HOST_POWERSW_PORT, &GPIO_InitStructure);
+
+ /* By Default, DISABLE is needed on output of the Power Switch */
+ GPIO_SetBits(HOST_POWERSW_PORT, HOST_POWERSW_VBUS);
+
+ USB_OTG_BSP_mDelay(200); /* Delay is need for stabilising the Vbus Low
+ in Reset Condition, when Vbus=1 and Reset-button is pressed by user */
+
+}
+
+/**
+ * @brief USB_OTG_BSP_TimeInit
+ * Initializes delay unit using Timer2
+ * @param None
+ * @retval None
+ */
+static void USB_OTG_BSP_TimeInit(void)
+{
+#ifdef USE_ACCURATE_TIME
+ NVIC_InitTypeDef NVIC_InitStructure;
+
+ /* Set the Vector Table base address at 0x08000000 */
+// NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x00);
+
+ /* Configure the Priority Group to 2 bits */
+ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
+
+ /* Enable the TIM2 gloabal Interrupt */
+ NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+
+ NVIC_Init(&NVIC_InitStructure);
+
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
+#endif
+}
+
+/**
+ * @brief USB_OTG_BSP_uDelay
+ * This function provides delay time in micro sec
+ * @param usec : Value of delay required in micro sec
+ * @retval None
+ */
+void USB_OTG_BSP_uDelay(const uint32_t usec)
+{
+
+#ifdef USE_ACCURATE_TIME
+ BSP_Delay(usec, TIM_USEC_DELAY);
+#else
+ __IO uint32_t count = 0;
+ const uint32_t utime = (120 * usec / 7);
+
+ do {
+ if (++count > utime) {
+ return ;
+ }
+ } while (1);
+
+#endif
+
+}
+
+/**
+ * @brief USB_OTG_BSP_mDelay
+ * This function provides delay time in milli sec
+ * @param msec : Value of delay required in milli sec
+ * @retval None
+ */
+void USB_OTG_BSP_mDelay(const uint32_t msec)
+{
+#ifdef USE_ACCURATE_TIME
+ BSP_Delay(msec, TIM_MSEC_DELAY);
+#else
+ USB_OTG_BSP_uDelay(msec * 1000);
+#endif
+
+}
+
+/**
+ * @brief USB_OTG_BSP_TimerIRQ
+ * Time base IRQ
+ * @param None
+ * @retval None
+ */
+void USB_OTG_BSP_TimerIRQ(void)
+{
+#ifdef USE_ACCURATE_TIME
+
+ if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
+ TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
+
+ if (BSP_delay > 0x00) {
+ BSP_delay--;
+ } else {
+ TIM_Cmd(TIM2, DISABLE);
+ }
+ }
+
+#endif
+}
+
+#ifdef USE_ACCURATE_TIME
+
+/**
+ * @brief BSP_Delay
+ * Delay routine based on TIM2
+ * @param nTime : Delay Time
+ * @param unit : Delay Time unit : mili sec / micro sec
+ * @retval None
+ */
+static void BSP_Delay(uint32_t nTime, uint8_t unit)
+{
+
+ BSP_delay = nTime;
+ BSP_SetTime(unit);
+
+ while (BSP_delay != 0);
+
+ TIM_Cmd(TIM2, DISABLE);
+}
+
+/**
+ * @brief BSP_SetTime
+ * Configures TIM2 for delay routine based on TIM2
+ * @param unit : msec /usec
+ * @retval None
+ */
+static void BSP_SetTime(uint8_t unit)
+{
+ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
+
+ TIM_Cmd(TIM2, DISABLE);
+ TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);
+
+
+ if (unit == TIM_USEC_DELAY) {
+ TIM_TimeBaseStructure.TIM_Period = 11;
+ } else if (unit == TIM_MSEC_DELAY) {
+ TIM_TimeBaseStructure.TIM_Period = 11999;
+ }
+
+ TIM_TimeBaseStructure.TIM_Prescaler = 5;
+ TIM_TimeBaseStructure.TIM_ClockDivision = 0;
+ TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
+
+ TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
+ TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
+
+ TIM_ARRPreloadConfig(TIM2, ENABLE);
+
+ /* TIM IT enable */
+ TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
+
+ /* TIM2 enable counter */
+ TIM_Cmd(TIM2, ENABLE);
+}
+
+#endif
+
+/**
+* @}
+*/
+
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/discovery/src/usbh_msc_core.c b/discovery/src/usbh_msc_core.c
index 28d99e6..2a3cda3 100644
--- a/discovery/src/usbh_msc_core.c
+++ b/discovery/src/usbh_msc_core.c
@@ -1,250 +1,276 @@
-
-#include "usbh_msc_core.h"
-#include "usbh_core.h"
-
-
-static USBH_Status USBH_MSC_InterfaceInit (USB_OTG_CORE_HANDLE *pdev ,
- void *phost);
-
-static void USBH_MSC_InterfaceDeInit (USB_OTG_CORE_HANDLE *pdev ,
- void *phost);
-
-static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev ,
- void *phost);
-
-static USBH_Status USBH_MSC_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
- void *phost);
-
-
-extern USB_OTG_CORE_HANDLE USB_OTG_Core;
-extern USBH_HOST USB_Host;
-
-
-
-USBH_Class_cb_TypeDef USBH_MSC_cb =
-{
- USBH_MSC_InterfaceInit,
- USBH_MSC_InterfaceDeInit,
- USBH_MSC_ClassRequest,
- USBH_MSC_Handle,
-};
-
-
-typedef struct
-{
- uint8_t hc_num_in;
- uint8_t hc_num_out;
- uint8_t MSBulkOutEp;
- uint8_t MSBulkInEp;
- uint16_t MSBulkInEpSize;
- uint16_t MSBulkOutEpSize;
-}
-MSC_Machine_TypeDef;
-MSC_Machine_TypeDef MSC_Machine;
-
-
-static USBH_Status USBH_MSC_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev,
- void *phost)
-{
- USBH_HOST *pphost = phost;
-
-
-
- if((pphost->device_prop.Itf_Desc[1].bInterfaceClass == 255) &&
- (pphost->device_prop.Itf_Desc[1].bInterfaceProtocol == 0) &&
- (pphost->device_prop.Itf_Desc[1].bInterfaceSubClass == 1))
- {
- if(pphost->device_prop.Ep_Desc[0][0].bEndpointAddress & 0x80)
- {
- MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
- MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize;
- }
- else
- {
- MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
- MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize;
- }
-
- if(pphost->device_prop.Ep_Desc[0][1].bEndpointAddress & 0x80)
- {
- MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress);
- MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize;
- }
- else
- {
- MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress);
- MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize;
- }
-
- MSC_Machine.hc_num_out = USBH_Alloc_Channel(pdev,MSC_Machine.MSBulkOutEp);
- MSC_Machine.hc_num_in = USBH_Alloc_Channel(pdev,MSC_Machine.MSBulkInEp);
-
- USBH_Open_Channel (pdev,
- MSC_Machine.hc_num_out,
- pphost->device_prop.address,
- pphost->device_prop.speed,
- EP_TYPE_BULK,
- MSC_Machine.MSBulkOutEpSize);
-
- USBH_Open_Channel (pdev,
- MSC_Machine.hc_num_in,
- pphost->device_prop.address,
- pphost->device_prop.speed,
- EP_TYPE_BULK,
- MSC_Machine.MSBulkInEpSize);
-
- }
-
- else
- {
- pphost->usr_cb->USBH_USR_DeviceNotSupported();
- }
-
- return USBH_OK ;
-
-}
-
-void USBH_MSC_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev,
- void *phost)
-{
- if ( MSC_Machine.hc_num_out)
- {
- USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_out);
- USBH_Free_Channel (pdev, MSC_Machine.hc_num_out);
- MSC_Machine.hc_num_out = 0;
- }
-
- if ( MSC_Machine.hc_num_in)
- {
- USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_in);
- USBH_Free_Channel (pdev, MSC_Machine.hc_num_in);
- MSC_Machine.hc_num_in = 0;
- }
-}
-
-static USBH_Status USBH_MSC_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
- void *phost)
-{
-
- USBH_Status status = USBH_OK ;
- return status;
-}
-
-static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev ,
- void *phost)
-{
- USBH_HOST *pphost = phost;
-
- USBH_Status status = USBH_BUSY;
-
- if(HCD_IsDeviceConnected(pdev))
- {
- int appliStatus = pphost->usr_cb->USBH_USR_MSC_Application();
- if(appliStatus != 0)
- {
- status = USBH_APPLY_DEINIT;
- }
- }
- return status;
-
-}
-
-
-volatile uint32_t cnt;
-volatile uint32_t cnt_int;
-void USBH_LL_systick() {
- cnt++;
- cnt_int++;
-}
-
-
-void USBH_LL_setTimer() {
- cnt=0;
-}
-
-uint32_t USBH_LL_getTimer() {
- return cnt;
-}
-
-
-int USBH_LL_open() {
- int timeoutDetect=100;
- int timeoutStartup=3000;
- cnt_int=0; //reset timer
-
- while(USB_Host.gState!=HOST_CLASS && cnt_int < timeoutDetect) {
- USBH_Process(&USB_OTG_Core, &USB_Host);
- }
-
- if(USB_Host.gState!=HOST_CLASS) {
- return -5; // = LIBUSB_ERROR_NOT_FOUND
- }
-
-
- cnt_int=0;
- while(cnt_int0 && cnt_int>=timeoutMs) {
- STM_EVAL_LEDOn(LED3);
- return -7; //timeout (error code like with libusb)
-
- }
- return -1;
- }
- return len;
-}
-
-int USBH_LL_receive(uint8_t *data, uint32_t len, uint16_t timeoutMs) {
-
- USB_OTG_CORE_HANDLE *pdev = &USB_OTG_Core;
-
- if(!HCD_IsDeviceConnected(pdev)) return -1;
-
- USBH_BulkReceiveData (pdev,
- data,
- len ,
- MSC_Machine.hc_num_in);
-
- URB_STATE state;
- cnt_int=0; //reset timer
- if(timeoutMs==0) timeoutMs=1000; //Force 1s timeout (testwise)
-
- while((state=HCD_GetURB_State(pdev , MSC_Machine.hc_num_in)) == URB_IDLE &&
- (timeoutMs==0 || cnt_int < timeoutMs));
-
- if(state!=URB_DONE) {
- if(timeoutMs>0 && cnt_int>=timeoutMs) {
- STM_EVAL_LEDOn(LED3);
- return -7; //timeout (error code like with libusb)
- }
- return -1;
- }
- return len;
-}
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: discovery/src/usbh_msc_core.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 21dd1e2 Starting to integrate usb branch. Optimized Makefiles
+* 2015-04-25 timolang@gmail.com 416883c Pixy&Usb work with the new folder structure now.
+* 2015-04-25 timolang@gmail.com 3d1e4b2 Simplified code a bit. Emulator does not work stable when replugging pixy.
+*
+**************************************************************************************************************************************/
+
+
+#include "usbh_msc_core.h"
+#include "usbh_core.h"
+
+
+static USBH_Status USBH_MSC_InterfaceInit(USB_OTG_CORE_HANDLE* pdev ,
+ void* phost);
+
+static void USBH_MSC_InterfaceDeInit(USB_OTG_CORE_HANDLE* pdev ,
+ void* phost);
+
+static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE* pdev ,
+ void* phost);
+
+static USBH_Status USBH_MSC_ClassRequest(USB_OTG_CORE_HANDLE* pdev ,
+ void* phost);
+
+
+extern USB_OTG_CORE_HANDLE USB_OTG_Core;
+extern USBH_HOST USB_Host;
+
+
+
+USBH_Class_cb_TypeDef USBH_MSC_cb = {
+ USBH_MSC_InterfaceInit,
+ USBH_MSC_InterfaceDeInit,
+ USBH_MSC_ClassRequest,
+ USBH_MSC_Handle,
+};
+
+
+typedef struct {
+ uint8_t hc_num_in;
+ uint8_t hc_num_out;
+ uint8_t MSBulkOutEp;
+ uint8_t MSBulkInEp;
+ uint16_t MSBulkInEpSize;
+ uint16_t MSBulkOutEpSize;
+}
+MSC_Machine_TypeDef;
+MSC_Machine_TypeDef MSC_Machine;
+
+
+static USBH_Status USBH_MSC_InterfaceInit(USB_OTG_CORE_HANDLE* pdev,
+ void* phost)
+{
+ USBH_HOST* pphost = phost;
+
+
+
+ if ((pphost->device_prop.Itf_Desc[1].bInterfaceClass == 255) &&
+ (pphost->device_prop.Itf_Desc[1].bInterfaceProtocol == 0) &&
+ (pphost->device_prop.Itf_Desc[1].bInterfaceSubClass == 1)) {
+ if (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress & 0x80) {
+ MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
+ MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize;
+ } else {
+ MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
+ MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize;
+ }
+
+ if (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress & 0x80) {
+ MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress);
+ MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize;
+ } else {
+ MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress);
+ MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize;
+ }
+
+ MSC_Machine.hc_num_out = USBH_Alloc_Channel(pdev, MSC_Machine.MSBulkOutEp);
+ MSC_Machine.hc_num_in = USBH_Alloc_Channel(pdev, MSC_Machine.MSBulkInEp);
+
+ USBH_Open_Channel(pdev,
+ MSC_Machine.hc_num_out,
+ pphost->device_prop.address,
+ pphost->device_prop.speed,
+ EP_TYPE_BULK,
+ MSC_Machine.MSBulkOutEpSize);
+
+ USBH_Open_Channel(pdev,
+ MSC_Machine.hc_num_in,
+ pphost->device_prop.address,
+ pphost->device_prop.speed,
+ EP_TYPE_BULK,
+ MSC_Machine.MSBulkInEpSize);
+
+ }
+
+ else {
+ pphost->usr_cb->USBH_USR_DeviceNotSupported();
+ }
+
+ return USBH_OK ;
+
+}
+
+void USBH_MSC_InterfaceDeInit(USB_OTG_CORE_HANDLE* pdev,
+ void* phost)
+{
+ if (MSC_Machine.hc_num_out) {
+ USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_out);
+ USBH_Free_Channel(pdev, MSC_Machine.hc_num_out);
+ MSC_Machine.hc_num_out = 0;
+ }
+
+ if (MSC_Machine.hc_num_in) {
+ USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_in);
+ USBH_Free_Channel(pdev, MSC_Machine.hc_num_in);
+ MSC_Machine.hc_num_in = 0;
+ }
+}
+
+static USBH_Status USBH_MSC_ClassRequest(USB_OTG_CORE_HANDLE* pdev ,
+ void* phost)
+{
+
+ USBH_Status status = USBH_OK ;
+ return status;
+}
+
+static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE* pdev ,
+ void* phost)
+{
+ USBH_HOST* pphost = phost;
+
+ USBH_Status status = USBH_BUSY;
+
+ if (HCD_IsDeviceConnected(pdev)) {
+ int appliStatus = pphost->usr_cb->USBH_USR_MSC_Application();
+
+ if (appliStatus != 0) {
+ status = USBH_APPLY_DEINIT;
+ }
+ }
+
+ return status;
+
+}
+
+
+volatile uint32_t cnt;
+volatile uint32_t cnt_int;
+void USBH_LL_systick()
+{
+ cnt++;
+ cnt_int++;
+}
+
+
+void USBH_LL_setTimer()
+{
+ cnt = 0;
+}
+
+uint32_t USBH_LL_getTimer()
+{
+ return cnt;
+}
+
+
+int USBH_LL_open()
+{
+ int timeoutDetect = 100;
+ int timeoutStartup = 3000;
+ cnt_int = 0; //reset timer
+
+ while (USB_Host.gState != HOST_CLASS && cnt_int < timeoutDetect) {
+ USBH_Process(&USB_OTG_Core, &USB_Host);
+ }
+
+ if (USB_Host.gState != HOST_CLASS) {
+ return -5; // = LIBUSB_ERROR_NOT_FOUND
+ }
+
+
+ cnt_int = 0;
+
+ while (cnt_int < timeoutStartup) { //let pixy's led flashing pass
+ USBH_Process(&USB_OTG_Core, &USB_Host);
+ }
+
+ return 0; //ok
+}
+
+int USBH_LL_close()
+{
+ USBH_Process(&USB_OTG_Core, &USB_Host);
+ return 0;
+}
+
+int USBH_LL_send(const uint8_t* data, uint32_t len, uint16_t timeoutMs)
+{
+ USB_OTG_CORE_HANDLE* pdev = &USB_OTG_Core;
+
+ if (!HCD_IsDeviceConnected(pdev)) {
+ return -1;
+ }
+
+ USBH_BulkSendData(pdev,
+ (uint8_t*)data,
+ len ,
+ MSC_Machine.hc_num_out);
+
+ URB_STATE state;
+ cnt_int = 0; //reset timer
+
+ if (timeoutMs == 0) {
+ timeoutMs = 1000; //Force 1s timeout (testwise)
+ }
+
+ while ((state = HCD_GetURB_State(pdev , MSC_Machine.hc_num_out)) == URB_IDLE &&
+ (timeoutMs == 0 || cnt_int < timeoutMs));
+
+ if (state != URB_DONE) {
+ if (timeoutMs > 0 && cnt_int >= timeoutMs) {
+ STM_EVAL_LEDOn(LED3);
+ return -7; //timeout (error code like with libusb)
+
+ }
+
+ return -1;
+ }
+
+ return len;
+}
+
+int USBH_LL_receive(uint8_t* data, uint32_t len, uint16_t timeoutMs)
+{
+
+ USB_OTG_CORE_HANDLE* pdev = &USB_OTG_Core;
+
+ if (!HCD_IsDeviceConnected(pdev)) {
+ return -1;
+ }
+
+ USBH_BulkReceiveData(pdev,
+ data,
+ len ,
+ MSC_Machine.hc_num_in);
+
+ URB_STATE state;
+ cnt_int = 0; //reset timer
+
+ if (timeoutMs == 0) {
+ timeoutMs = 1000; //Force 1s timeout (testwise)
+ }
+
+ while ((state = HCD_GetURB_State(pdev , MSC_Machine.hc_num_in)) == URB_IDLE &&
+ (timeoutMs == 0 || cnt_int < timeoutMs));
+
+ if (state != URB_DONE) {
+ if (timeoutMs > 0 && cnt_int >= timeoutMs) {
+ STM_EVAL_LEDOn(LED3);
+ return -7; //timeout (error code like with libusb)
+ }
+
+ return -1;
+ }
+
+ return len;
+}
diff --git a/discovery/src/usbh_msc_core.h b/discovery/src/usbh_msc_core.h
index 1762829..80616cd 100644
--- a/discovery/src/usbh_msc_core.h
+++ b/discovery/src/usbh_msc_core.h
@@ -1,27 +1,38 @@
-
-/* Define to prevent recursive ----------------------------------------------*/
-#ifndef __USBH_MSC_CORE_H
-#define __USBH_MSC_CORE_H
-
-/* Includes ------------------------------------------------------------------*/
-#include "usbh_core.h"
-#include "usbh_stdreq.h"
-#include "usb_bsp.h"
-#include "usbh_ioreq.h"
-#include "usbh_hcs.h"
-
-
-extern USBH_Class_cb_TypeDef USBH_MSC_cb;
-
-void USBH_LL_systick();
-int USBH_LL_open();
-int USBH_LL_close();
-int USBH_LL_send(const uint8_t *data, uint32_t len, uint16_t timeoutMs);
-int USBH_LL_receive(uint8_t *data, uint32_t len, uint16_t timeoutMs);
-void USBH_LL_setTimer();
-uint32_t USBH_LL_getTimer();
-
-
-#endif /* __USBH_MSC_CORE_H */
-
-
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: discovery/src/usbh_msc_core.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 21dd1e2 Starting to integrate usb branch. Optimized Makefiles
+*
+**************************************************************************************************************************************/
+
+
+/* Define to prevent recursive ----------------------------------------------*/
+#ifndef __USBH_MSC_CORE_H
+#define __USBH_MSC_CORE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_core.h"
+#include "usbh_stdreq.h"
+#include "usb_bsp.h"
+#include "usbh_ioreq.h"
+#include "usbh_hcs.h"
+
+
+extern USBH_Class_cb_TypeDef USBH_MSC_cb;
+
+void USBH_LL_systick();
+int USBH_LL_open();
+int USBH_LL_close();
+int USBH_LL_send(const uint8_t* data, uint32_t len, uint16_t timeoutMs);
+int USBH_LL_receive(uint8_t* data, uint32_t len, uint16_t timeoutMs);
+void USBH_LL_setTimer();
+uint32_t USBH_LL_getTimer();
+
+
+#endif /* __USBH_MSC_CORE_H */
diff --git a/discovery/src/usbh_usr.c b/discovery/src/usbh_usr.c
index 1d8f8a3..a99d4ce 100644
--- a/discovery/src/usbh_usr.c
+++ b/discovery/src/usbh_usr.c
@@ -1,229 +1,245 @@
-#include "usbh_usr.h"
-#include
-#include
-
-
-USBH_Usr_cb_TypeDef USR_Callbacks =
-{
- USBH_USR_Init,
- USBH_USR_DeInit,
- USBH_USR_DeviceAttached,
- USBH_USR_ResetDevice,
- USBH_USR_DeviceDisconnected,
- USBH_USR_OverCurrentDetected,
- USBH_USR_DeviceSpeedDetected,
- USBH_USR_Device_DescAvailable,
- USBH_USR_DeviceAddressAssigned,
- USBH_USR_Configuration_DescAvailable,
- USBH_USR_Manufacturer_String,
- USBH_USR_Product_String,
- USBH_USR_SerialNum_String,
- USBH_USR_EnumerationDone,
- USBH_USR_UserInput,
- USBH_USR_MSC_Application,
- USBH_USR_DeviceNotSupported,
- USBH_USR_UnrecoveredError
-};
-
-
-/* Private function prototypes -----------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-bool manufacturer_ok;
-bool product_ok;
-bool serial_ok;
-
-/**
- * @brief USBH_USR_Init
- * @param None
- * @retval None
- */
-void USBH_USR_Init(void)
-{
-}
-
-/**
- * @brief USBH_USR_DeviceAttached
- * @param None
- * @retval None
- */
-void USBH_USR_DeviceAttached(void)
-{
- manufacturer_ok=false;
- product_ok= false;
- serial_ok=false;
-
- STM_EVAL_LEDOff(LED3);
- STM_EVAL_LEDOn(LED4);
-}
-
-/**
- * @brief USBH_USR_UnrecoveredError
- * @param None
- * @retval None
- */
-void USBH_USR_UnrecoveredError (void)
-{
-}
-
-/**
- * @brief USBH_DisconnectEvent
- * Device disconnect event
- * @param None
- * @retval Staus
- */
-void USBH_USR_DeviceDisconnected (void)
-{
- STM_EVAL_LEDOff(LED4);
-}
-
-/**
- * @brief USBH_USR_ResetUSBDevice
- * @param None
- * @retval None
- */
-void USBH_USR_ResetDevice(void)
-{
- /* callback for USB-Reset */
-}
-
-
-/**
- * @brief USBH_USR_DeviceSpeedDetected
- * Displays the message on LCD for device speed
- * @param Device speed:
- * @retval None
- */
-void USBH_USR_DeviceSpeedDetected(uint8_t DeviceSpeed)
-{
-}
-
-/**
- * @brief USBH_USR_Device_DescAvailable
- * @param device descriptor
- * @retval None
- */
-void USBH_USR_Device_DescAvailable(void *DeviceDesc)
-{
- /* callback for device descriptor */
-}
-
-/**
- * @brief USBH_USR_DeviceAddressAssigned
- * USB device is successfully assigned the Address
- * @param None
- * @retval None
- */
-void USBH_USR_DeviceAddressAssigned(void)
-{
- /* callback for device successfully assigned the Address */
-}
-
-/**
- * @brief USBH_USR_Conf_Desc
- * @param Configuration descriptor
- * @retval None
- */
-void USBH_USR_Configuration_DescAvailable(USBH_CfgDesc_TypeDef * cfgDesc,
- USBH_InterfaceDesc_TypeDef *itfDesc,
- USBH_EpDesc_TypeDef *epDesc)
-{
- /* callback for configuration descriptor */
-}
-
-/**
- * @brief USBH_USR_Manufacturer_String
- * @param Manufacturer String
- * @retval None
- */
-void USBH_USR_Manufacturer_String(void *ManufacturerString)
-{
- manufacturer_ok = strcmp((char*)ManufacturerString,"Charmed Labs") == 0;
-}
-
-/**
- * @brief USBH_USR_Product_String
- * @param Product String
- * @retval None
- */
-void USBH_USR_Product_String(void *ProductString)
-{
- product_ok = strcmp((char*)ProductString,"Pixy") == 0;
-}
-
-/**
- * @brief USBH_USR_SerialNum_String
- * @param SerialNum_String
- * @retval None
- */
-void USBH_USR_SerialNum_String(void *SerialNumString)
-{
- serial_ok = strcmp((char*)SerialNumString,"DEMO 0.0") == 0;
-}
-
-/**
- * @brief EnumerationDone
- * User response request is displayed to ask application jump to class
- * @param None
- * @retval None
- */
-void USBH_USR_EnumerationDone(void)
-{
-
-}
-
-/**
- * @brief USBH_USR_DeviceNotSupported
- * Device is not supported
- * @param None
- * @retval None
- */
-void USBH_USR_DeviceNotSupported(void)
-{
-}
-
-
-/**
- * @brief USBH_USR_UserInput
- * User Action for application state entry
- * @param None
- * @retval USBH_USR_Status : User response for key button
- */
-USBH_USR_Status USBH_USR_UserInput(void)
-{
- if(product_ok&&manufacturer_ok&&serial_ok) {
- return USBH_USR_RESP_OK;
- }
- return USBH_USR_NO_RESP;
-}
-
-/**
- * @brief USBH_USR_OverCurrentDetected
- * Over Current Detected on VBUS
- * @param None
- * @retval None
- */
-void USBH_USR_OverCurrentDetected (void)
-{
-}
-
-/**
- * @brief USBH_USR_MSC_Application
- * @param None
- * @retval Staus
- */
-int USBH_USR_MSC_Application(void)
-{
- return 0;
-}
-
-/**
- * @brief USBH_USR_DeInit
- * Deint User state and associated variables
- * @param None
- * @retval None
- */
-void USBH_USR_DeInit(void)
-{
-
-}
-
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: discovery/src/usbh_usr.c
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 21dd1e2 Starting to integrate usb branch. Optimized Makefiles
+* 2015-04-03 timolang@gmail.com 9a1d12a Refactored discovery, to use new project structure. Almost ready.
+* 2015-04-25 timolang@gmail.com 416883c Pixy&Usb work with the new folder structure now.
+* 2015-04-25 timolang@gmail.com 3d1e4b2 Simplified code a bit. Emulator does not work stable when replugging pixy.
+* 2015-06-02 timolang@gmail.com 16bfdad Removed conflicting led usage from usb code.
+*
+**************************************************************************************************************************************/
+
+#include "usbh_usr.h"
+#include
+#include
+
+
+USBH_Usr_cb_TypeDef USR_Callbacks = {
+ USBH_USR_Init,
+ USBH_USR_DeInit,
+ USBH_USR_DeviceAttached,
+ USBH_USR_ResetDevice,
+ USBH_USR_DeviceDisconnected,
+ USBH_USR_OverCurrentDetected,
+ USBH_USR_DeviceSpeedDetected,
+ USBH_USR_Device_DescAvailable,
+ USBH_USR_DeviceAddressAssigned,
+ USBH_USR_Configuration_DescAvailable,
+ USBH_USR_Manufacturer_String,
+ USBH_USR_Product_String,
+ USBH_USR_SerialNum_String,
+ USBH_USR_EnumerationDone,
+ USBH_USR_UserInput,
+ USBH_USR_MSC_Application,
+ USBH_USR_DeviceNotSupported,
+ USBH_USR_UnrecoveredError
+};
+
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+bool manufacturer_ok;
+bool product_ok;
+bool serial_ok;
+
+/**
+ * @brief USBH_USR_Init
+ * @param None
+ * @retval None
+ */
+void USBH_USR_Init(void)
+{
+}
+
+/**
+ * @brief USBH_USR_DeviceAttached
+ * @param None
+ * @retval None
+ */
+void USBH_USR_DeviceAttached(void)
+{
+ manufacturer_ok = false;
+ product_ok = false;
+ serial_ok = false;
+
+ STM_EVAL_LEDOff(LED3);
+ STM_EVAL_LEDOn(LED4);
+}
+
+/**
+ * @brief USBH_USR_UnrecoveredError
+ * @param None
+ * @retval None
+ */
+void USBH_USR_UnrecoveredError(void)
+{
+}
+
+/**
+ * @brief USBH_DisconnectEvent
+ * Device disconnect event
+ * @param None
+ * @retval Staus
+ */
+void USBH_USR_DeviceDisconnected(void)
+{
+ STM_EVAL_LEDOff(LED4);
+}
+
+/**
+ * @brief USBH_USR_ResetUSBDevice
+ * @param None
+ * @retval None
+ */
+void USBH_USR_ResetDevice(void)
+{
+ /* callback for USB-Reset */
+}
+
+
+/**
+ * @brief USBH_USR_DeviceSpeedDetected
+ * Displays the message on LCD for device speed
+ * @param Device speed:
+ * @retval None
+ */
+void USBH_USR_DeviceSpeedDetected(uint8_t DeviceSpeed)
+{
+}
+
+/**
+ * @brief USBH_USR_Device_DescAvailable
+ * @param device descriptor
+ * @retval None
+ */
+void USBH_USR_Device_DescAvailable(void* DeviceDesc)
+{
+ /* callback for device descriptor */
+}
+
+/**
+ * @brief USBH_USR_DeviceAddressAssigned
+ * USB device is successfully assigned the Address
+ * @param None
+ * @retval None
+ */
+void USBH_USR_DeviceAddressAssigned(void)
+{
+ /* callback for device successfully assigned the Address */
+}
+
+/**
+ * @brief USBH_USR_Conf_Desc
+ * @param Configuration descriptor
+ * @retval None
+ */
+void USBH_USR_Configuration_DescAvailable(USBH_CfgDesc_TypeDef* cfgDesc,
+ USBH_InterfaceDesc_TypeDef* itfDesc,
+ USBH_EpDesc_TypeDef* epDesc)
+{
+ /* callback for configuration descriptor */
+}
+
+/**
+ * @brief USBH_USR_Manufacturer_String
+ * @param Manufacturer String
+ * @retval None
+ */
+void USBH_USR_Manufacturer_String(void* ManufacturerString)
+{
+ manufacturer_ok = strcmp((char*)ManufacturerString, "Charmed Labs") == 0;
+}
+
+/**
+ * @brief USBH_USR_Product_String
+ * @param Product String
+ * @retval None
+ */
+void USBH_USR_Product_String(void* ProductString)
+{
+ product_ok = strcmp((char*)ProductString, "Pixy") == 0;
+}
+
+/**
+ * @brief USBH_USR_SerialNum_String
+ * @param SerialNum_String
+ * @retval None
+ */
+void USBH_USR_SerialNum_String(void* SerialNumString)
+{
+ serial_ok = strcmp((char*)SerialNumString, "DEMO 0.0") == 0;
+}
+
+/**
+ * @brief EnumerationDone
+ * User response request is displayed to ask application jump to class
+ * @param None
+ * @retval None
+ */
+void USBH_USR_EnumerationDone(void)
+{
+
+}
+
+/**
+ * @brief USBH_USR_DeviceNotSupported
+ * Device is not supported
+ * @param None
+ * @retval None
+ */
+void USBH_USR_DeviceNotSupported(void)
+{
+}
+
+
+/**
+ * @brief USBH_USR_UserInput
+ * User Action for application state entry
+ * @param None
+ * @retval USBH_USR_Status : User response for key button
+ */
+USBH_USR_Status USBH_USR_UserInput(void)
+{
+ if (product_ok && manufacturer_ok && serial_ok) {
+ return USBH_USR_RESP_OK;
+ }
+
+ return USBH_USR_NO_RESP;
+}
+
+/**
+ * @brief USBH_USR_OverCurrentDetected
+ * Over Current Detected on VBUS
+ * @param None
+ * @retval None
+ */
+void USBH_USR_OverCurrentDetected(void)
+{
+}
+
+/**
+ * @brief USBH_USR_MSC_Application
+ * @param None
+ * @retval Staus
+ */
+int USBH_USR_MSC_Application(void)
+{
+ return 0;
+}
+
+/**
+ * @brief USBH_USR_DeInit
+ * Deint User state and associated variables
+ * @param None
+ * @retval None
+ */
+void USBH_USR_DeInit(void)
+{
+
+}
diff --git a/discovery/src/usbh_usr.h b/discovery/src/usbh_usr.h
index 3579dee..1da61c5 100644
--- a/discovery/src/usbh_usr.h
+++ b/discovery/src/usbh_usr.h
@@ -1,51 +1,60 @@
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __USH_USR_H__
-#define __USH_USR_H__
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f4_discovery.h"
-#include "usbh_core.h"
-#include
-
-
-/* Exported macros -----------------------------------------------------------*/
-/* Exported variables --------------------------------------------------------*/
-extern USBH_Usr_cb_TypeDef USR_Callbacks;
-
-/* Exported functions ------------------------------------------------------- */
-void USBH_USR_Init(void);
-void USBH_USR_DeviceAttached(void);
-void USBH_USR_ResetDevice(void);
-void USBH_USR_DeviceDisconnected (void);
-void USBH_USR_OverCurrentDetected (void);
-void USBH_USR_DeviceSpeedDetected(uint8_t DeviceSpeed);
-void USBH_USR_Device_DescAvailable(void *);
-void USBH_USR_DeviceAddressAssigned(void);
-void USBH_USR_Configuration_DescAvailable(USBH_CfgDesc_TypeDef * cfgDesc,
- USBH_InterfaceDesc_TypeDef *itfDesc,
- USBH_EpDesc_TypeDef *epDesc);
-void USBH_USR_Manufacturer_String(void *);
-void USBH_USR_Product_String(void *);
-void USBH_USR_SerialNum_String(void *);
-void USBH_USR_EnumerationDone(void);
-USBH_USR_Status USBH_USR_UserInput(void);
-int USBH_USR_MSC_Application(void);
-void USBH_USR_DeInit(void);
-void USBH_USR_DeviceNotSupported(void);
-void USBH_USR_UnrecoveredError(void);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*__USH_USR_H__*/
-
-/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
-
-
-
-
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: discovery/src/usbh_usr.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 21dd1e2 Starting to integrate usb branch. Optimized Makefiles
+*
+**************************************************************************************************************************************/
+
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USH_USR_H__
+#define __USH_USR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4_discovery.h"
+#include "usbh_core.h"
+#include
+
+
+/* Exported macros -----------------------------------------------------------*/
+/* Exported variables --------------------------------------------------------*/
+extern USBH_Usr_cb_TypeDef USR_Callbacks;
+
+/* Exported functions ------------------------------------------------------- */
+void USBH_USR_Init(void);
+void USBH_USR_DeviceAttached(void);
+void USBH_USR_ResetDevice(void);
+void USBH_USR_DeviceDisconnected(void);
+void USBH_USR_OverCurrentDetected(void);
+void USBH_USR_DeviceSpeedDetected(uint8_t DeviceSpeed);
+void USBH_USR_Device_DescAvailable(void*);
+void USBH_USR_DeviceAddressAssigned(void);
+void USBH_USR_Configuration_DescAvailable(USBH_CfgDesc_TypeDef* cfgDesc,
+ USBH_InterfaceDesc_TypeDef* itfDesc,
+ USBH_EpDesc_TypeDef* epDesc);
+void USBH_USR_Manufacturer_String(void*);
+void USBH_USR_Product_String(void*);
+void USBH_USR_SerialNum_String(void*);
+void USBH_USR_EnumerationDone(void);
+USBH_USR_Status USBH_USR_UserInput(void);
+int USBH_USR_MSC_Application(void);
+void USBH_USR_DeInit(void);
+void USBH_USR_DeviceNotSupported(void);
+void USBH_USR_UnrecoveredError(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__USH_USR_H__*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/doc/.gitignore b/doc/.gitignore
index 8709cfb..fa8d7aa 100644
--- a/doc/.gitignore
+++ b/doc/.gitignore
@@ -1,2 +1,3 @@
*.*~
html/
+latex/
diff --git a/doc/docu.odt b/doc/docu.odt
index e400a42..f227209 100644
Binary files a/doc/docu.odt and b/doc/docu.odt differ
diff --git a/doc/docu.pdf b/doc/docu.pdf
index 4e45d7d..3afa8cb 100644
Binary files a/doc/docu.pdf and b/doc/docu.pdf differ
diff --git a/doc/refman.pdf b/doc/refman.pdf
new file mode 100644
index 0000000..d4f6076
Binary files /dev/null and b/doc/refman.pdf differ
diff --git a/emulator/qt/ll_filesystem.cpp b/emulator/qt/ll_filesystem.cpp
index 8d1d47f..03f476c 100644
--- a/emulator/qt/ll_filesystem.cpp
+++ b/emulator/qt/ll_filesystem.cpp
@@ -1,5 +1,19 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: emulator/qt/ll_filesystem.cpp
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-05-10 timolang@gmail.com e2bce8f Added filesystem module, tests and implementation for it in emulator.
+* 2015-06-07 timolang@gmail.com 4b5768c Improved Comments in whole emulator. Finalized emulator section in docu.
+*
+**************************************************************************************************************************************/
+
extern "C" {
- #include "ll_filesystem.h"
+#include "ll_filesystem.h"
}
#include
#include
@@ -7,69 +21,78 @@ extern "C" {
#include
#include
-QDir rootdir ("./emulated"); //Create a QDir which points to the "root" of the emulated filesystem
+QDir rootdir("./emulated"); //Create a QDir which points to the "root" of the emulated filesystem
-bool ll_filesystem_init() {
- if(!rootdir.exists()) { //if our root dir is nonexistent
+bool ll_filesystem_init()
+{
+ if (!rootdir.exists()) { //if our root dir is nonexistent
qWarning() << "Filesystem can not be emulated because the 'emulated' folder does not exist";
return false; //mark an error
}
+
return true;
}
-DIRECTORY_STRUCT* ll_filesystem_dir_open(const char* path) {
+DIRECTORY_STRUCT* ll_filesystem_dir_open(const char* path)
+{
QDir d(rootdir); //Make a copy of the rootdir QDir instance
d.cd(path); //Change the directory to the passed path
- if(!d.exists()) {
+
+ if (!d.exists()) {
return NULL; //mark an error
}
DIRECTORY_STRUCT* directory = new DIRECTORY_STRUCT();
//get all files and directories which are important to us. Filter out . and .. symlinks (linux)
- QFileInfoList entries = d.entryInfoList(QDir::NoDotAndDotDot|QDir::Files|QDir::Dirs|QDir::Readable|QDir::Writable|QDir::Hidden|QDir::System);
+ QFileInfoList entries = d.entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs | QDir::Readable | QDir::Writable | QDir::Hidden | QDir::System);
//Fill the directory structure for the user
directory->path = path;
directory->num_files = entries.count();
directory->files = new FILE_STRUCT[directory->num_files]; //allocate array of file structs
- for(int i=0; ifiles[i]); //get the pointer to the current filestruct (which should be filled)
entry->fattrib = 0;
- entry->fname = new char[fi.fileName().length()+1]; //reserve memory for filename
- strcpy(entry->fname,fi.fileName().toStdString().c_str()); //copy filename into struct
- if(fi.isDir()) { //it's a direcory
- entry->fattrib|=F_DIR; //set directory attribute
+ entry->fname = new char[fi.fileName().length() + 1]; //reserve memory for filename
+ strcpy(entry->fname, fi.fileName().toStdString().c_str()); //copy filename into struct
+
+ if (fi.isDir()) { //it's a direcory
+ entry->fattrib |= F_DIR; //set directory attribute
entry->fsize = 0;
} else { //it's a file
entry->fsize = fi.size(); //set filesize
}
- if(fi.isHidden()) { //the file is hidden
- entry->fattrib|=F_HID;
+
+ if (fi.isHidden()) { //the file is hidden
+ entry->fattrib |= F_HID;
}
- if(!fi.isWritable()) { //the file is not writable
- entry->fattrib|=F_RDO; //set readonly attribue
+
+ if (!fi.isWritable()) { //the file is not writable
+ entry->fattrib |= F_RDO; //set readonly attribue
}
//Set date & time of file in structure
QDateTime dt = fi.lastModified();
- entry->fdate.year = dt.date().year()-1980; //year is realtive to 1980
+ entry->fdate.year = dt.date().year() - 1980; //year is realtive to 1980
entry->fdate.month = dt.date().month();
entry->fdate.day = dt.date().day();
entry->ftime.hour = dt.time().hour();
entry->ftime.min = dt.time().minute();
- entry->ftime.sec = dt.time().second()/2;
+ entry->ftime.sec = dt.time().second() / 2;
}
return directory; //return filled directory struct
}
-void ll_filesystem_dir_close(DIRECTORY_STRUCT* dir) {
- if(dir!=NULL) { //passed handle is valid
- for(int i=0; inum_files; i++) { //foreach file
+void ll_filesystem_dir_close(DIRECTORY_STRUCT* dir)
+{
+ if (dir != NULL) { //passed handle is valid
+ for (int i = 0; i < dir->num_files; i++) { //foreach file
delete dir->files[i].fname; //delete filename buffer
}
+
delete[] dir->files; //delete file array
delete dir; //delete structure itself
}
@@ -81,17 +104,20 @@ struct QT_FILE_HANDLE : FILE_HANDLE { //..derived from the FILE_HANDLE (of the F
};
-FILE_HANDLE* ll_filesystem_file_open(const char* filename) {
- if(!rootdir.exists()) {
+FILE_HANDLE* ll_filesystem_file_open(const char* filename)
+{
+ if (!rootdir.exists()) {
return NULL;
}
+
QString filepath = rootdir.absoluteFilePath(filename); //get the absolute path to the requested file
QFile* f = new QFile(filepath); //create a QFile instance to the requested file
- if(!f->exists()) { //File does not exist
+
+ if (!f->exists()) { //File does not exist
return NULL; //mark error
}
- if(!f->open(QFile::ReadWrite)) { //try to open the file, it it fails then ...
+ if (!f->open(QFile::ReadWrite)) { //try to open the file, it it fails then ...
return NULL; //... mark error
}
@@ -100,35 +126,42 @@ FILE_HANDLE* ll_filesystem_file_open(const char* filename) {
QT_FILE_HANDLE* fh = new QT_FILE_HANDLE(); //Create Structure to return to user
fh->file = f;
fh->fname = filename;
- fh->fpos =0;
+ fh->fpos = 0;
fh->fsize = f->size();
return fh;
}
-void ll_filesystem_file_close(FILE_HANDLE* handle) {
- if(handle!=NULL) { //passed handle is valid
+void ll_filesystem_file_close(FILE_HANDLE* handle)
+{
+ if (handle != NULL) { //passed handle is valid
QT_FILE_HANDLE* fh = static_cast(handle); //cast pointer to QT_FILE_HANDLE
- if(fh->file->isOpen()) { //if the file is still open
+
+ if (fh->file->isOpen()) { //if the file is still open
fh->file->close(); //close the file
}
+
delete fh->file; //delete QFile instance
delete fh; //delete the fle
}
}
-FILE_STATUS ll_filesystem_file_seek(FILE_HANDLE* handle, uint32_t offset) {
- if(handle==NULL) {
- return F_INVALIDPARAM;
- }
- QT_FILE_HANDLE* fh = static_cast(handle); //cast pointer to QT_FILE_HANDLE
- if(!fh->file->isOpen()) { //file is not open
- return F_DISKERROR;
- }
- if(offset>=fh->file->size()) { //offset exeeds filesize
+FILE_STATUS ll_filesystem_file_seek(FILE_HANDLE* handle, uint32_t offset)
+{
+ if (handle == NULL) {
return F_INVALIDPARAM;
}
- if(fh->file->seek(offset)) { //try to seek to desired offset
+ QT_FILE_HANDLE* fh = static_cast(handle); //cast pointer to QT_FILE_HANDLE
+
+ if (!fh->file->isOpen()) { //file is not open
+ return F_DISKERROR;
+ }
+
+ if (offset >= fh->file->size()) { //offset exeeds filesize
+ return F_INVALIDPARAM;
+ }
+
+ if (fh->file->seek(offset)) { //try to seek to desired offset
fh->fpos = offset; //update offset in FILE_HANDLE (for user)
return F_OK;
} else { //seek failed
@@ -136,49 +169,64 @@ FILE_STATUS ll_filesystem_file_seek(FILE_HANDLE* handle, uint32_t offset) {
}
}
-FILE_STATUS ll_filesystem_file_read(FILE_HANDLE* handle, uint8_t* buf, uint32_t size) {
- if(handle==NULL || buf==NULL) {
+FILE_STATUS ll_filesystem_file_read(FILE_HANDLE* handle, uint8_t* buf, uint32_t size)
+{
+ if (handle == NULL || buf == NULL) {
return F_INVALIDPARAM;
}
+
QT_FILE_HANDLE* fh = static_cast(handle); //cast pointer to QT_FILE_HANDLE
- if(!fh->file->isOpen()) { //file is not open
+
+ if (!fh->file->isOpen()) { //file is not open
return F_DISKERROR;
}
- if(!fh->file->isReadable()) { //file is not readable
+
+ if (!fh->file->isReadable()) { //file is not readable
return F_EACCESS;
}
- qint64 bytesRead = fh->file->read((char*)buf,size); //try to read desired amount of bytes
- if(bytesRead<0) { //read failed
+
+ qint64 bytesRead = fh->file->read((char*)buf, size); //try to read desired amount of bytes
+
+ if (bytesRead < 0) { //read failed
return F_DISKERROR;
}
- fh->fpos+=bytesRead; //increase file position (for user)
- if(bytesRead!=size) { //we got less bytes than expected
+
+ fh->fpos += bytesRead; //increase file position (for user)
+
+ if (bytesRead != size) { //we got less bytes than expected
return F_EOF; //we reached the end of the file
} else {
return F_OK;
}
}
-FILE_STATUS ll_filesystem_file_write(FILE_HANDLE* handle, uint8_t* buf, uint32_t size) {
- if(handle==NULL) {
+FILE_STATUS ll_filesystem_file_write(FILE_HANDLE* handle, uint8_t* buf, uint32_t size)
+{
+ if (handle == NULL) {
return F_INVALIDPARAM;
}
+
QT_FILE_HANDLE* fh = static_cast(handle); //cast pointer to QT_FILE_HANDLE
- if(!fh->file->isOpen()) { //file is not open
+
+ if (!fh->file->isOpen()) { //file is not open
return F_DISKERROR;
}
- if(!fh->file->isWritable()) { //file is not writable
+
+ if (!fh->file->isWritable()) { //file is not writable
return F_EACCESS;
}
- qint64 bytesWritten = fh->file->write((char*)buf,size); //try to write desired amount of bytes
- if(bytesWritten<0) { //write failed
+
+ qint64 bytesWritten = fh->file->write((char*)buf, size); //try to write desired amount of bytes
+
+ if (bytesWritten < 0) { //write failed
return F_DISKERROR;
}
- fh->fpos+=bytesWritten; //increase file position (for user)
- if(bytesWritten!=size) { //we wrote less bytes than expected
+
+ fh->fpos += bytesWritten; //increase file position (for user)
+
+ if (bytesWritten != size) { //we wrote less bytes than expected
return F_EOF; //we reached the end of the file
} else {
return F_OK;
}
}
-
diff --git a/emulator/qt/ll_system.cpp b/emulator/qt/ll_system.cpp
index 68efd72..7b0734c 100644
--- a/emulator/qt/ll_system.cpp
+++ b/emulator/qt/ll_system.cpp
@@ -1,3 +1,21 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: emulator/qt/ll_system.cpp
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 1f2af9f Added more tft functions to common and emulator. Fixed eventloop.
+* 2015-04-03 timolang@gmail.com cab8609 Integrated pixy into emulator. Pixy is no longer in the common/libs folder but in emulator/libs and discovery/libs
+* 2015-04-25 timolang@gmail.com 3d1e4b2 Simplified code a bit. Emulator does not work stable when replugging pixy.
+* 2015-04-25 timolang@gmail.com 0858b0d Fixed some bugs when receiving large data.
+* 2015-05-09 timolang@gmail.com c652b6b Improved Emulator Gui
+* 2015-06-07 timolang@gmail.com 4b5768c Improved Comments in whole emulator. Finalized emulator section in docu.
+*
+**************************************************************************************************************************************/
+
#include
#include
@@ -5,19 +23,23 @@ extern "C" {
#include "ll_system.h"
}
-bool ll_system_init() {
+bool ll_system_init()
+{
return true; //nothing to initialize here, apart from the stuff which is done in the main method.
}
-void ll_system_delay(uint32_t msec) {
- QThread::msleep(msec); //Let the app_process() Thread sleep
+void ll_system_delay(uint32_t msec)
+{
+ QThread::msleep(msec); //Let the app_process() Thread sleep
}
-void ll_system_process() {
- QApplication::processEvents(); //Process pending qt events
- QThread::msleep(1); //Sleep for 1ms, to keep the cpu load down
+void ll_system_process()
+{
+ QApplication::processEvents(); //Process pending qt events
+ QThread::msleep(1); //Sleep for 1ms, to keep the cpu load down
}
-void ll_system_toggle_led() {
+void ll_system_toggle_led()
+{
//No led emulated :(
}
diff --git a/emulator/qt/ll_tft.cpp b/emulator/qt/ll_tft.cpp
index 5963104..7003991 100644
--- a/emulator/qt/ll_tft.cpp
+++ b/emulator/qt/ll_tft.cpp
@@ -1,3 +1,22 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: emulator/qt/ll_tft.cpp
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 51089aa Refactored Project Structure for use with emulator
+* 2015-04-03 timolang@gmail.com 1f2af9f Added more tft functions to common and emulator. Fixed eventloop.
+* 2015-04-03 timolang@gmail.com 1aa9194 Fixed Drawing of rects in Emulator. Got frames from pixy to emulator. Slooooow.
+* 2015-04-27 aaron@duckpond.ch aed90ef Drawcircle added (emulator)
+* 2015-04-27 timolang@gmail.com e249fb2 Added font support
+* 2015-05-15 timolang@gmail.com b08a897 Added tft method to draw a bmp from filesystem. Added another font to emulator.
+* 2015-06-07 timolang@gmail.com 4b5768c Improved Comments in whole emulator. Finalized emulator section in docu.
+*
+**************************************************************************************************************************************/
+
#include "mainwindow.h"
extern "C" {
@@ -6,50 +25,60 @@ extern "C" {
MainWindow* mainwindow;
-bool ll_tft_init() {
- mainwindow = new MainWindow(); //create the designed window
- mainwindow->show(); //open it (non blocking)
- return true;
+bool ll_tft_init()
+{
+ mainwindow = new MainWindow(); //create the designed window
+ mainwindow->show(); //open it (non blocking)
+ return true;
}
//the following functions redirect the call to the mainwindow, to a function with the same signature
-void ll_tft_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) {
- mainwindow->draw_line(x1,y1,x2,y2,color);
+void ll_tft_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
+{
+ mainwindow->draw_line(x1, y1, x2, y2, color);
}
-void ll_tft_clear(uint16_t color) {
+void ll_tft_clear(uint16_t color)
+{
mainwindow->clear(color);
}
-void ll_tft_draw_pixel(uint16_t x,uint16_t y,uint16_t color) {
- mainwindow->draw_pixel(x,y,color);
+void ll_tft_draw_pixel(uint16_t x, uint16_t y, uint16_t color)
+{
+ mainwindow->draw_pixel(x, y, color);
}
-void ll_tft_draw_rectangle(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2, uint16_t color) {
- mainwindow->draw_rectangle(x1,y1,x2,y2,color);
+void ll_tft_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
+{
+ mainwindow->draw_rectangle(x1, y1, x2, y2, color);
}
-void ll_tft_fill_rectangle(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2, uint16_t color) {
- mainwindow->fill_rectangle(x1,y1,x2,y2,color);
+void ll_tft_fill_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
+{
+ mainwindow->fill_rectangle(x1, y1, x2, y2, color);
}
-void ll_tft_draw_bitmap_unscaled(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t* dat) {
- mainwindow->draw_bitmap_unscaled(x,y,width,height,dat);
+void ll_tft_draw_bitmap_unscaled(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t* dat)
+{
+ mainwindow->draw_bitmap_unscaled(x, y, width, height, dat);
}
-void ll_tft_draw_circle(uint16_t x, uint16_t y, uint16_t r, uint16_t color) {
- mainwindow->draw_circle(x,y,r,color);
+void ll_tft_draw_circle(uint16_t x, uint16_t y, uint16_t r, uint16_t color)
+{
+ mainwindow->draw_circle(x, y, r, color);
}
-uint8_t ll_tft_num_fonts() {
+uint8_t ll_tft_num_fonts()
+{
return 2; //we have two fonts (see below)
}
//Helper function to get the QFont to the corresponding font number
//Note: only return monospaced fonts!!!
-QFont get_font(uint8_t fontnum) {
+QFont get_font(uint8_t fontnum)
+{
switch(fontnum) {
case 0:
return QFont("Courier New",8);
@@ -61,23 +90,37 @@ QFont get_font(uint8_t fontnum) {
}
-uint8_t ll_tft_font_height(uint8_t fontnum) {
+uint8_t ll_tft_font_height(uint8_t fontnum)
+{
QFont f = get_font(fontnum);
- if(f == QFont()) return -1;
+
+ if (f == QFont()) {
+ return -1;
+ }
+
QFontMetrics m(f); //use font metcris object to calculate height of font
return m.height();
}
-uint8_t ll_tft_font_width(uint8_t fontnum) {
+uint8_t ll_tft_font_width(uint8_t fontnum)
+{
QFont f = get_font(fontnum);
- if(f == QFont()) return -1;
+
+ if (f == QFont()) {
+ return -1;
+ }
+
QFontMetrics m(f); //use font metcris object to calculate width of font
return m.averageCharWidth();
}
-void ll_tft_draw_char(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t font, char c) {
+void ll_tft_draw_char(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t font, char c)
+{
QFont f = get_font(font);
- if(f == QFont()) return; //if the font is the default-font, we want to abort.
- mainwindow->draw_char(x,y,color,bgcolor,f,c);
-}
+ if (f == QFont()) {
+ return; //if the font is the default-font, we want to abort.
+ }
+
+ mainwindow->draw_char(x, y, color, bgcolor, f, c);
+}
diff --git a/emulator/qt/ll_touch.cpp b/emulator/qt/ll_touch.cpp
index cf978d9..996d3a6 100644
--- a/emulator/qt/ll_touch.cpp
+++ b/emulator/qt/ll_touch.cpp
@@ -1,10 +1,25 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: emulator/qt/ll_touch.cpp
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-27 timolang@gmail.com 259d446 Added touch support to emulator. Implemented basic touch function.
+* 2015-06-01 timolang@gmail.com eb573bc Finalized calibration. Fixed a bug in screen module.
+*
+**************************************************************************************************************************************/
+
extern "C" {
#include "ll_touch.h"
#include "touch.h"
}
-bool ll_touch_init() {
+bool ll_touch_init()
+{
touch_set_value_convert_mode(false); //tell the touch module that we don't need calibration or value conversion
return true;
}
diff --git a/emulator/qt/main.cpp b/emulator/qt/main.cpp
index 96937c1..9a73892 100644
--- a/emulator/qt/main.cpp
+++ b/emulator/qt/main.cpp
@@ -1,3 +1,21 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: emulator/qt/main.cpp
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 51089aa Refactored Project Structure for use with emulator
+* 2015-04-03 timolang@gmail.com 1f2af9f Added more tft functions to common and emulator. Fixed eventloop.
+* 2015-04-03 timolang@gmail.com cab8609 Integrated pixy into emulator. Pixy is no longer in the common/libs folder but in emulator/libs and discovery/libs
+* 2015-04-07 timolang@gmail.com 383fc86 Simplified Emulator (main)
+* 2015-04-25 timolang@gmail.com 3d1e4b2 Simplified code a bit. Emulator does not work stable when replugging pixy.
+* 2015-06-07 timolang@gmail.com 4b5768c Improved Comments in whole emulator. Finalized emulator section in docu.
+*
+**************************************************************************************************************************************/
+
#include
#include
@@ -7,19 +25,18 @@ extern "C" {
void app_process(); //Processes one eventloop of the app
}
-void app_loop() {
- while(!QApplication::closingDown()) { //as long as the application is not terminating
+void app_loop()
+{
+ while (!QApplication::closingDown()) { //as long as the application is not terminating
app_process(); //let the application process it's events
}
}
-int main(int argc, char* argv[]) {
- QApplication app(argc,argv); //Process qt-specific commandline arguments and create event loop
+int main(int argc, char* argv[])
+{
+ QApplication app(argc, argv); //Process qt-specific commandline arguments and create event loop
app_init(); //Let the application initialize it self
QtConcurrent::run(&app_loop); //Start a thread that executes app_loop
return app.exec(); //Run the event loop until the last window is closed.
}
-
-
-
diff --git a/emulator/qt/mainwindow.cpp b/emulator/qt/mainwindow.cpp
index 99b2ae2..d04e133 100644
--- a/emulator/qt/mainwindow.cpp
+++ b/emulator/qt/mainwindow.cpp
@@ -1,3 +1,29 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: emulator/qt/mainwindow.cpp
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 51089aa Refactored Project Structure for use with emulator
+* 2015-04-03 timolang@gmail.com 1f2af9f Added more tft functions to common and emulator. Fixed eventloop.
+* 2015-04-03 timolang@gmail.com c570bda Fixed bug in color conversion
+* 2015-04-03 timolang@gmail.com 867f766 Some gui changes.
+* 2015-04-03 timolang@gmail.com 1aa9194 Fixed Drawing of rects in Emulator. Got frames from pixy to emulator. Slooooow.
+* 2015-04-04 timolang@gmail.com 0636381 Improved tff_draw_bitmap_unscaled in emulator.
+* 2015-04-27 timolang@gmail.com 259d446 Added touch support to emulator. Implemented basic touch function.
+* 2015-04-27 aaron@duckpond.ch aed90ef Drawcircle added (emulator)
+* 2015-04-27 timolang@gmail.com e249fb2 Added font support
+* 2015-05-09 timolang@gmail.com c652b6b Improved Emulator Gui
+* 2015-05-25 timolang@gmail.com 911760e Added "Mouse Position"-Label to Emulator.
+* 2015-06-01 timolang@gmail.com 06227da Added calibrate screen (WIP). fixed bug in emulator drawing.
+* 2015-06-07 timolang@gmail.com 4b5768c Improved Comments in whole emulator. Finalized emulator section in docu.
+* 2015-06-07 timolang@gmail.com 8752356 Started with tests in docu. fixed a small bug in emulator when drawing a rectangle.
+*
+**************************************************************************************************************************************/
+
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
@@ -6,33 +32,36 @@
#include
extern "C" {
- #include "touch.h"
- #include "tft.h"
+#include "touch.h"
+#include "tft.h"
}
#define DISPLAY_WIDTH 320
#define DISPLAY_HEIGHT 240
//function to calculate QColor out of a RGB565 16bit color
-QColor QColorFromRGB565(uint16_t color) {
+QColor QColorFromRGB565(uint16_t color)
+{
//interpolate colors
- int R8 = (int) floor( (color>>(5+6)) * 255.0 / 31.0 + 0.5);
- int G8 = (int) floor( ((color>>5)&0x3F) * 255.0 / 63.0 + 0.5);
- int B8 = (int) floor( (color&0x1F) * 255.0 / 31.0 + 0.5);
- return QColor::fromRgb(R8,G8,B8);
+ int R8 = (int) floor((color >> (5 + 6)) * 255.0 / 31.0 + 0.5);
+ int G8 = (int) floor(((color >> 5) & 0x3F) * 255.0 / 63.0 + 0.5);
+ int B8 = (int) floor((color & 0x1F) * 255.0 / 31.0 + 0.5);
+ return QColor::fromRgb(R8, G8, B8);
}
//function to calculate QRgb out of a RGB565 16bit color
-QRgb QRgbFromRGB565(uint16_t color) {
+QRgb QRgbFromRGB565(uint16_t color)
+{
//interpolate colors
- int R8 = (int) floor( (color>>(5+6)) * 255.0 / 31.0 + 0.5);
- int G8 = (int) floor( ((color>>5)&0x3F) * 255.0 / 63.0 + 0.5);
- int B8 = (int) floor( (color&0x1F) * 255.0 / 31.0 + 0.5);
- return qRgb(R8,G8,B8);
+ int R8 = (int) floor((color >> (5 + 6)) * 255.0 / 31.0 + 0.5);
+ int G8 = (int) floor(((color >> 5) & 0x3F) * 255.0 / 63.0 + 0.5);
+ int B8 = (int) floor((color & 0x1F) * 255.0 / 31.0 + 0.5);
+ return qRgb(R8, G8, B8);
}
-MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), image(DISPLAY_WIDTH,DISPLAY_HEIGHT, QImage::Format_RGB16), ui(new Ui::MainWindow){
+MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), image(DISPLAY_WIDTH, DISPLAY_HEIGHT, QImage::Format_RGB16), ui(new Ui::MainWindow)
+{
ui->setupUi(this);
image.fill(Qt::black); //clear display buffer
currentScale = 1; //start with scale factor 1
@@ -44,13 +73,13 @@ void MainWindow::draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, u
{
QPainter painter(&(image));
painter.setPen(QColorFromRGB565(color));
- painter.drawLine(x1,y1,x2,y2);
+ painter.drawLine(x1, y1, x2, y2);
update();
}
void MainWindow::draw_pixel(uint16_t x, uint16_t y, uint16_t color)
{
- image.setPixel(x,y,QRgbFromRGB565(color));
+ image.setPixel(x, y, QRgbFromRGB565(color));
update();
}
@@ -64,31 +93,32 @@ void MainWindow::draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t
{
QPainter painter(&(image));
painter.setPen(QColorFromRGB565(color));
- painter.drawRect(qMin(x1,x2),qMin(y1,y2),abs((int)x2-(int)x1),abs((int)y2-(int)y1));
+ painter.drawRect(qMin(x1, x2), qMin(y1, y2), abs((int)x2 - (int)x1), abs((int)y2 - (int)y1));
update();
}
void MainWindow::fill_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
QPainter painter(&(image));
- painter.fillRect(qMin(x1,x2),qMin(y1,y2),abs((int)x2-(int)x1)+1,abs((int)y2-(int)y1)+1,QColorFromRGB565(color));
+ painter.fillRect(qMin(x1, x2), qMin(y1, y2), abs((int)x2 - (int)x1) + 1, abs((int)y2 - (int)y1) + 1, QColorFromRGB565(color));
update();
}
-void MainWindow::draw_bitmap_unscaled(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t *dat)
+void MainWindow::draw_bitmap_unscaled(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t* dat)
{
//Creating a new image and access it directly is faster than setPixel
- QImage img(width,height,QImage::Format_RGB32); //create a new image
+ QImage img(width, height, QImage::Format_RGB32); //create a new image
- for(int yi=0; yiwidgetDisplay->geometry().topLeft(),QSizeF(DISPLAY_WIDTH*currentScale,DISPLAY_HEIGHT*currentScale));
+ //Create a QRectF which represents the rectangle to draw the buffered image to
+ QRectF imgRect(ui->widgetDisplay->geometry().topLeft(), QSizeF(DISPLAY_WIDTH * currentScale, DISPLAY_HEIGHT * currentScale));
- painter.drawImage(imgRect,image); //draw buffer
- painter.setPen(QPen(Qt::green,2)); //set border color
- painter.drawRect(imgRect.adjusted(-1,-1,1,1)); //draw border
+ painter.drawImage(imgRect, image); //draw buffer
+ painter.setPen(QPen(Qt::green, 2)); //set border color
+ painter.drawRect(imgRect.adjusted(-1, -1, 1, 1)); //draw border
}
-void MainWindow::mousePressEvent(QMouseEvent *evt)
+void MainWindow::mousePressEvent(QMouseEvent* evt)
{
//the mouse was pressed
- checkAndSendEvent(evt->pos(),true);
+ checkAndSendEvent(evt->pos(), true);
}
-void MainWindow::mouseReleaseEvent(QMouseEvent *evt)
+void MainWindow::mouseReleaseEvent(QMouseEvent* evt)
{
//the mouse was released
- checkAndSendEvent(evt->pos(),false);
+ checkAndSendEvent(evt->pos(), false);
}
-void MainWindow::mouseMoveEvent(QMouseEvent *evt)
+void MainWindow::mouseMoveEvent(QMouseEvent* evt)
{
//the mouse was released
- checkAndSendEvent(evt->pos(),true);
+ checkAndSendEvent(evt->pos(), true);
}
-bool MainWindow::eventFilter(QObject *obj, QEvent *evt)
+bool MainWindow::eventFilter(QObject* obj, QEvent* evt)
{
- if(obj==ui->widgetDisplay) { //we received a redirect event from the target rectangle
- switch(evt->type()) {
- case QEvent::MouseMove: //it's a mouse move event
- {
- QMouseEvent* mouseEvent = static_cast(evt); //get mouse event
- QPoint p = (mouseEvent->pos()-QPoint(1,1))/currentScale; //calculate correct corrdinates (undo scale)
- if(p.x()txtMousePos->setText(QString("Mouse Position: (%1,%2)").arg(p.x()).arg(p.y()));
- }
+ if (obj == ui->widgetDisplay) { //we received a redirect event from the target rectangle
+ switch (evt->type()) {
+ case QEvent::MouseMove: { //it's a mouse move event
+ QMouseEvent* mouseEvent = static_cast(evt); //get mouse event
+ QPoint p = (mouseEvent->pos() - QPoint(1, 1)) / currentScale; //calculate correct corrdinates (undo scale)
+
+ if (p.x() < DISPLAY_WIDTH && p.y() < DISPLAY_HEIGHT) { //mouse position not out of bounds
+ //set mouse position text
+ ui->txtMousePos->setText(QString("Mouse Position: (%1,%2)").arg(p.x()).arg(p.y()));
}
- break;
- default: break;
}
- }
- return false;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return false;
}
@@ -177,15 +210,18 @@ MainWindow::~MainWindow()
void MainWindow::checkAndSendEvent(QPoint pos, bool down)
{
QPoint p = pos - ui->widgetDisplay->geometry().topLeft(); //make coordinate relative to target area (0,0)
- p/=currentScale; //undo scaling
- if(p.x()<0 || p.y()<0 || p.x() >= DISPLAY_WIDTH || p.y() >= DISPLAY_HEIGHT) return; //abort if out of bounds
+ p /= currentScale; //undo scaling
- touch_add_raw_event(p.x(),p.y(),down?TOUCH_DOWN:TOUCH_UP); //submit touch event to touch module (common)
+ if (p.x() < 0 || p.y() < 0 || p.x() >= DISPLAY_WIDTH || p.y() >= DISPLAY_HEIGHT) {
+ return; //abort if out of bounds
+ }
+
+ touch_add_raw_event(p.x(), p.y(), down ? TOUCH_DOWN : TOUCH_UP); //submit touch event to touch module (common)
}
void MainWindow::on_cboZoom_currentIndexChanged(int index)
{
- currentScale=index+1; //zoom factor 1 is the 0th entry, zoom factor 2 is the 1st entry, zoom factor 3 is the 2nd entry
+ currentScale = index + 1; //zoom factor 1 is the 0th entry, zoom factor 2 is the 1st entry, zoom factor 3 is the 2nd entry
update(); //force redraw
}
diff --git a/emulator/qt/mainwindow.h b/emulator/qt/mainwindow.h
index 7c0f845..719178a 100644
--- a/emulator/qt/mainwindow.h
+++ b/emulator/qt/mainwindow.h
@@ -1,3 +1,24 @@
+/**************************************************************************************************************************************
+* Project: discoverpixy
+* Website: https://github.com/t-moe/discoverpixy
+* Authors: Aaron Schmocker, Timo Lang
+* Institution: BFH Bern University of Applied Sciences
+* File: emulator/qt/mainwindow.h
+*
+* Version History:
+* Date Autor Email SHA Changes
+* 2015-04-03 timolang@gmail.com 51089aa Refactored Project Structure for use with emulator
+* 2015-04-03 timolang@gmail.com 1f2af9f Added more tft functions to common and emulator. Fixed eventloop.
+* 2015-04-03 timolang@gmail.com 1aa9194 Fixed Drawing of rects in Emulator. Got frames from pixy to emulator. Slooooow.
+* 2015-04-27 timolang@gmail.com 259d446 Added touch support to emulator. Implemented basic touch function.
+* 2015-04-27 aaron@duckpond.ch aed90ef Drawcircle added (emulator)
+* 2015-04-27 timolang@gmail.com e249fb2 Added font support
+* 2015-05-09 timolang@gmail.com c652b6b Improved Emulator Gui
+* 2015-05-25 timolang@gmail.com 911760e Added "Mouse Position"-Label to Emulator.
+* 2015-06-07 timolang@gmail.com 4b5768c Improved Comments in whole emulator. Finalized emulator section in docu.
+*
+**************************************************************************************************************************************/
+
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
@@ -5,7 +26,8 @@
#include
#include
-namespace Ui {
+namespace Ui
+{
class MainWindow;
}
@@ -14,33 +36,33 @@ class MainWindow : public QMainWindow
Q_OBJECT
public:
- explicit MainWindow(QWidget *parent = 0);
+ explicit MainWindow(QWidget* parent = 0);
void draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
- void draw_pixel(uint16_t x,uint16_t y,uint16_t color);
+ void draw_pixel(uint16_t x, uint16_t y, uint16_t color);
void clear(uint16_t color);
void draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
void fill_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
- void draw_bitmap_unscaled(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t *dat);
+ void draw_bitmap_unscaled(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t* dat);
void draw_circle(uint16_t x, uint16_t y, uint16_t r, uint16_t color);
void draw_char(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, QFont font, char c);
protected:
- bool eventFilter(QObject * obj , QEvent * env);
- void paintEvent(QPaintEvent * evt);
- void mousePressEvent(QMouseEvent* evt);
- void mouseReleaseEvent(QMouseEvent* evt);
- void mouseMoveEvent(QMouseEvent* evt);
+ bool eventFilter(QObject* obj , QEvent* env);
+ void paintEvent(QPaintEvent* evt);
+ void mousePressEvent(QMouseEvent* evt);
+ void mouseReleaseEvent(QMouseEvent* evt);
+ void mouseMoveEvent(QMouseEvent* evt);
~MainWindow();
private slots:
- void on_cboZoom_currentIndexChanged(int index); //slot that is called when the zoomlevel changed
+ void on_cboZoom_currentIndexChanged(int index); //slot that is called when the zoomlevel changed
private:
QImage image; //Display buffer
int currentScale; //current scale factor
void checkAndSendEvent(QPoint pos, bool down);
- Ui::MainWindow *ui;
+ Ui::MainWindow* ui;
};
#endif // MAINWINDOW_H
diff --git a/utils/genheader.sh b/utils/genheader.sh
index 26ee24b..b6145a7 100755
--- a/utils/genheader.sh
+++ b/utils/genheader.sh
@@ -2,6 +2,7 @@
echo "/**************************************************************************************************************************************"
echo "* Project: discoverpixy"
+echo "* Website: https://github.com/t-moe/discoverpixy"
echo "* Authors: Aaron Schmocker, Timo Lang"
echo "* Institution: BFH Bern University of Applied Sciences"
echo "* File: $1"