Merge remote-tracking branch 'origin/emulator' into dev_aaron

This commit is contained in:
id101010
2015-05-12 14:19:36 +02:00
43 changed files with 3751 additions and 74 deletions

2414
Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -2,15 +2,16 @@
#include "tft.h" #include "tft.h"
#include "system.h" #include "system.h"
#include "touch.h" #include "touch.h"
#include "screen_guitest.h" #include "screen_main.h"
#include "filesystem.h"
void app_init() { void app_init() {
system_init(); system_init();
tft_init(); tft_init();
touch_init(); touch_init();
filesystem_init();
gui_screen_navigate(get_screen_guitest()); gui_screen_navigate(get_screen_main());
} }

View File

@@ -1,2 +1,25 @@
#ifndef APP_H
#define APP_H
/**
* @defgroup app Application
* The App Module contains the effective, platform independent application.
*/
/*@{*/
/**
* Starts/Initializes the app
* This function should be called at the top of the main function of your platform
*/
void app_init(); void app_init();
/**
* Executes one cycle of the app
* Call this function repeatedly from a loop inside the main function
*/
void app_process(); void app_process();
/*@}*/
#endif /* APP_H */

View File

@@ -0,0 +1,174 @@
#include "screen_filetest.h"
#include "button.h"
#include "tft.h"
#include "filesystem.h"
#include <stdlib.h>
static BUTTON_STRUCT b_back;
static void b_back_cb(void* button) {
gui_screen_back();
}
static void image_test();
static void enter(void* screen) {
tft_clear(HEX(0xBABECD));
//Back button
b_back.base.x1=10; //Start X of Button
b_back.base.y1=200; //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");
*/
tft_draw_line(10,30,310,30,BLACK);
tft_print_line(10,18,BLUE,TRANSPARENT,0,"Name D H RO Date Time Size");
int y = 33;
DIRECTORY_STRUCT* dir = filesystem_dir_open(".");
if(dir==NULL) return;
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;
}
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_file_close(file);
image_test();
}
static void leave(void* screen) {
gui_button_remove(&b_back);
}
static void update(void* screen) {
}
static SCREEN_STRUCT screen = {
enter,
leave,
update
};
SCREEN_STRUCT* get_screen_filetest() {
return &screen;
}
static void image_test() {
//Source: http://stackoverflow.com/a/17040962/2606757
FILE_HANDLE* file = filesystem_file_open("cpu.bmp");
if(file==NULL) {
tft_print_line(10,180,BLUE,TRANSPARENT,0,"Could not open cpu.bmp");
return;
}
unsigned char info[54];
if(filesystem_file_read(file,info,54)!=F_OK) {
tft_print_line(10,180,BLUE,TRANSPARENT,0,"Could not read header of cpu.bmp");
filesystem_file_close(file);
return;
}
// extract image height and width from header
int width = *(int*)&info[18];
int height = *(int*)&info[22];
filesystem_file_seek(file,*(int*)&info[10]);
unsigned char data [width*4];
tft_draw_rectangle(100-1,160-1,100-1+width,160-1+height,BLACK);
for(int i = 0; i < height; i++)
{
filesystem_file_read(file,data,width*4);
for(int j = 0; j < width*4; j += 4)
{
unsigned char a = data[j];
unsigned char r = data[j+1];
unsigned char g = data[j+2];
unsigned char b = data[j+3];
if(a!=0) {
tft_draw_pixel(100+j/4,160+height-1-i,RGB(r,g,b));
}
}
}
filesystem_file_close(file);
}

View File

@@ -0,0 +1,22 @@
#include "screen.h"
/**
* @addtogroup screens
*/
/*@{*/
/**
* @defgroup filetest Filetest
* The File-Test Screen tests the filesystem module. It read/writes from/to files and shows a bitmap
*/
/*@{*/
/**
* Returns a pointer to the filetest screen
* \sa gui_screen_navigate
* @return
*/
SCREEN_STRUCT* get_screen_filetest();
/*@}@}*/

View File

@@ -62,6 +62,8 @@ static void enter(void* screen) {
//tft test //tft test
tft_draw_pixel(0,0,BLACK);
tft_draw_pixel(319,239,BLACK);
tft_draw_pixel(10,210,BLUE); tft_draw_pixel(10,210,BLUE);
tft_draw_pixel(12,210,BLUE); tft_draw_pixel(12,210,BLUE);
tft_draw_rectangle(40,100,60,235,BLUE); tft_draw_rectangle(40,100,60,235,BLUE);

View File

@@ -1,3 +1,23 @@
#include "screen.h" #include "screen.h"
/**
* @addtogroup screens
*/
/*@{*/
/**
* @defgroup guitest Guitest
* The Gui-Test Screen tests the gui and the tft module.
*/
/*@{*/
/**
* Returns a pointer to the guitest screen
* \sa gui_screen_navigate
* @return
*/
SCREEN_STRUCT* get_screen_guitest(); SCREEN_STRUCT* get_screen_guitest();
/*@}@}*/

View File

@@ -1,17 +1,22 @@
#include "screen_main.h" #include "screen_main.h"
#include "screen_guitest.h" #include "screen_guitest.h"
#include "screen_pixytest.h" #include "screen_pixytest.h"
#include "screen_filetest.h"
#include "button.h" #include "button.h"
#include "tft.h" #include "tft.h"
BUTTON_STRUCT b_guitest; BUTTON_STRUCT b_guitest;
BUTTON_STRUCT b_pixytest; BUTTON_STRUCT b_pixytest;
BUTTON_STRUCT b_filetest;
static void b_guitest_cb(void* button) { static void b_guitest_cb(void* button) {
gui_screen_navigate(get_screen_guitest()); gui_screen_navigate(get_screen_guitest());
} }
static void b_filetest_cb(void* button) {
gui_screen_navigate(get_screen_filetest());
}
static void b_pixytest_cb(void* button) { static void b_pixytest_cb(void* button) {
gui_screen_navigate(get_screen_pixytest()); gui_screen_navigate(get_screen_pixytest());
} }
@@ -33,7 +38,7 @@ static void enter(void* screen) {
gui_button_add(&b_guitest); //Register Button (and run the callback from now on) gui_button_add(&b_guitest); //Register Button (and run the callback from now on)
//button to reach pixy test //button to reach pixy test
b_pixytest.base.x1=200; //Start X of Button b_pixytest.base.x1=150; //Start X of Button
b_pixytest.base.y1=45; //Start Y of Button b_pixytest.base.y1=45; //Start Y of Button
b_pixytest.base.x2=AUTO; //b_pixytest.base.x1+160; //Auto Calculate X2 with String Width b_pixytest.base.x2=AUTO; //b_pixytest.base.x1+160; //Auto Calculate X2 with String Width
b_pixytest.base.y2=AUTO; //Auto Calculate Y2 with String Height b_pixytest.base.y2=AUTO; //Auto Calculate Y2 with String Height
@@ -44,6 +49,18 @@ static void enter(void* screen) {
b_pixytest.callback=b_pixytest_cb; //Call b_pixytest_cb as Callback b_pixytest.callback=b_pixytest_cb; //Call b_pixytest_cb as Callback
gui_button_add(&b_pixytest); //Register Button (and run the callback from now on) gui_button_add(&b_pixytest); //Register Button (and run the callback from now on)
//button to reach filesystem test
b_filetest.base.x1=240; //Start X of Button
b_filetest.base.y1=45; //Start Y of Button
b_filetest.base.x2=AUTO; //b_filetest.base.x1+160; //Auto Calculate X2 with String Width
b_filetest.base.y2=AUTO; //Auto Calculate Y2 with String Height
b_filetest.txtcolor=WHITE; //Set foreground color
b_filetest.bgcolor=HEX(0x501EA0); //Set background color (Don't take 255 or 0 on at least one channel, to make shadows possible)
b_filetest.font=0; //Select Font
b_filetest.text="File Test"; //Set Text (For formatted strings take sprintf)
b_filetest.callback=b_filetest_cb; //Call b_filetest_cb as Callback
gui_button_add(&b_filetest); //Register Button (and run the callback from now on)
} }
@@ -51,6 +68,7 @@ static void enter(void* screen) {
static void leave(void* screen) { static void leave(void* screen) {
gui_button_remove(&b_guitest); gui_button_remove(&b_guitest);
gui_button_remove(&b_pixytest); gui_button_remove(&b_pixytest);
gui_button_remove(&b_filetest);
} }
static void update(void* screen) { static void update(void* screen) {

View File

@@ -1,3 +1,34 @@
#include "screen.h" #include "screen.h"
/**
* @addtogroup app
*/
/*@{*/
/**
* @defgroup screens Screens
* The Screens of the application. \sa \ref screen
*/
/*@}*/
/**
* @addtogroup screens
*/
/*@{*/
/**
* @defgroup main Main
* The Main Screen is the start-screen for the application
*/
/*@{*/
/**
* Returns a pointer to the main screen
* \sa gui_screen_navigate
* @return
*/
SCREEN_STRUCT* get_screen_main(); SCREEN_STRUCT* get_screen_main();
/*@}@}*/

View File

@@ -10,14 +10,25 @@ static volatile bool pixy_connected = false;
static BUTTON_STRUCT b_back; static BUTTON_STRUCT b_back;
static BUTTON_STRUCT b_runstop;
static TOUCH_AREA_STRUCT a_area; static TOUCH_AREA_STRUCT a_area;
static void b_back_cb(void* button) { static void b_back_cb(void* button) {
gui_screen_back(); gui_screen_back();
} }
POINT_STRUCT pixy_pos;
POINT_STRUCT old_pos; static volatile bool pixy_running = false;
static bool old_pixy_running= false;
static void b_runstop_cb(void* button) {
pixy_running=!pixy_running;
}
static POINT_STRUCT pixy_pos;
static POINT_STRUCT old_pos;
static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction) { static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction) {
POINT_STRUCT p = touch_get_last_point(); POINT_STRUCT p = touch_get_last_point();
switch(triggeredAction) { switch(triggeredAction) {
@@ -68,6 +79,20 @@ static void enter(void* screen) {
b_back.callback=b_back_cb; //Call b_back_cb as Callback 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) gui_button_add(&b_back); //Register Button (and run the callback from now on)
//Back button
b_runstop.base.x1=60; //Start X of Button
b_runstop.base.y1=210; //Start Y of Button
b_runstop.base.x2=AUTO; //b_runstop.base.x1+160; //Auto Calculate X2 with String Width
b_runstop.base.y2=AUTO; //Auto Calculate Y2 with String Height
b_runstop.txtcolor=WHITE; //Set foreground color
b_runstop.bgcolor=HEX(0xAE1010); //Set runstopground color (Don't take 255 or 0 on at least one channel, to make shadows possible)
b_runstop.font=0; //Select Font
b_runstop.text="Run/Stop"; //Set Text (For formatted strings take sprintf)
b_runstop.callback=b_runstop_cb; //Call b_runstop_cb as Callrunstop
gui_button_add(&b_runstop); //Register Button (and run the callrunstop from now on)
//Area test //Area test
a_area.hookedActions = PEN_DOWN | PEN_MOVE | PEN_ENTER | PEN_UP | PEN_LEAVE; a_area.hookedActions = PEN_DOWN | PEN_MOVE | PEN_ENTER | PEN_UP | PEN_LEAVE;
a_area.x1 = 0; a_area.x1 = 0;
@@ -88,12 +113,14 @@ static void enter(void* screen) {
static void leave(void* screen) { static void leave(void* screen) {
gui_button_remove(&b_back); gui_button_remove(&b_back);
gui_button_remove(&b_runstop);
touch_unregister_area(&a_area); touch_unregister_area(&a_area);
} }
int pixy_led_test(); int pixy_led_test();
int pixy_frame_test(); int pixy_frame_test();
static void update(void* screen) { 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 :'( //Note: The only way to detect that pixy has been disconnected is if a command fails. There's no pixy_is_connected method yet :'(
@@ -110,19 +137,35 @@ static void update(void* screen) {
if(pixy_connected) { if(pixy_connected) {
pixy_service(); //Send/receive event data from/to pixy failed pixy_service(); //Send/receive event data from/to pixy failed
//Code for tests see below
if(pixy_led_test()!=0) {
pixy_connected=false;
}
if(pixy_frame_test()!=0) { if(pixy_frame_test()!=0) {
pixy_connected=false; pixy_connected=false;
} }
/*if(pixy_led_test()!=0) {
pixy_rcs_set_position(0,pixy_pos.x); pixy_connected=false;
pixy_rcs_set_position(1,pixy_pos.y); }*/
if(!pixy_running) {
pixy_rcs_set_position(0,pixy_pos.x);
pixy_rcs_set_position(1,pixy_pos.y);
}
if(pixy_running!=old_pixy_running) {
old_pixy_running=pixy_running;
if(pixy_running) { //start tracking
int32_t response;
int return_value;
return_value = pixy_command("runprog", INT8(2), END_OUT_ARGS, &response, END_IN_ARGS);
} else { //stop tracking
int32_t response;
int return_value;
return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);
}
}
//system_delay(500); //system_delay(500);
} }
} }

View File

@@ -1,3 +1,21 @@
#include "screen.h" #include "screen.h"
/**
* @addtogroup screens
*/
/*@{*/
/**
* @defgroup pixytest Pixytest
* The Pixy-Test Screen tests the pixy module.
*/
/*@{*/
/**
* Returns a pointer to the pixytest screen
* \sa gui_screen_navigate
* @return
*/
SCREEN_STRUCT* get_screen_pixytest(); SCREEN_STRUCT* get_screen_pixytest();
/*@}@}*/

View File

@@ -0,0 +1,38 @@
#include "filesystem.h"
#include "ll_filesystem.h"
bool filesystem_init() {
return ll_filesystem_init();
}
DIRECTORY_STRUCT* filesystem_dir_open(const char* path) {
return ll_filesystem_dir_open(path);
}
void filesystem_dir_close(DIRECTORY_STRUCT* dir) {
filesystem_dir_close(dir);
}
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);
}
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_write(FILE_HANDLE* handle, uint8_t* buf, uint32_t size) {
return ll_filesystem_file_write(handle,buf,size);
}

View File

@@ -0,0 +1,71 @@
#ifndef FILESYSTEM_H
#define FILESYSTEM_H
#include <stdbool.h>
#include <stdint.h>
typedef enum {
F_DIR=1,
F_RDO=2,
F_HID=4,
F_SYS=8,
F_ARC=16
} FILE_ATTRIBUTES;
typedef struct {
unsigned year : 7; //year from 1980 (0..127)
unsigned month: 4; //month (1..12)
unsigned day: 5; //day (1..31)
} FILE_DATE_STRUCT;
typedef struct {
unsigned hour : 5; //hour (0..23)
unsigned min: 6; //minute (0..59
unsigned sec: 5; //second/2 (0..29)
} FILE_TIME_STRUCT;
typedef struct {
uint32_t fsize; /* File size */
FILE_DATE_STRUCT fdate; /* Last modified date */
FILE_TIME_STRUCT ftime; /* Last modified time */
uint8_t fattrib; /* Attribute */
char* fname; /* File name */
} FILE_STRUCT;
typedef struct {
const char* path;
uint16_t num_files;
FILE_STRUCT* files;
} DIRECTORY_STRUCT;
typedef struct {
const char* fname;
uint32_t fpos;
uint32_t fsize;
} FILE_HANDLE;
typedef enum {
F_OK,
F_EOF,
F_EACCESS,
F_INVALIDPARAM,
F_DISKERROR
} FILE_STATUS;
bool filesystem_init();
DIRECTORY_STRUCT* filesystem_dir_open(const char* path);
void filesystem_dir_close(DIRECTORY_STRUCT* dir);
FILE_HANDLE* filesystem_file_open(const char* filename);
void filesystem_file_close(FILE_HANDLE* handle);
FILE_STATUS filesystem_file_seek(FILE_HANDLE* handle, uint32_t offset);
FILE_STATUS filesystem_file_read(FILE_HANDLE* handle, uint8_t* buf, uint32_t size);
FILE_STATUS filesystem_file_write(FILE_HANDLE* handle, uint8_t* buf, uint32_t size);
#endif /* FILESYSTEM_H */

View File

@@ -1,20 +1,70 @@
#ifndef BUTTON_H #ifndef BUTTON_H
#define BUTTON_H #define BUTTON_H
/**
* @defgroup gui Gui
* The Gui Module
*/
/*@{*/
/**
* @defgroup button Button
* The Button Gui-Element
*/
/*@{*/
#include "touch.h" #include "touch.h"
/**
* Prototype for Event Listeners (called when the button is pressed)
* @param button The pointer to the BUTTON_STRUCT where to corresponding Button was pressed
*/
typedef void (*BUTTON_CALLBACK)(void *button);
typedef void (*BUTTON_CALLBACK)(void *button); //!< Function pointer used...
/**
* Structure to configure the Button
*/
typedef struct { typedef struct {
TOUCH_AREA_STRUCT base; 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; uint16_t bgcolor; //!< The 16-bit background color of the button
BUTTON_CALLBACK callback; //Callback BUTTON_CALLBACK callback; //!< Callback
uint16_t txtcolor; uint16_t txtcolor; //!< The 16-bit text color
uint8_t font; uint8_t font; //!< The number of the font to use
const char *text; const char *text; //!< The label of the button
} BUTTON_STRUCT; } 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);
/*
bool guiAddBitmapButton(BITMAPBUTTON_STRUCT* button);
void guiRemoveBitmapButton(BITMAPBUTTON_STRUCT* button);
void guiRedrawBitmapButton(BITMAPBUTTON_STRUCT* button);
*/
/* /*
typedef struct { typedef struct {
TOUCH_AREA_STRUCT base; TOUCH_AREA_STRUCT base;
@@ -27,18 +77,8 @@ typedef struct {
*/ */
//Notice that the first 3 Members are Equal, so it's possible to cast it to a BUTTON_STRUCT even if it's a BITMAPBUTTON_STRUCT (when changeing only the first 3 Members). //Notice that the first 3 Members are Equal, so it's possible to cast it to a BUTTON_STRUCT even if it's a BITMAPBUTTON_STRUCT (when changeing only the first 3 Members).
#define AUTO 0
bool gui_button_add(BUTTON_STRUCT* button);
void gui_button_remove(BUTTON_STRUCT* button);
void gui_button_redraw(BUTTON_STRUCT* button);
/*
bool guiAddBitmapButton(BITMAPBUTTON_STRUCT* button);
void guiRemoveBitmapButton(BITMAPBUTTON_STRUCT* button);
void guiRedrawBitmapButton(BITMAPBUTTON_STRUCT* button);
*/
/*@}@}*/
#endif /* BUTTON_H */ #endif /* BUTTON_H */

View File

@@ -1,3 +1,17 @@
#ifndef CHECKBOX_H
#define CHECKBOX_H
/**
* @addtogroup gui
*/
/*@{*/
/**
* @defgroup checkbox Checkbox
* The Checkbox Gui-Element
*/
/*@{*/
typedef void (*CHECKBOX_CALLBACK)(void *checkbox, bool checked); //!< Function pointer used... typedef void (*CHECKBOX_CALLBACK)(void *checkbox, bool checked); //!< Function pointer used...
typedef struct { typedef struct {
@@ -13,3 +27,7 @@ void gui_checkbox_remove(CHECKBOX_STRUCT* checkbox);
void gui_checkbox_update(CHECKBOX_STRUCT* checkbox); void gui_checkbox_update(CHECKBOX_STRUCT* checkbox);
void gui_checkbox_redraw(CHECKBOX_STRUCT* checkbox); void gui_checkbox_redraw(CHECKBOX_STRUCT* checkbox);
#define CHECKBOX_WIN_FG_COLOR RGB(32,161,34) #define CHECKBOX_WIN_FG_COLOR RGB(32,161,34)
/*@}@}*/
#endif /* CHECKBOX_H */

View File

@@ -1,3 +1,18 @@
#ifndef NUMUPDOWN_H
#define NUMUPDOWN_H
/**
* @addtogroup gui
*/
/*@{*/
/**
* @defgroup numupdown NummericUpDown
* The NummericUpDown Gui Element
*/
/*@{*/
#include "button.h" #include "button.h"
typedef void (*NUMUPDOWN_CALLBACK)(void *numupdown, int16_t value); //!< Function pointer used... typedef void (*NUMUPDOWN_CALLBACK)(void *numupdown, int16_t value); //!< Function pointer used...
@@ -20,3 +35,7 @@ bool gui_numupdown_add(NUMUPDOWN_STRUCT* numupdown);
void gui_numupdown_remove(NUMUPDOWN_STRUCT* numupdown); void gui_numupdown_remove(NUMUPDOWN_STRUCT* numupdown);
void gui_numupdown_update(NUMUPDOWN_STRUCT* numupdown); void gui_numupdown_update(NUMUPDOWN_STRUCT* numupdown);
void gui_numupdown_redraw(NUMUPDOWN_STRUCT* numupdown); void gui_numupdown_redraw(NUMUPDOWN_STRUCT* numupdown);
/*@}@}*/
#endif /* NUMUPDOWN_H */

View File

@@ -1,8 +1,8 @@
#include "screen.h" #include "screen.h"
static volatile SCREEN_STRUCT* screen_list = NULL; static SCREEN_STRUCT* screen_list = NULL;
static volatile SCREEN_STRUCT* screen_current = NULL; static SCREEN_STRUCT* screen_current = NULL;
static volatile SCREEN_STRUCT* screen_goto = NULL; static volatile SCREEN_STRUCT* screen_goto = NULL;
SCREEN_STRUCT* gui_screen_get_current() { SCREEN_STRUCT* gui_screen_get_current() {
@@ -11,7 +11,7 @@ SCREEN_STRUCT* gui_screen_get_current() {
void gui_screen_update() { void gui_screen_update() {
if(screen_goto!=NULL) { //we received the task to switch the screen if(screen_goto!=NULL) { //we received the task to switch the screen
SCREEN_STRUCT* go = screen_goto; //Backup volatile variable SCREEN_STRUCT* go = (SCREEN_STRUCT*) screen_goto; //Backup volatile variable
screen_goto=NULL; screen_goto=NULL;
if(go->next!=NULL) { //we're going back if(go->next!=NULL) { //we're going back
if(go->next!=screen_current) return; //list corrupted? if(go->next!=screen_current) return; //list corrupted?
@@ -26,7 +26,7 @@ void gui_screen_update() {
} }
} }
go->on_enter(go); go->on_enter(go);
screen_current = go; screen_current =go;
} }
if(screen_current!=NULL) { //A screen has been set if(screen_current!=NULL) { //A screen has been set

View File

@@ -1,6 +1,16 @@
#ifndef SCREEN_H #ifndef SCREEN_H
#define SCREEN_H #define SCREEN_H
/**
* @addtogroup gui
*/
/*@{*/
/**
* @defgroup screen Screen
* The Screen Submodule
*/
/*@{*/
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
@@ -30,4 +40,6 @@ SCREEN_STRUCT* gui_screen_get_current();
//Updates/switches the screens. Call this from the app main loop, as fast as you can. //Updates/switches the screens. Call this from the app main loop, as fast as you can.
void gui_screen_update(); void gui_screen_update();
/*@}@}*/
#endif /* SCREEN_H */ #endif /* SCREEN_H */

View File

@@ -0,0 +1,11 @@
#include "filesystem.h"
bool ll_filesystem_init();
DIRECTORY_STRUCT* ll_filesystem_dir_open(const char* path);
void ll_filesystem_dir_close(DIRECTORY_STRUCT* dir);
FILE_HANDLE* ll_filesystem_file_open(const char* filename);
void ll_filesystem_file_close(FILE_HANDLE* handle);
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);
FILE_STATUS ll_filesystem_file_write(FILE_HANDLE* handle, uint8_t* buf, uint32_t size);

View File

@@ -1,7 +1,38 @@
#ifndef SYSTEM_H
#define SYSTEM_H
/**
* @defgroup system System
* The System Module provides access to delay functions, leds and provides a system init function
*/
/*@{*/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
/**
* Initializes the system. Call this method at the start of your app_init() function and before using any system_* functions
* @return true on success
*/
bool system_init(); bool system_init();
/**
* Sleeps for a certain amount of time
* @param msec The number of milliseconds to sleep
*/
void system_delay(uint32_t msec); void system_delay(uint32_t msec);
/**
* Executes pending system events (like handling usb, timers etc). Call this somewhere in app_process().
*/
void system_process(); void system_process();
/**
* Toggles a Status Led. Use this function for debugging or to show activity
*/
void system_toggle_led(); void system_toggle_led();
/*@}*/
#endif /* SYSTEM_H */

View File

@@ -2,6 +2,7 @@
#include "ll_tft.h" #include "ll_tft.h"
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h>
bool tft_init() { bool tft_init() {
return ll_tft_init(); return ll_tft_init();

View File

@@ -1,29 +1,159 @@
#ifndef TFT_H
#define TFT_H
/**
* @defgroup tft TFT
* The TFT Modul provides access to the display
*/
/**
* @addtogroup tft
*/
/*@{*/
#include<stdbool.h> #include<stdbool.h>
#include<stdint.h> #include<stdint.h>
/**
* Creates a 16bit color from 8bit * 3 colors (r,g,b)
* @return
*/
#define RGB(r,g,b) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | (((b) & 0xF8) >> 3)) #define RGB(r,g,b) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | (((b) & 0xF8) >> 3))
#define RED RGB(255,0,0) #define RED RGB(255,0,0)
#define GREEN RGB(0,255,0) #define GREEN RGB(0,255,0)
#define BLUE RGB(0,0,255) #define BLUE RGB(0,0,255)
#define WHITE 0xF7BE #define WHITE 0xF7BE
#define BLACK RGB(0,0,0) #define BLACK RGB(0,0,0)
/**
* Creates a 16bit color from a 24bit hex rgb color code
* @return
*/
#define HEX(h) (RGB(((h)>>16),((h)>>8),(h))) #define HEX(h) (RGB(((h)>>16),((h)>>8),(h)))
/**
* Transparent color
* @return
*/
#define TRANSPARENT ((uint16_t)0x80C2) #define TRANSPARENT ((uint16_t)0x80C2)
/**
* Initializes the display.
* Call this method before using any tft_* functions
* @return true on success
*/
bool tft_init(); bool tft_init();
/**
* Clears the entire display with the given color. Overpaints everything which was there before.
* @param color The 16-bit color to clear the display with.
*/
void tft_clear(uint16_t color); void tft_clear(uint16_t color);
/**
* Draws a line onto the display. The pixels specified by start/end point are inclusive!
* @param x1 The x-Coordinate of the start-point
* @param y1 The y-Coordinate of the start-point
* @param x2 The x-Coordinate of the end-point
* @param y2 The y-Coordinate of the end-point
* @param color The 16-bit color to draw the line with
*/
void tft_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); void tft_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
/**
* Draws a pixel onto the display.
* @param x The x-Coordinate of the pixel
* @param y The y-Coordinate of the pixel
* @param 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.
* The outline is one pixel wide and goes through the specified start and endpoint.
* @param x1 The x-Coordinate of the start-point
* @param y1 The y-Coordinate of the start-point
* @param x2 The x-Coordinate of the end-point
* @param y2 The y-Coordinate of the end-point
* @param 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
* @param x1 The x-Coordinate of the start-point
* @param y1 The y-Coordinate of the start-point
* @param x2 The x-Coordinate of the end-point
* @param y2 The y-Coordinate of the end-point
* @param 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.
* The bitmap must be provided as an array of 16-bit colors
* @param x The x-coordinate of the top-left corner to draw the bitmap at
* @param y The y-coordinate of the top-left corner to draw the bitmap at
* @param width The width of the bitmap in pixels
* @param height The height of the bitmap in pixels
* @param dat A pointer to a uint16_t array containing the colors for each pixel. Starting in the topleft and going from left to right, line by line.
*/
void tft_draw_bitmap_unscaled(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t* dat); void tft_draw_bitmap_unscaled(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t* dat);
/**
* Draws the outline of a circle onto the display
* @param x The x-Coordinate of the center point
* @param y The y-Coordinate of the center point
* @param r The Radius in Pixels
* @param color The 16-Bit color to draw the circle with
*/
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);
/**
* Queries the number of available fonts
* @return
*/
uint8_t tft_num_fonts(); uint8_t tft_num_fonts();
/**
* Get the height of a font
* @param fontnum The number of the font, from 0 .. (num_fonts -1)
* @return The height in pixel
*/
uint8_t tft_font_height(uint8_t fontnum); uint8_t tft_font_height(uint8_t fontnum);
/**
* Get the width of a font
* @param fontnum The number of the font, from 0 .. (num_fonts -1)
* @return The width in pixel
*/
uint8_t tft_font_width(uint8_t fontnum); uint8_t tft_font_width(uint8_t fontnum);
/**
* Prints a unformatted/preformatted string onto the display
* @param x The x-Coordinate of the Top-Left corner where the text should be drawn
* @param y The y-Coordinate of the Top-Left corner where the text should be drawn
* @param color The 16-bit foreground color of the text
* @param bgcolor The 16-bit background color of the text. You may pass TRANSPARENT as Color
* @param font The Fontnum to use for drawing
* @param text The text to draw
*/
void tft_print_line(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t font, const char* text); void tft_print_line(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t font, const char* text);
/**
* Prints a formatted text (like printf) onto the display
* @param x The x-Coordinate of the Top-Left corner where the text should be drawn
* @param y The y-Coordinate of the Top-Left corner where the text should be drawn
* @param color The 16-bit foreground color of the text
* @param bgcolor The 16-bit background color of the text. You may pass TRANSPARENT as Color
* @param font The Fontnum to use for drawing
* @param format The format string (like printf)
*/
void tft_print_formatted(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t font, const char* format, ...); void tft_print_formatted(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t font, const char* format, ...);
/*@}*/
#endif /* TFT_H */

View File

@@ -1,39 +1,116 @@
#ifndef TOUCH_H #ifndef TOUCH_H
#define TOUCH_H #define TOUCH_H
/**
* @defgroup touch Touch
* The Touch module provides access to the touch controller, and executes a callback if a certain region is touched
*/
/**
* @addtogroup touch
*/
/*@{*/
#include<stdbool.h> #include<stdbool.h>
#include<stdint.h> #include<stdint.h>
/**
Enum to describe the current Touch State. \sa touch_add_raw_event
*/
typedef enum {
TOUCH_UP, //!< The display is currently not touched
TOUCH_DOWN //!< The display is currently touched at some point
} TOUCH_STATE ;
typedef enum {TOUCH_UP,TOUCH_DOWN} TOUCH_STATE ; /**
typedef enum {NONE=0x00,PEN_DOWN=0x01, PEN_UP=0x02, PEN_ENTER=0x04, PEN_LEAVE=0x08,PEN_MOVE=0x10} TOUCH_ACTION; * Enum to describe the hooked actions for which you want to receive events for.
* You can OR-combine them. \sa touch_register_area
*/
typedef enum {
NONE=0x00, //!< Do not receive any events
PEN_DOWN=0x01, //!< Receive an event when the pen goes down inside the region
PEN_UP=0x02, //!< Receive an event when the pen goes up inside the region
PEN_ENTER=0x04, //!< Receive an event when the pen enters the region (pen was down before)
PEN_LEAVE=0x08, //!< Receive an event when the pen leaves the region (pen was inside region before)
PEN_MOVE=0x10 //!< Receive an event when the pen moves inside the region (pen is down)
} TOUCH_ACTION;
/**
* Prototype for Event Listeners (called for every occurring, hooked action)
* @param touchArea The pointer to the TOUCH_AREA_STRUCT in which the event occurred
* @param triggeredAction The Action which occurred
*/
typedef void (*TOUCH_CALLBACK)(void* touchArea, TOUCH_ACTION triggeredAction); typedef void (*TOUCH_CALLBACK)(void* touchArea, TOUCH_ACTION triggeredAction);
/**
* Structure to configure a Touch Area
*/
typedef struct { typedef struct {
TOUCH_ACTION hookedActions; //Actions to listen to TOUCH_ACTION hookedActions; //!< Actions to listen to
uint16_t x1; //Top Left X Coordiate of Area uint16_t x1; //!< Top Left X-Coordinate of Area
uint16_t y1; //Top Left Y Coordiate of Area uint16_t y1; //!< Top Left Y-Coordinate of Area
uint16_t x2; //Bottom Right X Coordiate of Area uint16_t x2; //!< Bottom Right X-Coordinate of Area
uint16_t y2; //Bottom Right Y Coordiate of Area uint16_t y2; //!< Bottom Right Y-Coordinate of Area
TOUCH_CALLBACK callback; //Callback TOUCH_CALLBACK callback; //!< Callback
uint8_t flags; //Internal Used, don't change uint8_t flags; //!< For internal Used, don't change, don't initialize
} TOUCH_AREA_STRUCT; } TOUCH_AREA_STRUCT;
/**
* Struct which represents a 2D point on the display
*/
typedef struct { typedef struct {
uint16_t x; uint16_t x; //!< The X-Coordinate of the point
uint16_t y; uint16_t y; //!< The Y-Coordinate of the point
} POINT_STRUCT; } POINT_STRUCT;
/**
* Initializes the Touch Controller.
* Call this method before using any touch_* functions
* @return true on success
*/
bool touch_init(); bool touch_init();
/**
* Processes a native touch event.
* Call this function when the pen goes down (\ref TOUCH_DOWN), when it moves (\ref TOUCH_DOWN) and also when it goes up again (\ref TOUCH_UP)!
* It's safe to call this function from an (SPI)-Interrupt.
* @param x The x-Coordinate of the touch event
* @param y The y-Coordinate of the touch event
* @param state Whether the pen is up or down
* @return True on success
*/
bool touch_add_raw_event(uint16_t x, uint16_t y,TOUCH_STATE state); bool touch_add_raw_event(uint16_t x, uint16_t y,TOUCH_STATE state);
/**
* Checks whether or not we have memory to manage and track additional \p num TOUCH_AREA_STRUCT%s
* @param num The number of touch areas you would like to allocate
* @return True if there's enough memory to allocate num TOUCH_AREAs
*/
bool touch_have_empty(unsigned char num); bool touch_have_empty(unsigned char num);
/**
* Registers a new touch Area. You will receive events for this area from now on.
* @param area A pointer to the configured TOUCH_AREA_STRUCT
* @return True if everything was successful and the corresponding Touch Area will be monitored from now on
*/
bool touch_register_area(TOUCH_AREA_STRUCT* area); bool touch_register_area(TOUCH_AREA_STRUCT* area);
/**
* Unregisters a touch area. You will no longer receive events for this area
* @param area A pointer to the TOUCH_AREA_STRUCT instance
*/
void touch_unregister_area(TOUCH_AREA_STRUCT* area); void touch_unregister_area(TOUCH_AREA_STRUCT* area);
/**
* Gets the last touched point
* @return The Coordinates of the last touched points
*/
POINT_STRUCT touch_get_last_point(); POINT_STRUCT touch_get_last_point();
/*@}*/
#endif /* TOUCH_H */ #endif /* TOUCH_H */

View File

@@ -0,0 +1,38 @@
#include "ll_filesystem.h"
#include <stdio.h>
bool ll_filesystem_init() {
return false;
}
DIRECTORY_STRUCT* ll_filesystem_dir_open(const char* path) {
return NULL;
}
void ll_filesystem_dir_close(DIRECTORY_STRUCT* dir) {
}
FILE_HANDLE* ll_filesystem_file_open(const char* filename) {
return NULL;
}
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_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;
}

View File

@@ -604,7 +604,8 @@ void ll_tft_draw_char(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor,
bool enTrans = 0; bool enTrans = 0;
ll_tft_set_window(x, y, x + width - 1, y + height - 1); ll_tft_set_window(x, y, x + width - 1, y + height - 1);
ll_tft_set_cursor(x, y);
for(cnt = (width / 8) * height; cnt > 0; cnt--){ for(cnt = (width / 8) * height; cnt > 0; cnt--){
for(bitm = 0x80; bitm > 0; bitm >>= 1){ for(bitm = 0x80; bitm > 0; bitm >>= 1){
if((font[ind]) & bitm){ if((font[ind]) & bitm){

1
doc/.gitignore vendored
View File

@@ -1 +1,2 @@
*.*~ *.*~
html/

67
emulator/.cproject Normal file
View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1806077868">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.1806077868" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.1806077868" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.1806077868.2077011731" name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.base.1150843993" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.378935317" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
<builder id="cdt.managedbuild.target.gnu.builder.base.1833415788" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.367957313" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.507131523" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1786829669" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.353743385" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
<option id="gnu.c.compiler.option.include.paths.1790787810" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/discoverpixy emulator/common}&quot;"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1079325095" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1526738848" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.196111216" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.583908749" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.assembler.base.1121015218" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1174397664" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="common" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="common"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="discoverpixy emulator.null.652385621" name="discoverpixy emulator"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.1806077868;cdt.managedbuild.toolchain.gnu.base.1806077868.2077011731;cdt.managedbuild.tool.gnu.c.compiler.base.353743385;cdt.managedbuild.tool.gnu.c.compiler.input.1079325095">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.1806077868;cdt.managedbuild.toolchain.gnu.base.1806077868.2077011731;cdt.managedbuild.tool.gnu.cpp.compiler.base.507131523;cdt.managedbuild.tool.gnu.cpp.compiler.input.1786829669">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
</cproject>

34
emulator/.project Normal file
View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>discoverpixy emulator</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>common</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/common</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="cdt.managedbuild.toolchain.gnu.base.1806077868" name="Default">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser" keep-relative-paths="false" name="CDT GCC Build Output Parser" parameter="(gcc)|([gc]\+\+)|(clang)" prefer-non-shared="true"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
</extension>
</configuration>
</project>

View File

BIN
emulator/emulated/cpu.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

View File

View File

@@ -0,0 +1 @@
Hallo Test 1241

View File

@@ -0,0 +1 @@
hallo welt

View File

@@ -15,14 +15,16 @@ SOURCES += \
main.cpp \ main.cpp \
ll_tft.cpp \ ll_tft.cpp \
ll_system.cpp \ ll_system.cpp \
ll_touch.cpp ll_touch.cpp \
ll_filesystem.cpp
HEADERS += \ HEADERS += \
mainwindow.h \ mainwindow.h \
INCLUDEPATH+= ../../common/lowlevel/ \ INCLUDEPATH+= ../../common/lowlevel/ \
../../common/touch/ \ ../../common/touch/ \
../../common/tft/ ../../common/tft/ \
../../common/filesystem
FORMS += \ FORMS += \

View File

@@ -0,0 +1,181 @@
extern "C" {
#include "ll_filesystem.h"
}
#include <QFile>
#include <QDir>
#include <QDebug>
#include <QFileInfoList>
#include <QDateTime>
QDir rootdir ("./emulated");
bool ll_filesystem_init() {
if(!rootdir.exists()) {
qWarning() << "Filesystem can not be emulated because the 'emulated' folder does not exist";
return false;
}
return true;
}
DIRECTORY_STRUCT* ll_filesystem_dir_open(const char* path) {
QDir d(rootdir);
d.cd(path);
if(!d.exists()) {
return NULL;
}
DIRECTORY_STRUCT* directory = new DIRECTORY_STRUCT();
QFileInfoList entries = d.entryInfoList(QDir::NoDotAndDotDot|QDir::Files|QDir::Dirs|QDir::Readable|QDir::Writable|QDir::Hidden|QDir::System);
directory->path = path;
directory->num_files = entries.count();
directory->files = new FILE_STRUCT[directory->num_files];
for(int i=0; i<entries.count(); i++){
QFileInfo fi = entries.at(i);
FILE_STRUCT* entry = &(directory->files[i]);
entry->fattrib = 0;
entry->fname = new char[fi.fileName().length()+1];
strcpy(entry->fname,fi.fileName().toStdString().c_str());
if(fi.isDir()) {
entry->fattrib|=F_DIR;
entry->fsize = 0;
} else {
entry->fsize = fi.size();
}
if(fi.isHidden()) {
entry->fattrib|=F_HID;
}
if(!fi.isWritable()) {
entry->fattrib|=F_RDO;
}
QDateTime dt = fi.lastModified();
entry->fdate.year = dt.date().year()-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;
}
return directory;
}
void ll_filesystem_dir_close(DIRECTORY_STRUCT* dir) {
if(dir!=NULL) {
for(int i=0; i<dir->num_files; i++) {
delete dir->files[i].fname;
}
delete[] dir->files;
delete dir;
}
}
struct QT_FILE_HANDLE : FILE_HANDLE {
QFile* file;
};
FILE_HANDLE* ll_filesystem_file_open(const char* filename) {
if(!rootdir.exists()) {
return NULL;
}
QString filepath = rootdir.absoluteFilePath(filename);
QFile* f = new QFile(filepath);
if(!f->exists()) {
return NULL;
}
if(!f->open(QFile::ReadWrite)) {
return NULL;
}
QT_FILE_HANDLE* fh = new QT_FILE_HANDLE();
fh->file = f;
fh->fname = filename;
fh->fpos =0;
fh->fsize = f->size();
return fh;
}
void ll_filesystem_file_close(FILE_HANDLE* handle) {
if(handle!=NULL) {
QT_FILE_HANDLE* fh = static_cast<QT_FILE_HANDLE*>(handle);
if(fh->file->isOpen()) {
fh->file->close();
}
delete fh;
}
}
FILE_STATUS ll_filesystem_file_seek(FILE_HANDLE* handle, uint32_t offset) {
if(handle==NULL) {
return F_INVALIDPARAM;
}
QT_FILE_HANDLE* fh = static_cast<QT_FILE_HANDLE*>(handle);
if(!fh->file->isOpen()) {
return F_DISKERROR;
}
if(offset>=fh->file->size()) {
return F_INVALIDPARAM;
}
if(fh->file->seek(offset)) {
fh->fpos = offset;
return F_OK;
} else {
return F_DISKERROR;
}
}
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<QT_FILE_HANDLE*>(handle);
if(!fh->file->isOpen()) {
return F_DISKERROR;
}
if(!fh->file->isReadable()) {
return F_EACCESS;
}
qint64 bytesRead = fh->file->read((char*)buf,size);
if(bytesRead<0) {
return F_DISKERROR;
}
fh->fpos+=bytesRead;
if(bytesRead!=size) {
return F_EOF;
} else {
return F_OK;
}
}
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<QT_FILE_HANDLE*>(handle);
if(!fh->file->isOpen()) {
return F_DISKERROR;
}
if(!fh->file->isWritable()) {
return F_EACCESS;
}
qint64 bytesWritten = fh->file->write((char*)buf,size);
if(bytesWritten<0) {
return F_DISKERROR;
}
fh->fpos+=bytesWritten;
if(bytesWritten!=size) {
return F_EOF;
} else {
return F_OK;
}
}

View File

@@ -15,6 +15,7 @@ void ll_system_delay(uint32_t msec) {
void ll_system_process() { void ll_system_process() {
QApplication::processEvents(); QApplication::processEvents();
QThread::msleep(1);
} }
void ll_system_toggle_led() { void ll_system_toggle_led() {

View File

@@ -12,8 +12,6 @@ extern "C" {
#define DISPLAY_WIDTH 320 #define DISPLAY_WIDTH 320
#define DISPLAY_HEIGHT 240 #define DISPLAY_HEIGHT 240
#define DISPLAY_X 10
#define DISPLAY_Y 10
QColor QColorFromRGB565(uint16_t color) { QColor QColorFromRGB565(uint16_t color) {
@@ -35,6 +33,7 @@ QRgb QRgbFromRGB565(uint16_t color) {
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); ui->setupUi(this);
image.fill(Qt::black); image.fill(Qt::black);
currentScale = 1;
} }
void MainWindow::draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) void MainWindow::draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
@@ -134,9 +133,13 @@ void MainWindow::paintEvent(QPaintEvent *)
//render_mutex.lock(); //render_mutex.lock();
QPainter painter(this); QPainter painter(this);
painter.drawImage(DISPLAY_X,DISPLAY_Y,image); QRectF imgRect (ui->widgetDisplay->geometry().topLeft(),QSizeF(DISPLAY_WIDTH*currentScale,DISPLAY_HEIGHT*currentScale));
painter.drawImage(imgRect,image);
painter.setPen(QPen(Qt::green,2)); painter.setPen(QPen(Qt::green,2));
painter.drawRect(DISPLAY_X-1,DISPLAY_Y-1,DISPLAY_WIDTH+2,DISPLAY_HEIGHT+2); painter.drawRect(imgRect.adjusted(-1,-1,1,1));
//render_mutex.unlock(); //render_mutex.unlock();
} }
@@ -167,7 +170,8 @@ MainWindow::~MainWindow()
void MainWindow::checkAndSendEvent(QPoint pos, bool down) void MainWindow::checkAndSendEvent(QPoint pos, bool down)
{ {
QPoint p = pos - QPoint(DISPLAY_X,DISPLAY_Y); QPoint p = pos - ui->widgetDisplay->geometry().topLeft();
p/=currentScale;
if(p.x()<0 || p.y()<0 || p.x() >= DISPLAY_WIDTH || p.y() >= DISPLAY_HEIGHT) return; if(p.x()<0 || p.y()<0 || p.x() >= DISPLAY_WIDTH || p.y() >= DISPLAY_HEIGHT) return;
//qDebug() << down << p; //qDebug() << down << p;
@@ -175,3 +179,9 @@ void MainWindow::checkAndSendEvent(QPoint pos, bool down)
touch_add_raw_event(p.x(),p.y(),down?TOUCH_DOWN:TOUCH_UP); touch_add_raw_event(p.x(),p.y(),down?TOUCH_DOWN:TOUCH_UP);
} }
void MainWindow::on_cboZoom_currentIndexChanged(int index)
{
currentScale=index+1;
update();
}

View File

@@ -31,9 +31,13 @@ protected:
void mouseMoveEvent(QMouseEvent* evt); void mouseMoveEvent(QMouseEvent* evt);
~MainWindow(); ~MainWindow();
private slots:
void on_cboZoom_currentIndexChanged(int index);
private: private:
//QMutex render_mutex; //QMutex render_mutex;
QImage image; QImage image;
int currentScale;
void checkAndSendEvent(QPoint pos, bool down); void checkAndSendEvent(QPoint pos, bool down);
Ui::MainWindow *ui; Ui::MainWindow *ui;

View File

@@ -6,26 +6,102 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>339</width> <width>980</width>
<height>263</height> <height>778</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>DiscoverPixy Emulator</string> <string>DiscoverPixy Emulator</string>
</property> </property>
<widget class="QWidget" name="centralwidget"/> <widget class="QWidget" name="centralwidget">
<widget class="QMenuBar" name="menubar"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="geometry"> <item>
<rect> <layout class="QHBoxLayout" name="horizontalLayout">
<x>0</x> <item>
<y>0</y> <widget class="QLabel" name="label">
<width>339</width> <property name="text">
<height>19</height> <string>Zoom</string>
</rect> </property>
</property> </widget>
</item>
<item>
<widget class="QComboBox" name="cboZoom">
<item>
<property name="text">
<string>1x</string>
</property>
</item>
<item>
<property name="text">
<string>2x</string>
</property>
</item>
<item>
<property name="text">
<string>3x</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnExit">
<property name="text">
<string>Exit</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widgetDisplay" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget> </widget>
<widget class="QStatusBar" name="statusbar"/>
</widget> </widget>
<resources/> <resources/>
<connections/> <connections>
<connection>
<sender>btnExit</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>652</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>351</x>
<y>244</y>
</hint>
</hints>
</connection>
</connections>
</ui> </ui>

15
genheader.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/bash
echo "/**************************************************************************************************************************************"
echo "* Project: discoverpixy"
echo "* Authors: Aaron Schmocker, Timo Lang"
echo "* Institution: BFH Bern University of Applied Sciences"
echo "* File: $1"
echo "*"
echo "* Version History:"
echo "* Date Autor Email SHA Changes"
git log --pretty=format:"* %ad%x09%ae%x09%h%x09%s" --date=short --date-order --no-merges --reverse $1 | grep -v -i "fileheader"
echo "*"
echo "**************************************************************************************************************************************/"

19
updateheaders.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/bash
FILES=`find common/ emulator/ discovery/ -name "*.c" -or -name "*.h" -or -name "*.cpp" | grep -v libs | grep -v /pixy/`
for FILE in $FILES; do
echo "Adding Header to $FILE"
#remove old header
CONTENT=$(perl -0777 -pe 's%^/\*.*?discoverpixy.*?\*/%%igs' $FILE)
#add new header
./genheader.sh $FILE > $FILE
#append file content
echo "$CONTENT" >> $FILE
done