diff --git a/include/BTKOM.h b/include/BTKOM.h index c37402c..f8c9392 100644 --- a/include/BTKOM.h +++ b/include/BTKOM.h @@ -3,9 +3,8 @@ extern "C"{ #include #include #include "MonochromeLib.h" - #include "syscall.h" #include "libfx.h" } -#include "bluetooth.h" +#include "libJelling/libJelling.h" \ No newline at end of file diff --git a/include/bluetooth.h b/include/bluetooth.h deleted file mode 100644 index 2ab29f7..0000000 --- a/include/bluetooth.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * AUTHOR : Xavier Bruni - * - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * As long as you retain this notice you can do whatever you want with this - * stuff. If we meet some day, and you think this stuff is worth it, you can - * buy me a beer in return. - * ---------------------------------------------------------------------------- - */ - -extern "C"{ - #include "MonochromeLib.h" - #include "syscall.h" - #include - #include - #include - #include "libfx.h" -} - - -/* -This bluetooth library is working with the 3-pin port of your calculator. -This library is compatible with SuperH-3 and SuperH-4 processor : -This include : Graph 35+, 75, 85 & 95. -This library has been written for the following bluetooth module : HC-05, HC-06 -RAM can contain approximately 50KO of data. Each message can't do more than 32KO -You can't send more than 1ko -including header- from your smartphone to the calculator. In fact, the reception buffer has a size of 1ko max. -Without the header : 1000 - 48 = 952o -for sending : 256-48 = 208 -If the 32 ko buffer is full, it will return a FUL packet. -*/ - -/* -How does Bluetooth header have to look like in a Message: - -- (1) time : 19 bytes (YYYY-MM-DD-HH-MM-SS) -- (2) type : 3 bytes (3*char) -- (3) ID : 4 bytes (unsigned int) -- (4) sender : 10 bytes (10*char) -- (5) total length of the message (in bytes), headers not included : 4 bytes (unsigned int) -- (6) total length of this packet (in bytes), headers not included : 4 bytes (unsigned int) -- (7) part of the message / number of part : 2 bytes (short unsigned int) / 2 bytes (short unsigned int) - -Total : 48 bytes. -Length must contain the null byte ! Null byte must be at the end of the message. - -(2) type can be : -- RQT : request -- ASW : answer to a request -- ACK : acknowledgment. packet received. -- MIS : missing packet -- FUL : full reception buffer or RAM buffer or precedent message unread. It sends the ID of last message read. -- ERR : error. see error code in message content. -- HED : incorrect header -- END : terminate the connection. - -Those are classic types. You can also set your own type (3 characters). - -Practical informations and example : - -This library has been build to save as much as memory as it can. To do that, Bluetooth class is sharing the same message ptr as the Message class. -The fact is that it will delete your precedent message on new message reception. If you want to avoid that, you can copy the message to another location before accepting new message. - -- To read message : ptr = Obj.getMessage(); - -- To save message : length = Obj.getLength()+48\ - ptr = malloc(length);\ - memcpy(ptr, Obj.msg, length);\ - Message Obj2;\ - Obj2.setTotalMessage(ptr); - -*/ - -class Message{ - -public: - - Message(); - - // init message attribute. opt=1 to send the message directly (if possible) - int init(const char* type, int ID, char* sender,const char* message); - - // set the type of the message. You have not to worry about other things to set in the header. It is automatic. - int setType(const char *typeH); - - // set message content. - int setMessage(const char *message); - - int setTotalMessage(char *message); - - // get message content. (ptr + 48) - unsigned char* getMessage(); - - // header informations : - char* getTime(); - char* getType(); - char* getSender(); - int getLength(); - - // this is message address (with header) - char *msg; - int isHeader; - -private: - - char type[3]; - int isType; - -}; - - -class Bluetooth{ - -public: - - Bluetooth(); - - // listen for new message. This function is non blocking. maxSize is the maximum length of message to receive. - // it will return NOT_ENOUG_RAM if it can not allocate that much. call this function early in your code, you'll have more chance to have enough ram. - // There is no maximum restriction, but RAM is about 50KO. 32KO should be the maximum. - int listen(int maxSize, int timer, void(*)(void), int time); - - // Send a message. There is no maximum size. Indead, you will be limited by the RAM size (approx. 50ko) - int sendMessage(Message *message); - - // get last message. - Message& getLastMessage(); - - // set the sender name (for header) - int setSender(char *senderName); - - // set it to 1 if you want to allow message reception. it will delete previous message on new reception !! save it if you would like to keep it !! - unsigned int allowReception; - unsigned int unread; - - // point on the 32ko of data. - char* ptr; - // point to the 1ko to receive - char* ptr1ko; - - // call by a timber every 25ms. It CAN NOT recept more than 1 ko in a row. - // use (3) and (4) to send bigger message from your device. - void receptMessage(); - int timer; - -private: - // total size of all send packet - int sentPacketsTotalSize; - // total szie of all received packets - int receivedPacketsTotalSize; - int max; - char sender[10]; - unsigned int ID; - unsigned int secondTry; - - // Keep the last message in memory - Message msg; - -}; - -int tabcmp(const char *tab[], int size, char *string); -char *itoa(int integer); - -#define RTC 15.625 - -#define RQT 0 -#define ASW 1 -#define ACK 2 -#define MIS 3 -#define FUL 4 -#define ERR 5 -#define END 6 - -// Error code : - -#define TIMER_ERROR_INSTALL 1 -#define SENDER_TOO_BIG 2 -#define SENDER_EMPTY 3 -#define SERIAL_ALREADY_OPEN 4 -#define NOT_ENOUGH_RAM 5 -#define MISSING_ACK 6 -#define UNKNOWN_ERROR 7 -#define INVALID_TYPE 8 -#define END_OF_COMMUNICATION 9 diff --git a/include/libJelling/bluetooth.h b/include/libJelling/bluetooth.h new file mode 100644 index 0000000..9ef30ad --- /dev/null +++ b/include/libJelling/bluetooth.h @@ -0,0 +1,102 @@ +/* + * AUTHOR : Xavier Bruni + * + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * As long as you retain this notice you can do whatever you want with this + * stuff. If we meet some day, and you think this stuff is worth it, you can + * buy me a beer in return. + * ---------------------------------------------------------------------------- + */ + +#define LIB_JELLING +#define BLUETOOTH_H_INCLUDED + +extern "C"{ + #include + #include + #include + #include "MonochromeLib.h" + #include "syscall.h" + #include "libfx.h" + #include "others.h" +} + +#include "libJelling/message.h" + +/* +This bluetooth library is working with the 3-pin port of your calculator. +This library is compatible with SuperH-3 and SuperH-4 processor : +This include : Graph 35+, 75, 85 & 95. +This library has been written for the following bluetooth module : HC-05, HC-06 +RAM can contain approximately 50KO of data. Each message can't do more than 32KO +You can't send more than 1ko -including header- from your smartphone to the calculator. In fact, the reception buffer has a size of 1ko max. +Without the header : 1000 - 48 = 952o +for sending : 256-48 = 208 +If the 32 ko buffer is full, it will return a FUL packet. +*/ + + +class Bluetooth{ + +public: + + Bluetooth(); + + // listen for new message. This function is non blocking. maxSize is the maximum length of message to receive. + // it will return NOT_ENOUG_RAM if it can not allocate that much. call this function early in your code, you'll have more chance to have enough ram. + // There is no maximum restriction, but RAM is about 50KO. 32KO should be the maximum. + int listen(int maxSize, int timer, void(*)(void), int time); + + // Properly terminate the bluetooth communication. + int stop(); + + // Send a message. There is no maximum size. Indead, you will be limited by the RAM size (approx. 50ko) + int sendMessage(Message *message); + + // get last message. + Message& getLastMessage(); + + // set the sender name (for header) + int setSender(const char *senderName); + + // set message ID + int setID(unsigned int id); + + // set it to 1 if you want to allow message reception. it will delete previous message on new reception !! save it if you would like to keep it !! + unsigned int allowReception; + unsigned int unread; + + // point on the 32ko of data. + char* ptr; + // point to the 1ko to receive + char* ptr1ko; + + // call by a timer every 25ms. It CAN NOT recept more than 1 ko in a row. + // use (5) and (6) to send bigger message from your device. + void receptMessage(); + int timer; + +private: + // total size of all send packet + int sentPacketsTotalSize; + // total szie of all received packets + int receivedPacketsTotalSize; + int max; + char sender[10]; + unsigned int caltoID; + unsigned int androidID; + unsigned int secondTry; + // for ACK + unsigned int lastType; + unsigned int lastID; + bool isWaitingAck; + + // Keep the last message in memory + Message msg; + +}; + +#define RETURN Timer_Start(this->timer);return; +#define SIZE_TX 255 +#define SIZE_DATA (SIZE_TX-48) \ No newline at end of file diff --git a/include/libJelling/libJelling.h b/include/libJelling/libJelling.h new file mode 100644 index 0000000..8a680e8 --- /dev/null +++ b/include/libJelling/libJelling.h @@ -0,0 +1,36 @@ +#ifndef LIB_JELLING + #ifndef BLUETOOTH_H_INCLUDED + #include "libJelling/bluetooth.h" + #endif + + #ifndef MESSAGE_H_INCLUDED + #include "libJelling/message.h" + #endif + + #ifndef MODULE_H_INCLUDED + #include "libJelling/module.h" + #endif +#endif + +#define TOO_LONG 1 +#define WRITE_ERROR 2 +#define BAD_RESPONSE 3 +#define TIMER_ERROR_INSTALL 4 +#define TOO_SHORT 5 +#define SERIAL_ALREADY_OPEN 6 +#define NOT_ENOUGH_RAM 7 +#define MISSING_ACK 8 +#define UNKNOWN_ERROR 9 +#define INVALID_TYPE 10 +#define END_OF_COMMUNICATION 11 + +#define RTC 0.128 + +#define RQT 0 +#define ASW 1 +#define ACK 2 +#define MIS 3 +#define FUL 4 +#define ERR 5 +#define END 6 +#define SYN 7 \ No newline at end of file diff --git a/include/libJelling/message.h b/include/libJelling/message.h new file mode 100644 index 0000000..ae01b09 --- /dev/null +++ b/include/libJelling/message.h @@ -0,0 +1,109 @@ +/* + * AUTHOR : Xavier Bruni + * + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * As long as you retain this notice you can do whatever you want with this + * stuff. If we meet some day, and you think this stuff is worth it, you can + * buy me a beer in return. + * ---------------------------------------------------------------------------- + */ + +#define LIB_JELLING +#define MESSAGE_H_INCLUDED + +extern "C"{ + #include + #include + #include + #include "libfx.h" + #include "syscall.h" +} + +#include "libJelling/libJelling.h" + +/* +How does Bluetooth header have to look like in a Message: + +- (1) time : 19 bytes (YYYY-MM-DD-HH-MM-SS) +- (2) type : 3 bytes (3*char) +- (3) ID : 4 bytes (unsigned int) +- (4) sender : 10 bytes (10*char) +- (5) total length of the message (in bytes), headers not included : 4 bytes (unsigned int) +- (6) total length of this packet (in bytes), headers not included : 4 bytes (unsigned int) +- (7) part of the message / number of part : 2 bytes (short unsigned int) / 2 bytes (short unsigned int) + +Total : 48 bytes. +Length must contain the null byte ! Null byte must be at the end of the message. + +(2) type can be : +- RQT : request +- ASW : answer to a request +- ACK : acknowledgment. packet received. +- MIS : missing packet +- FUL : full reception buffer or RAM buffer or precedent message unread. It sends the ID of last message read. +- ERR : error. see error code in message content. +- HED : incorrect header +- END : terminate the connection. + +Those are classic types. You can also set your own type (3 characters). + +Practical informations and example : + +This library has been build to save as much as memory as it can. To do that, Bluetooth class is sharing the same message ptr as the Message class. +The fact is that it will delete your precedent message on new message reception. If you want to avoid that, you can copy the message to +another location before accepting new message. + +- To read message : ptr = Obj.getMessage(); + +- To save message : length = Obj.getLength()+48\ + ptr = malloc(length);\ + memcpy(ptr, Obj.msg, length);\ + Message Obj2;\ + Obj2.setTotalMessage(ptr); + +*/ + +class Message{ + +public: + + Message(); + + // init message attribute. opt=1 to send the message directly (if possible) + int init(const char* type, int ID, const char* sender,const char* message); + + // set headers informations. + int setType(const char *typeH); + int setID(unsigned int ID); + int setSender(const char *sender); + + // set message content. + int setMessage(const char *message); + + // set message (headers ) + int setTotalMessage(char *message); + + // get message content. (ptr + 48) + unsigned char* getMessage(); + + // header informations : + char* getTime(); + char* getType(); + char* getSender(); + int getID(); + int getLength(); + + // this is message address (with header) + char *msg; + int isHeader; + +private: + + char type[3]; + char sender[10]; + int ID; + int isType; + int isID; + int isSender; +}; \ No newline at end of file diff --git a/include/libJelling/module.h b/include/libJelling/module.h new file mode 100644 index 0000000..f2aa380 --- /dev/null +++ b/include/libJelling/module.h @@ -0,0 +1,33 @@ +/* + * AUTHOR : Xavier Bruni + * + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * As long as you retain this notice you can do whatever you want with this + * stuff. If we meet some day, and you think this stuff is worth it, you can + * buy me a beer in return. + * ---------------------------------------------------------------------------- + */ + +#define LIB_JELLING +#define MODULE_H_INCLUDED + +extern "C"{ + #include "syscall.h" + #include + #include + #include "libJelling/libJelling.h" +} + +class Module{ + +public: + + static int setName(char* string); + static int setPassword(char* string); + +private: + + static int set(unsigned char* string); + +}; \ No newline at end of file diff --git a/include/others.h b/include/others.h new file mode 100644 index 0000000..6f153aa --- /dev/null +++ b/include/others.h @@ -0,0 +1,4 @@ +#include + +int tabcmp(const char** tab, int size, char *string); +char *itoa(int integer); diff --git a/libs/libfx.a b/libs/libfx.a new file mode 100644 index 0000000..5ef92aa Binary files /dev/null and b/libs/libfx.a differ diff --git a/libs/libmonochrome.a b/libs/libmonochrome.a new file mode 100644 index 0000000..4ac114c Binary files /dev/null and b/libs/libmonochrome.a differ diff --git a/makefile b/makefile new file mode 100644 index 0000000..22971b2 --- /dev/null +++ b/makefile @@ -0,0 +1,32 @@ +CC = sh3eb-elf-gcc +SRCDIR = src +INCLDIR = include +LIBDIR = libs +EXTENSIONS = c cpp s +LIBS = -lgcc -lmonochrome -lfx +WFLAGS = -W -Wall -Werror -Wextra +CFLAGS = -m3 -mb -O2 -fno-exceptions -ffreestanding -I $(INCLDIR) $(WFLAGS) +LFLAGS = -nostdlib -T addin.ld -L $(LIBDIR) $(LIBS) +SRCS := $(SRCS) $(foreach EXT,$(EXTENSIONS),$(wildcard $(SRCDIR)/*.$(EXT))) +OBJS := $(OBJS) $(foreach EXT,$(EXTENSIONS),$(patsubst $(SRCDIR)/%.$(EXT),%.o,$(wildcard $(SRCDIR)/*.$(EXT)))) +OUT = addin + +all : $(OUT).g1a + +$(OUT).g1a : $(OUT).bin + g1a-wrapper $(OUT).bin -o $(OUT).g1a -i icon.bmp + +$(OUT).bin : $(OUT).elf + sh3eb-elf-objcopy -R .bss -O binary $(OUT).elf $(OUT).bin + +$(OUT).elf : $(OBJS) + $(CC) -o $@ $^ $(LFLAGS) + +$(OBJS) : $(SRCDIR)/$(SRCS) + $(CC) -c $(SRCS) $(CFLAGS) + +clean : + rm -f *.o + +cleaner : + rm -f *.o $(OUT).elf $(OUT).g1a $(OUT).bin diff --git a/src/BTKOM.cpp b/src/BTKOM.cpp new file mode 100644 index 0000000..3338d48 --- /dev/null +++ b/src/BTKOM.cpp @@ -0,0 +1,54 @@ +#include "BTKOM.h" + +Bluetooth bluetooth; + +void listen(){ + //bluetooth.receptMessage(); +} + +int init(){ + int err = 0; + err = bluetooth.listen(2000, 0, listen, 1); + if(err == NOT_ENOUGH_RAM) PrintMini(0,0,(const unsigned char*)"Not enough RAM to start listening.",0); + else if(err == SERIAL_ALREADY_OPEN) PrintMini(0,0,(const unsigned char*)"Serial already open.",0); + bluetooth.setSender((const char*)"Xavier"); + return !err; +} + +int sendMessage(const char* type, const char* message){ + int err = 0; + Message toSend; + toSend.setType(type); + toSend.setMessage(message); + toSend.setSender((const char*)"Fuck"); + err = bluetooth.sendMessage(&toSend); + //PrintMini(0,0,(const unsigned char*)itoa(err),0); + //PrintMini(1,1,(const unsigned char*)toSend.getSender(),0); + if(err == MISSING_ACK){ + PrintMini(50,0,(const unsigned char*)"Message sent",0); + }else if(err == UNKNOWN_ERROR){ + PrintMini(50,0,(const unsigned char*)"Unknown error",0); + } + return !err; +} + +int main(){ + + unsigned int key; + char buffer[] = {"ok so this is gonna be a very long message to see the behavior even if I think it's gonna bug it will be funny then let's do it i need at least 100 more characters to see if it works corectly but I think i'm approximatly arriving to this objectif nevermind fuck this shit which doesn't work most of the time"}; + ML_clear_screen(); + //ML_clear_vram(); + if(init()){ + sendMessage((const char*)"ACK",(const char*) buffer); + } + //ML_display_vram(); + //bluetooth.stop(); + while(1){ + GetKey(&key); + } + + return 1; +} + + + diff --git a/src/MonochromeLib.c b/src/MonochromeLib.c new file mode 100644 index 0000000..f7cbfe9 --- /dev/null +++ b/src/MonochromeLib.c @@ -0,0 +1,1289 @@ +/*************************************************************/ +/** MonochromeLib - monochrome graphic library for fx-9860G **/ +/** MonochromeLib is free software **/ +/** **/ +/** @author Pierre "PierrotLL" Le Gall **/ +/** @contact legallpierre89@gmail.com **/ +/** **/ +/** @file MonochromeLib.c **/ +/** Code file of MonochromeLib **/ +/** **/ +/** @date 11-22-2011 **/ +/*************************************************************/ + +#include "MonochromeLib.h" +#include + + +/******************************/ +/** Dependencies management **/ +/******************************/ + +#ifdef ML_ALL + #define ML_CLEAR_VRAM + #define ML_CLEAR_SCREEN + #define ML_DISPLAY_VRAM + #define ML_SET_CONTRAST + #define ML_GET_CONTRAST + #define ML_PIXEL + #define ML_POINT + #define ML_PIXEL_TEST + #define ML_LINE + #define ML_HORIZONTAL_LINE + #define ML_VERTICAL_LINE + #define ML_RECTANGLE + #define ML_POLYGON + #define ML_FILLED_POLYGON + #define ML_CIRCLE + #define ML_FILLED_CIRCLE + #define ML_ELLIPSE + #define ML_ELLIPSE_IN_RECT + #define ML_FILLED_ELLIPSE + #define ML_FILLED_ELLIPSE_IN_RECT + #define ML_HORIZONTAL_SCROLL + #define ML_VERTICAL_SCROLL + #define ML_BMP_OR + #define ML_BMP_AND + #define ML_BMP_XOR + #define ML_BMP_OR_CL + #define ML_BMP_AND_CL + #define ML_BMP_XOR_CL + #define ML_BMP_8_OR + #define ML_BMP_8_AND + #define ML_BMP_8_XOR + #define ML_BMP_8_OR_CL + #define ML_BMP_8_AND_CL + #define ML_BMP_8_XOR_CL + #define ML_BMP_16_OR + #define ML_BMP_16_AND + #define ML_BMP_16_XOR + #define ML_BMP_16_OR_CL + #define ML_BMP_16_AND_CL + #define ML_BMP_16_XOR_CL +#endif + +#ifdef ML_POLYGON + #define ML_LINE +#endif + +#ifdef ML_LINE + #define ML_PIXEL +#endif + +#ifdef ML_POINT + #define ML_PIXEL + #define ML_RECTANGLE +#endif + +#ifdef ML_RECTANGLE + #define ML_HORIZONTAL_LINE +#endif + +#ifdef ML_FILLED_POLYGON + #define ML_HORIZONTAL_LINE +#endif + +#ifdef ML_CIRCLE + #define ML_PIXEL +#endif + +#ifdef ML_FILLED_CIRCLE + #define ML_HORIZONTAL_LINE +#endif + +#ifdef ML_ELLIPSE_IN_RECT + #define ML_ELLIPSE +#endif + +#ifdef ML_ELLIPSE + #define ML_PIXEL +#endif + +#ifdef ML_FILLED_ELLIPSE_IN_RECT + #define ML_FILLED_ELLIPSE +#endif + +#ifdef ML_FILLED_ELLIPSE + #define ML_HORIZONTAL_LINE +#endif + + +/***************/ +/** Functions **/ +/***************/ + +#define sgn(x) (x<0?-1:1) +#define rnd(x) ((int)(x+0.5)) + +//Thanks to Simon Lothar for this function +static int SysCallCode[] = {0xD201422B,0x60F20000,0x80010070}; +static int (*SysCall)( int R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallCode; +char* ML_vram_adress() +{ + return (char*)((*SysCall)(0, 0, 0, 0, 309)); +} + +#ifdef ML_CLEAR_VRAM +void ML_clear_vram() +{ + int i, end, *pointer_long, vram; + char *pointer_byte; + vram = (int)ML_vram_adress(); + end = (4-vram)&3; + pointer_byte = (char*)vram; + for(i=0 ; i>3)] |= 128>>(x&7); + break; + case ML_WHITE: + vram[(y<<4)+(x>>3)] &= ~(128>>(x&7)); + break; + case ML_XOR: + vram[(y<<4)+(x>>3)] ^= 128>>(x&7); + break; + case ML_CHECKER: + if(y&1^x&1) vram[(y<<4)+(x>>3)] &= ~(128>>(x&7)); + else vram[(y<<4)+(x>>3)] |= 128>>(x&7); + break; + } +} +#endif + +#ifdef ML_POINT +void ML_point(int x, int y, int width, ML_Color color) +{ + if(width < 1) return; + if(width == 1) ML_pixel(x, y, color); + else + { + int padding, pair; + padding = width>>1; + pair = !(width&1); + ML_rectangle(x-padding+pair, y-padding+pair, x+padding, y+padding, 0, 0, color); + } +} +#endif + +#ifdef ML_PIXEL_TEST +ML_Color ML_pixel_test(int x, int y) +{ + char *vram, byte; + if(x&~127 || y&~63) return ML_TRANSPARENT; + vram = ML_vram_adress(); + byte = 1<<(7-(x&7)); + return (vram[(y<<4)+(x>>3)] & byte ? ML_BLACK : ML_WHITE); + +} +#endif + +#ifdef ML_LINE +void ML_line(int x1, int y1, int x2, int y2, ML_Color color) +{ + int i, x, y, dx, dy, sx, sy, cumul; + x = x1; + y = y1; + dx = x2 - x1; + dy = y2 - y1; + sx = sgn(dx); + sy = sgn(dy); + dx = abs(dx); + dy = abs(dy); + ML_pixel(x, y, color); + if(dx > dy) + { + cumul = dx / 2; + for(i=1 ; i dx) + { + cumul -= dx; + y += sy; + } + ML_pixel(x, y, color); + } + } + else + { + cumul = dy / 2; + for(i=1 ; i dy) + { + cumul -= dy; + x += sx; + } + ML_pixel(x, y, color); + } + } +} +#endif + +#ifdef ML_HORIZONTAL_LINE +void ML_horizontal_line(int y, int x1, int x2, ML_Color color) +{ + int i; + char checker; + char* vram = ML_vram_adress(); + if(y&~63 || (x1<0 && x2<0) || (x1>127 && x2>127)) return; + if(x1 > x2) + { + i = x1; + x1 = x2; + x2 = i; + } + if(x1 < 0) x1 = 0; + if(x2 > 127) x2 = 127; + switch(color) + { + case ML_BLACK: + if(x1>>3 != x2>>3) + { + vram[(y<<4)+(x1>>3)] |= 255 >> (x1&7); + vram[(y<<4)+(x2>>3)] |= 255 << 7-(x2&7); + for(i=(x1>>3)+1 ; i>3 ; i++) + vram[(y<<4) + i] = 255; + } + else vram[(y<<4)+(x1>>3)] |= (255>>(x1%8 + 7-x2%8))<<(7-(x2&7)); + break; + case ML_WHITE: + if(x1>>3 != x2>>3) + { + vram[(y<<4)+(x1>>3)] &= 255 << 8-(x1&7); + vram[(y<<4)+(x2>>3)] &= 255 >> 1+(x2&7); + for(i=(x1>>3)+1 ; i>3 ; i++) + vram[(y<<4) + i] = 0; + } + else vram[(y<<4)+(x1>>3)] &= (255<<8-(x1&7)) | (255>>1+(x2&7)); + break; + case ML_XOR: + if(x1>>3 != x2>>3) + { + vram[(y<<4)+(x1>>3)] ^= 255 >> (x1&7); + vram[(y<<4)+(x2>>3)] ^= 255 << 7-(x2&7); + for(i=(x1>>3)+1 ; i<(x2>>3) ; i++) + vram[(y<<4) + i] ^= 255; + } + else vram[(y<<4)+(x1>>3)] ^= (255>>((x1&7) + 7-(x2&7)))<<(7-(x2&7)); + break; + case ML_CHECKER: + checker = (y&1 ? 85 : 170); + if(x1>>3 != x2>>3) + { + vram[(y<<4)+(x1>>3)] &= 255 << 8-(x1&7); + vram[(y<<4)+(x2>>3)] &= 255 >> 1+(x2&7); + vram[(y<<4)+(x1>>3)] |= checker & 255>>(x1&7); + vram[(y<<4)+(x2>>3)] |= checker & 255<<7-(x2&7); + for(i=(x1>>3)+1 ; i>3 ; i++) + vram[(y<<4) + i] = checker; + } + else + { + vram[(y<<4)+(x1>>3)] &= (255<<8-(x1&7)) | (255>>1+(x2&7)); + vram[(y<<4)+(x1>>3)] |= checker & (255>>(x1%8 + 7-x2%8))<<(7-(x2&7)); + } + break; + } +} + +#endif + +#ifdef ML_VERTICAL_LINE +void ML_vertical_line(int x, int y1, int y2, ML_Color color) +{ + int i, j; + char checker, byte, *vram = ML_vram_adress(); + if(x&~127 || (y1<0 && y2<0) || (y1>63 && y2>63)) return; + if(y1 > y2) + { + int tmp = y1; + y1 = y2; + y2 = tmp; + } + if(y1 < 0) y1 = 0; + if(y2 > 63) y2 = 63; + + i = (y1<<4)+(x>>3); + j = (y2<<4)+(x>>3); + switch(color) + { + case ML_BLACK: + byte = 128>>(x&7); + for( ; i<=j ; i+=16) + vram[i] |= byte; + break; + case ML_WHITE: + byte = ~(128>>(x&7)); + for( ; i<=j ; i+=16) + vram[i] &= byte; + break; + case ML_XOR: + byte = 128>>(x&7); + for( ; i<=j ; i+=16) + vram[i] ^= byte; + break; + case ML_CHECKER: + byte = 128>>(x&7); + checker = y1&1^x&1; + for( ; i<=j ; i+=16) + { + if(checker) vram[i] &= ~byte; + else vram[i] |= byte; + checker = !checker; + } + break; + } +} +#endif + +#ifdef ML_RECTANGLE +void ML_rectangle(int x1, int y1, int x2, int y2, int border_width, ML_Color border_color, ML_Color fill_color) +{ + int i; + if(x1 > x2) + { + i = x1; + x1 = x2; + x2 = i; + } + if(y1 > y2) + { + i = y1; + y1 = y2; + y2 = i; + } + if(border_width > (x2-x1)/2+1) border_width = (x2-x1)/2+1; + if(border_width > (y2-y1)/2+1) border_width = (y2-y1)/2+1; + if(border_color != ML_TRANSPARENT && border_width > 0) + { + for(i=0 ; i t[i]) + { + j++; + tmp = t[j]; + t[j] = t[i]; + t[i] = tmp; + } + } + t[r] = t[j+1]; + t[j+1] = x; + return j + 1; +} + +static void ML_filled_polygon_quicksord(int* t, int p, int r) +{ + int q; + if(p < r) + { + q = ML_filled_polygon_quicksord_partition(t, p, r); + ML_filled_polygon_quicksord(t, p, q-1); + ML_filled_polygon_quicksord(t, q+1, r); + } +} + + +void ML_filled_polygon(const int *x, const int *y, int nb_vertices, ML_Color color) +{ + int i, j, dx, dy, ymin, ymax; + int *cut_in_line, nb_cut; + if(nb_vertices < 3) return; + cut_in_line = malloc(nb_vertices*sizeof(int)); + if(!cut_in_line) return; + ymin = ymax = y[0]; + for(i=1 ; i ymax) ymax = y[i]; + } + for(i=ymin ; i<=ymax ; i++) + { + nb_cut = 0; + for(j=0 ; j=i) || (y[j]>=i && y[(j+1)%nb_vertices]<=i)) + { + dy = abs(y[j]-y[(j+1)%nb_vertices]); + if(dy) + { + dx = x[(j+1)%nb_vertices]-x[j]; + cut_in_line[nb_cut] = x[j] + rnd(abs(i-y[j]+sgn(i-y[j])/2)*dx/dy); + nb_cut++; + } + } + } + ML_filled_polygon_quicksord(cut_in_line, 0, nb_cut-1); + j = 0; + while(j plot_x) + { + if(d < 0) + d += 2*plot_x+3; + else + { + d += 2*(plot_x-plot_y)+5; + plot_y--; + } + plot_x++; + if(plot_y >= plot_x) + { + ML_pixel(x+plot_x, y+plot_y, color); + ML_pixel(x-plot_x, y+plot_y, color); + ML_pixel(x+plot_x, y-plot_y, color); + ML_pixel(x-plot_x, y-plot_y, color); + } + if(plot_y > plot_x) + { + ML_pixel(x+plot_y, y+plot_x, color); + ML_pixel(x-plot_y, y+plot_x, color); + ML_pixel(x+plot_y, y-plot_x, color); + ML_pixel(x-plot_y, y-plot_x, color); + } + } +} +#endif + +#ifdef ML_FILLED_CIRCLE +void ML_filled_circle(int x, int y, int radius, ML_Color color) +{ + int plot_x, plot_y, d; + + if(radius < 0) return; + plot_x = 0; + plot_y = radius; + d = 1 - radius; + + ML_horizontal_line(y, x-plot_y, x+plot_y, color); + while(plot_y > plot_x) + { + if(d < 0) + d += 2*plot_x+3; + else { + d += 2*(plot_x-plot_y)+5; + plot_y--; + ML_horizontal_line(y+plot_y+1, x-plot_x, x+plot_x, color); + ML_horizontal_line(y-plot_y-1, x-plot_x, x+plot_x, color); + } + plot_x++; + if(plot_y >= plot_x) + { + ML_horizontal_line(y+plot_x, x-plot_y, x+plot_y, color); + ML_horizontal_line(y-plot_x, x-plot_y, x+plot_y, color); + } + } +} +#endif + +#ifdef ML_ELLIPSE +void ML_ellipse(int x, int y, int radius1, int radius2, ML_Color color) +{ + int plot_x, plot_y; + float d1, d2; + if(radius1 < 1 || radius2 < 1) return; + plot_x = 0; + plot_y = radius2; + d1 = radius2*radius2 - radius1*radius1*radius2 + radius1*radius1/4; + ML_pixel(x, y+plot_y, color); + ML_pixel(x, y-plot_y, color); + while(radius1*radius1*(plot_y-.5) > radius2*radius2*(plot_x+1)) + { + if(d1 < 0) + { + d1 += radius2*radius2*(2*plot_x+3); + plot_x++; + } else { + d1 += radius2*radius2*(2*plot_x+3) + radius1*radius1*(-2*plot_y+2); + plot_x++; + plot_y--; + } + ML_pixel(x+plot_x, y+plot_y, color); + ML_pixel(x-plot_x, y+plot_y, color); + ML_pixel(x+plot_x, y-plot_y, color); + ML_pixel(x-plot_x, y-plot_y, color); + } + d2 = radius2*radius2*(plot_x+.5)*(plot_x+.5) + radius1*radius1*(plot_y-1)*(plot_y-1) - radius1*radius1*radius2*radius2; + while(plot_y > 0) + { + if(d2 < 0) + { + d2 += radius2*radius2*(2*plot_x+2) + radius1*radius1*(-2*plot_y+3); + plot_y--; + plot_x++; + } else { + d2 += radius1*radius1*(-2*plot_y+3); + plot_y--; + } + ML_pixel(x+plot_x, y+plot_y, color); + ML_pixel(x-plot_x, y+plot_y, color); + if(plot_y > 0) + { + ML_pixel(x+plot_x, y-plot_y, color); + ML_pixel(x-plot_x, y-plot_y, color); + } + } +} +#endif + +#ifdef ML_ELLIPSE_IN_RECT +void ML_ellipse_in_rect(int x1, int y1, int x2, int y2, ML_Color color) +{ + int radius1, radius2; + if(x1 > x2) + { + int tmp = x1; + x1 = x2; + x2 = tmp; + } + if(y1 > y2) + { + int tmp = y1; + y1 = y2; + y2 = tmp; + } + radius1 = (x2-x1)/2; + radius2 = (y2-y1)/2; + ML_ellipse(x1+radius1, y1+radius2, radius1, radius2, color); +} +#endif + +#ifdef ML_FILLED_ELLIPSE +void ML_filled_ellipse(int x, int y, int radius1, int radius2, ML_Color color) +{ + int plot_x, plot_y; + float d1, d2; + if(radius1 < 1 || radius2 < 1) return; + plot_x = 0; + plot_y = radius2; + d1 = radius2*radius2 - radius1*radius1*radius2 + radius1*radius1/4; + while(radius1*radius1*(plot_y-.5) > radius2*radius2*(plot_x+1)) + { + if(d1 < 0) + { + d1 += radius2*radius2*(2*plot_x+3); + plot_x++; + } else { + d1 += radius2*radius2*(2*plot_x+3) + radius1*radius1*(-2*plot_y+2); + ML_horizontal_line(y+plot_y, x-plot_x, x+plot_x, color); + ML_horizontal_line(y-plot_y, x-plot_x, x+plot_x, color); + plot_x++; + plot_y--; + } + } + ML_horizontal_line(y+plot_y, x-plot_x, x+plot_x, color); + ML_horizontal_line(y-plot_y, x-plot_x, x+plot_x, color); + d2 = radius2*radius2*(plot_x+.5)*(plot_x+.5) + radius1*radius1*(plot_y-1)*(plot_y-1) - radius1*radius1*radius2*radius2; + while(plot_y > 0) + { + if(d2 < 0) + { + d2 += radius2*radius2*(2*plot_x+2) + radius1*radius1*(-2*plot_y+3); + plot_y--; + plot_x++; + } else { + d2 += radius1*radius1*(-2*plot_y+3); + plot_y--; + } + ML_horizontal_line(y+plot_y, x-plot_x, x+plot_x, color); + if(plot_y > 0) + ML_horizontal_line(y-plot_y, x-plot_x, x+plot_x, color); + } +} +#endif + +#ifdef ML_FILLED_ELLIPSE_IN_RECT +void ML_filled_ellipse_in_rect(int x1, int y1, int x2, int y2, ML_Color color) +{ + int radius1, radius2; + if(x1 > x2) + { + int tmp = x1; + x1 = x2; + x2 = tmp; + } + if(y1 > y2) + { + int tmp = y1; + y1 = y2; + y2 = tmp; + } + radius1 = (x2-x1)/2; + radius2 = (y2-y1)/2; + ML_filled_ellipse(x1+radius1, y1+radius2, radius1, radius2, color); +} +#endif + +#ifdef ML_HORIZONTAL_SCROLL +void ML_horizontal_scroll(int scroll) +{ + int i, j; + char line[16], shift, *vram; + unsigned char next; + unsigned short word; + vram = ML_vram_adress(); + scroll %= 128; + shift = 8-(scroll&7); + for(i=0 ; i<64 ; i++) + { + for(j=0 ; j<16 ; j++) line[j] = vram[(i<<4)+((j-(scroll>>3)+15)&15)]; + next = line[15]; + vram[(i<<4)+15] = 0; + for(j=15 ; j>0 ; j--) + { + word = next << shift; + next = line[j-1]; + vram[(i<<4)+j] |= *((char*)&word+1); + vram[(i<<4)+j-1] = *((char*)&word); + } + word = next << shift; + vram[(i<<4)] |= *((char*)&word+1); + vram[(i<<4)+15] |= *((char*)&word); + } +} +#endif + +#ifdef ML_VERTICAL_SCROLL +void ML_vertical_scroll(int scroll) +{ + int i, j; + char column[64], *vram = ML_vram_adress(); + scroll %= 64; + for(i=0 ; i<16 ; i++) + { + for(j=0 ; j<64 ; j++) column[j] = vram[(j<<4)+i]; + for(j=0 ; j<64 ; j++) vram[(j<<4)+i] = column[(j-scroll+64)&63]; + } +} +#endif + +#ifdef ML_BMP_OR +void ML_bmp_or(const unsigned char *bmp, int x, int y, int width, int height) +{ + unsigned short line; + char shift, *screen, *p=(char*)&line; + int i, j, begin=0, end=height, real_width=(width-1>>3<<3)+8; + if(!bmp || x<0 || x>128-width || y<1-height || y>63 || width<1 || height<1) return; + if(y < 0) begin = -y; + if(y+height > 64) end = 64-y; + shift = 8-(x&7); + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; i>3 ; j++) + { + line = bmp[i*(real_width>>3)+j]<>3)+j] & -1<<(real_width-width))<>3<<3)+8; + if(!bmp || x<0 || x>128-width || y<1-height || y>63 || width<1 || height<1) return; + if(y < 0) begin = -y; + if(y+height > 64) end = 64-y; + shift = 8-(x&7); + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; i>3 ; j++) + { + line = ~((unsigned char)~bmp[i*(real_width>>3)+j]<>3)+j] | (unsigned char)-1>>8-(width&7))<>3<<3)+8; + if(!bmp || x<0 || x>128-width || y<1-height || y>63 || width<1 || height<1) return; + if(y < 0) begin = -y; + if(y+height > 64) end = 64-y; + shift = 8-(x&7); + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; i>3 ; j++) + { + line = bmp[i*(real_width>>3)+j]<>3)+j] & -1<<(real_width-width))<127 || y<1-height || y>63 || height<1 || width<1) return; + p = (char*)&line; + real_width = (width-1>>3<<3)+8; + if(y < 0) begin_y = -y; + else begin_y = 0; + if(y+height > 64) end_y = 64-y; + else end_y = height; + shift = 8-(x&7); + if(x<0) + { + begin_x = -x>>3; + if(shift != 8) bool1 = 0; + } else begin_x = 0; + if(x+real_width > 128) end_x = 15-(x>>3), bool2 = 0; + else end_x = real_width-1>>3; + bool3 = (end_x == real_width-1>>3); + screen = ML_vram_adress()+(y+begin_y<<4)+(x>>3); + + for(i=begin_y ; i>3)+begin_x] << shift; + if(bool1) screen[begin_x] |= *p; + if(shift!=8) screen[begin_x+1] |= *(p+1); + for(j=begin_x+1 ; j>3)+j] << shift; + screen[j] |= *p; + if(shift!=8) screen[j+1] |= *(p+1); + } + } + line = bmp[i*(real_width>>3)+end_x]; + if(bool3) line &= -1<127 || y<1-height || y>63 || height<1 || width<1) return; + p = (char*)&line; + real_width = (width-1>>3<<3)+8; + if(y < 0) begin_y = -y; + else begin_y = 0; + if(y+height > 64) end_y = 64-y; + else end_y = height; + shift = 8-(x&7); + if(x<0) + { + begin_x = -x>>3; + if(shift != 8) bool1 = 0; + } else begin_x = 0; + if(x+real_width > 128) end_x = 15-(x>>3), bool2 = 0; + else end_x = real_width-1>>3; + bool3 = (end_x == real_width-1>>3); + screen = ML_vram_adress()+(y+begin_y<<4)+(x>>3); + + for(i=begin_y ; i>3)+begin_x]<>3)+j]<>3)+end_x]; + if(bool3) line &= -1<127 || y<1-height || y>63 || height<1 || width<1) return; + p = (char*)&line; + real_width = (width-1>>3<<3)+8; + if(y < 0) begin_y = -y; + else begin_y = 0; + if(y+height > 64) end_y = 64-y; + else end_y = height; + shift = 8-(x&7); + if(x<0) + { + begin_x = -x>>3; + if(shift != 8) bool1 = 0; + } else begin_x = 0; + if(x+real_width > 128) end_x = 15-(x>>3), bool2 = 0; + else end_x = real_width-1>>3; + bool3 = (end_x == real_width-1>>3); + screen = ML_vram_adress()+(y+begin_y<<4)+(x>>3); + + for(i=begin_y ; i>3)+begin_x] << shift; + if(bool1) screen[begin_x] ^= *p; + if(shift!=8) screen[begin_x+1] ^= *(p+1); + for(j=begin_x+1 ; j>3)+j] << shift; + screen[j] ^= *p; + if(shift!=8) screen[j+1] ^= *(p+1); + } + } + line = bmp[i*(real_width>>3)+end_x]; + if(bool3) line &= -1<120 || y<-7 || y>63) return; + if(y < 0) begin = -y; + if(y > 56) end = 64-y; + shift = 8-(x&7); + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; i120 || y<-7 || y>63) return; + if(y < 0) begin = -y; + if(y > 56) end = 64-y; + shift = 8-(x&7); + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; i120 || y<-7 || y>63) return; + if(y < 0) begin = -y; + if(y > 56) end = 64-y; + shift = 8-(x&7); + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; i127 || y<-7 || y>63) return; + if(y < 0) begin = -y; + if(y > 56) end = 64-y; + shift = 8-(x&7); + if(x < 0) bool1 = 0; + if(x>120 || shift==8) bool2 = 0; + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; i127 || y<-7 || y>63) return; + if(y < 0) begin = -y; + if(y > 56) end = 64-y; + shift = 8-(x&7); + if(x < 0) bool1 = 0; + if(x>120 || shift==8) bool2 = 0; + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; i127 || y<-7 || y>63) return; + if(y < 0) begin = -y; + if(y > 56) end = 64-y; + shift = 8-(x&7); + if(x < 0) bool1 = 0; + if(x>120 || shift==8) bool2 = 0; + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; i112 || y<-15 || y>63) return; + if(y < 0) begin = -y; + if(y > 48) end = 64-y; + shift = 8-(x&7); + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; i112 || y<-15 || y>63) return; + if(y < 0) begin = -y; + if(y > 48) end = 64-y; + shift = 8-(x&7); + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; i112 || y<-15 || y>63) return; + if(y < 0) begin = -y; + if(y > 48) end = 64-y; + shift = 8-(x&7); + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; i127 || y<-15 || y>63) return; + if(y < 0) begin = -y; + if(y > 48) end = 64-y; + shift = 8-(x&7); + if(x < 0) bool1 = 0; + if(x<-8 || x>119) bool2 = 0; + if(x>111 || shift==8) bool3 = 0; + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; i127 || y<-15 || y>63) return; + if(y < 0) begin = -y; + if(y > 48) end = 64-y; + shift = 8-(x&7); + if(x < 0) bool1 = 0; + if(x<-8 || x>119) bool2 = 0; + if(x>111 || shift==8) bool3 = 0; + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; i127 || y<-15 || y>63) return; + if(y < 0) begin = -y; + if(y > 48) end = 64-y; + shift = 8-(x&7); + if(x < 0) bool1 = 0; + if(x<-8 || x>119) bool2 = 0; + if(x>111 || shift==8) bool3 = 0; + screen = ML_vram_adress()+(y+begin<<4)+(x>>3); + for(i=begin ; isentPacketsTotalSize = 0; + this->receivedPacketsTotalSize = 0; + this->unread = 0; + this->allowReception = 1; + srand(RTC_GetTicks()); + this->caltoID = rand(); + this->secondTry = 0; + memcpy(this->sender, "HC-06\0", 6); +} + +int Bluetooth::listen(int maxSize, int timer, void(*func)(void), int time){ + unsigned char conf[6] = {0, 5, 0, 0, 0, 0}; + max = maxSize; + this->ptr = (char*)malloc(maxSize); + this->ptr1ko = (char*)malloc(1000); + if(this->ptr == NULL || this->ptr1ko == NULL) return NOT_ENOUGH_RAM; + this->timer = Timer_Install(timer, func, time); + if(Serial_Open(conf) == 3) return SERIAL_ALREADY_OPEN; + + Timer_Start(this->timer); + + return 0; +} + +int Bluetooth::stop(){ + Serial_Close(1); + return 0; +} + +int Bluetooth::setSender(const char *senderName){ + if(strlen(senderName)+1 <= 10){ + if(strlen(senderName) > 0){ + memcpy(this->sender, senderName, strlen(senderName)+1); + }else{ + return TOO_SHORT; + } + }else{ + return TOO_LONG; + } + return 0; +} + +int Bluetooth::sendMessage(Message *message){ + int RTCTime, tempInt; + unsigned short tempShort, split; + char *ptr2; + unsigned char dateEx[] = "YYYY-MM-DD-HH-MM-SS"; + split = (unsigned short)(message->getLength()/SIZE_DATA + (message->getLength()%SIZE_DATA == 0 ? 0:1)); + if((ptr2 = (char*)malloc(SIZE_TX)) == NULL) return NOT_ENOUGH_RAM; + Timer_Stop(this->timer); + for(unsigned short i=0; igetType() != NULL){ + memcpy(ptr2+19, message->getType(), 3); + }else{ + memcpy(ptr2+19,"RQT",3); + } + if(message->getID() != -1){ + tempInt = message->getID(); + memcpy(ptr2+22, &tempInt, sizeof(int)); + }else{ + memcpy(ptr2+22, &this->caltoID, sizeof(int)); + } + if(message->getSender() != NULL){ + memcpy(ptr2+26, message->getSender(), 10); + }else{ + memcpy(ptr2+26, this->sender, 10); + } + tempInt = message->getLength(); + memcpy(ptr2+36, &tempInt, sizeof(int)); + tempInt = (i+1)*SIZE_DATA > message->getLength() ? message->getLength()-i*SIZE_DATA : SIZE_DATA; + memcpy(ptr2+40, &tempInt, sizeof(int)); + tempShort = i+1; + memcpy(ptr2+44, &tempShort, sizeof(unsigned short)); + memcpy(ptr2+46, &split, sizeof(unsigned short)); + memcpy(ptr2+48, (char*)message->getMessage()+i*SIZE_DATA, tempInt); + Serial_WriteBytes((unsigned char*)ptr2,48+tempInt); + RTCTime = RTC_GetTicks(); + while(Serial_GetTxBufferFreeCapacity() < SIZE_TX){ + if((RTC_GetTicks() - RTCTime)/RTC > 300){ + free(ptr2); + Timer_Start(this->timer); + return UNKNOWN_ERROR; + } + } + } + + RTCTime = RTC_GetTicks(); + isWaitingAck = true; + while(this->lastID != this->caltoID){ + if((RTC_GetTicks() - RTCTime)/RTC > 300){ + free(ptr2); + Timer_Start(this->timer); + isWaitingAck = false; + return MISSING_ACK; + } + } + isWaitingAck = false; + free(ptr2); + this->caltoID++; + Timer_Start(this->timer); + return 0; + +} + +Message& Bluetooth::getLastMessage(){ + return msg; +} + +void Bluetooth::receptMessage(){ + int size, errorID; + int RTCTime; + int messageLength = 48; + int typeCase; + char buffer[50]; + int lengthPackets[2]; + unsigned short partsNumber[2] = {(unsigned short)0,(unsigned short)1}; + const char type[7][4] = {"RQT","ASW","ACK","MIS","FUL","ERR","END"}; + const char err[1][4] = {"ERR"}; + char ptr2[3]; + unsigned int messageID; + Message sendBack; + if((this->secondTry = Serial_GetRxBufferSize()) == 1000 || (int)this->secondTry==Serial_GetRxBufferSize()){ + Serial_ReadBytes((unsigned char*)this->ptr1ko, 1000,(short*)&size); + memcpy(ptr2, this->ptr1ko+19, 3); + typeCase = tabcmp((const char**)type, 7, ptr2); + switch(typeCase){ + case ACK: + if(isWaitingAck){ + this->lastType = ACK; + memcpy(&this->lastID, (unsigned int*)this->ptr1ko+48, sizeof(unsigned int)); + } + break; + case RQT: + case END: + case ASW: + // if allowReception. else, send back a FUL packet to the device + if(this->allowReception){ + if(size >= 26) memcpy(&messageID, (unsigned int*)this->ptr1ko+22, sizeof(unsigned int)); + if(size < 48){ + if(size >= 26)sendBack.init("HED", this->caltoID, this->sender, (char*)messageID); + else sendBack.init("HED", this->caltoID, this->sender, "\0"); + sendMessage(&sendBack); + RETURN + } + memcpy(this->sender, this->ptr1ko+26, 10); + for(unsigned short i=0; iptr1ko+22, sizeof(unsigned int)); + if(messageID != this->androidID){ + sprintf(buffer,"INCORRECT ID %d-%d",messageID,this->androidID); + sendBack.init("ERR", messageID, this->sender, buffer); + sendMessage(&sendBack); + RETURN + } + memcpy(lengthPackets, this->ptr1ko+36, sizeof(lengthPackets)); + sprintf(buffer,"%d", i+1); + if(partsNumber[0] != i+1){ + if(partsNumber[0] > i+1){ + sendBack.init("MIS", messageID, this->sender, buffer); + sendMessage(&sendBack); + }else{ + sendBack.init("ACK", messageID, this->sender, buffer); + sendMessage(&sendBack); + } + }else if(lengthPackets[1] != size-48){ + sprintf(buffer, "INCOMPLETE PACKET SIZE %d", this->androidID); + sendBack.init("ERR", messageID, this->sender, buffer); + sendMessage(&sendBack); + RETURN + }else{ + messageLength+=size-48; + memcpy(this->ptr+48+i*952, this->ptr1ko+48, 952); + sendBack.init("ACK", messageID, this->sender, buffer); + sendMessage(&sendBack); + if(messageLength-48 == lengthPackets[0] && partsNumber[0] == partsNumber[1]){ + if(!(errorID = msg.setTotalMessage(this->ptr))){ + this->unread = 1; + this->allowReception = 0; + this->androidID++; + RETURN + }else{ + sendBack.init("ERR", messageID, this->sender, (char*)&err[errorID]); + sendMessage(&sendBack); + RETURN + } + } + + } + RTCTime = RTC_GetTicks(); + while(Serial_GetRxBufferSize() != (lengthPackets[0]-messageLength-48>1000 ? 1000 : lengthPackets[0]-messageLength-48)){ + if((RTC_GetTicks() - RTCTime)/RTC > 300){ + RETURN + } + } + memcpy(partsNumber, this->ptr1ko+44, sizeof(partsNumber)); + } + }else{ + sprintf(buffer, "%d",this->androidID); + sendBack.init("FUL", this->caltoID, this->sender, buffer); + sendMessage(&sendBack); + RETURN + } + break; + } + }else if(Serial_GetRxBufferSize()>0){ + this->secondTry = Serial_GetRxBufferSize(); + RETURN + } +} \ No newline at end of file diff --git a/src/crt0.s b/src/crt0.s new file mode 100644 index 0000000..93000cf --- /dev/null +++ b/src/crt0.s @@ -0,0 +1,172 @@ + .section .pretext + .global initialize +initialize: + sts.l pr, @-r15 + + ! set up TLB + mov.l Hmem_SetMMU, r3 + mov.l address_one, r4 ! 0x8102000 + mov.l address_two, r5 ! 0x8801E000 + jsr @r3 ! _Hmem_SetMMU + mov #108, r6 + + ! clear the BSS + mov.l bbss, r4 ! start + mov.l ebss, r5 ! end + bra L_check_bss + mov #0, r6 +L_zero_bss: + mov.l r6, @r4 ! zero and advance + add #4, r4 +L_check_bss: + cmp/hs r5, r4 + bf L_zero_bss + + ! Copy the .data + mov.l bdata, r4 ! dest + mov.l edata, r5 ! dest limit + mov.l romdata, r6 ! source + bra L_check_data + nop +L_copy_data: + mov.l @r6+, r3 + mov.l r3, @r4 + add #4, r4 +L_check_data: + cmp/hs r5, r4 + bf L_copy_data + + mov.l bbss, r4 + mov.l edata, r5 + sub r4, r5 ! size of .bss and .data sections + add #4, r5 + mov.l bssdatasize, r4 + mov.l r5, @r4 + + mov.l GLibAddinAplExecutionCheck, r2 + mov #0, r4 + mov #1, r5 + jsr @r2 ! _GLibAddinAplExecutionCheck(0,1,1); + mov r5, r6 + + mov.l CallbackAtQuitMainFunction, r3 + mov.l exit_handler, r4 + jsr @r3 ! _CallbackAtQuitMainFunction(&exit_handler) + nop + mov.l main, r3 + jmp @r3 ! _main() + lds.l @r15+, pr + +_exit_handler: + mov.l r14, @-r15 + mov.l r13, @-r15 + mov.l r12, @-r15 + sts.l pr, @-r15 + + mov.l Bdel_cychdr, r14 + jsr @r14 ! _Bdel_cychdr + mov #6, r4 + jsr @r14 ! _Bdel_cychdr + mov #7, r4 + jsr @r14 ! _Bdel_cychdr + mov #8, r4 + jsr @r14 ! _Bdel_cychdr + mov #9, r4 + jsr @r14 ! _Bdel_cychdr + mov #10, r4 + + mov.l BfileFLS_CloseFile, r12 + mov #4, r14 + mov #0, r13 +L_close_files: + jsr @r12 ! _BfileFLS_CloseFile + mov r13, r4 + add #1, r13 + cmp/ge r14, r13 + bf L_close_files + + mov.l flsFindClose, r12 + mov #0, r13 +L_close_finds: + jsr @r12 ! _flsFindClose + mov r13, r4 + add #1, r13 + cmp/ge r14, r13 + bf L_close_finds + + lds.l @r15+, pr + mov.l @r15+, r12 + mov.l @r15+, r13 + mov.l Bkey_Set_RepeatTime_Default, r2 + jmp @r2 ! _Bkey_Set_RepeatTime_Default + mov.l @r15+, r14 + +.align 4 +address_two: .long 0x8801E000 +address_one: .long 0x8102000 +Hmem_SetMMU: .long _Hmem_SetMMU +GLibAddinAplExecutionCheck: .long _GLibAddinAplExecutionCheck +CallbackAtQuitMainFunction: .long _CallbackAtQuitMainFunction +Bdel_cychdr: .long _Bdel_cychdr +BfileFLS_CloseFile: .long _BfileFLS_CloseFile +flsFindClose: .long _flsFindClose +Bkey_Set_RepeatTime_Default: .long _Bkey_Set_RepeatTime_Default +bbss: .long _bbss +ebss: .long _ebss +edata: .long _edata +bdata: .long _bdata +romdata: .long _romdata +bssdatasize: .long _bssdatasize + +exit_handler: .long _exit_handler +main: .long _main + +_Hmem_SetMMU: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x3FA + +_Bdel_cychdr: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x119 + +_BfileFLS_CloseFile: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x1E7 + +_Bkey_Set_RepeatTime_Default: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x244 + +_CallbackAtQuitMainFunction: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x494 + +_flsFindClose: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x218 + +_GLibAddinAplExecutionCheck: + mov.l sc_addr, r2 + mov #0x13, r0 + jmp @r2 + nop +sc_addr: .long 0x80010070 +.end diff --git a/src/message.cpp b/src/message.cpp new file mode 100644 index 0000000..42bbaa0 --- /dev/null +++ b/src/message.cpp @@ -0,0 +1,97 @@ +#include "libJelling/message.h" + +Message::Message(){ + this->isHeader = 0; + this->isType = 0; + this->isID = 0; + this->isSender = 0; + this->msg = (char*)NULL; +} + +int Message::init(const char* type, int ID, const char* sender,const char* message){ + if(setType(type)) return INVALID_TYPE; + if(setMessage(message)) return NOT_ENOUGH_RAM; + setID((unsigned int)ID); + if(setSender(sender)) return TOO_LONG; + return 0; +} + +int Message::setType(const char *typeH){ + memcpy(this->type, typeH, 3); + this->isType = 1; + return 0; +} + +int Message::setID(unsigned int ID){ + memcpy(&this->ID, &ID, sizeof(int)); + this->isID = 1; + return 0; +} + +int Message::setSender(const char *sender){ + memcpy(this->sender, sender, 10); + this->isSender = 1; + return 0; +} + +int Message::setMessage(const char *message){ + int length; + length = strlen(message) + 49; + this->msg = (char*)realloc(this->msg, length); + if(this->msg == NULL) return NOT_ENOUGH_RAM; + memcpy(this->msg+48, message, length-48); + return 0; +} + +int Message::setTotalMessage(char *message){ + this->msg = message; + this->isHeader = 1; + return 0; +} + +char* Message::getTime(){ + if(this->isHeader){ + return this->msg; + }else{ + return (char*)NULL; + } +} + +char* Message::getType(){ + if(this->isHeader){ + return this->msg+19; + }else if(this->isType){ + return this->type; + }else{ + return (char*)NULL; + } +} + +int Message::getID(){ + if(this->isHeader){ + return (unsigned int)this->msg+22; + }else if(this->isID){ + return this->ID; + }else{ + return -1; + } +} + +char* Message::getSender(){ + if(this->isHeader){ + return this->msg+26; + }else if(this->isSender){ + return this->sender; + }else{ + return (char*)NULL; + } +} + +int Message::getLength(){ + if(this->msg == NULL) return -1; + return strlen(this->msg+48)+1; +} + +unsigned char* Message::getMessage(){ + return (unsigned char*)this->msg+48; +} \ No newline at end of file diff --git a/src/module.cpp b/src/module.cpp new file mode 100644 index 0000000..5d7d5c7 --- /dev/null +++ b/src/module.cpp @@ -0,0 +1,37 @@ +#include "libJelling/module.h" + +int Module::setName(char *string){ + char buffer[28] = "AT+NAME"; + if(strlen(string) > 20) return TOO_LONG; + strcat(buffer,(const char*)string); + return set((unsigned char*)buffer); +} + +int Module::setPassword(char *string){ + char buffer[11] = "AT+PIN"; + if(strlen(string) > 4) return TOO_LONG; + else if(strlen(string) < 4) return TOO_SHORT; + strcat(buffer, (const char*)string); + return set((unsigned char*)buffer); +} + +int Module::set(unsigned char *string){ + int RTCTime; + unsigned char conf[6] = {0, 5, 0, 0, 0, 0}; + unsigned char buffer[2]; + short *size = NULL; + Serial_Open(conf); + Serial_ClearReceiveBuffer(); + if(Serial_WriteBytes(string, strlen((const char*)string)+1)) return WRITE_ERROR; + + RTCTime = RTC_GetTicks(); + while(Serial_GetRxBufferSize()<2){ + if((RTC_GetTicks() - RTCTime)/RTC > 1000){ + return BAD_RESPONSE; + } + } + Serial_ReadBytes(buffer, 2, size); + if(buffer[0] == 'O' && buffer[1] == 'K') return 0; + else return BAD_RESPONSE; + +} \ No newline at end of file diff --git a/src/others.c b/src/others.c new file mode 100644 index 0000000..d6bab2d --- /dev/null +++ b/src/others.c @@ -0,0 +1,27 @@ +#include "others.h" + +int tabcmp(const char** tab, int size, char* string){ + for(int i=0; i= 0) { + do{ + *--p = '0' + (i % 10); + i /= 10; + }while (i != 0); + return p; + }else { + do { + *--p = '0' - (i % 10); + i /= 10; + }while (i != 0); + *--p = '-'; + } + return p; +} diff --git a/src/syscall.s b/src/syscall.s new file mode 100644 index 0000000..73cf661 --- /dev/null +++ b/src/syscall.s @@ -0,0 +1,130 @@ +.global _Serial_ReadByte +_Serial_Readbyte: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x40C + +.global _Serial_ReadBytes +_Serial_ReadBytes: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x40D + +.global _Serial_WriteByte +_Serial_WriteByte: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x40E + +.global _Serial_WriteBytes +_Serial_WriteBytes: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x40F + +.global _Serial_WriteByteFIFO +_Serial_WriteByteFIFO: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x410 + +.global _Serial_GetRxBufferSize +_Serial_GetRxBufferSize: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x411 + +.global _Serial_GetTxBufferFreeCapacity +_Serial_GetTxBufferFreeCapacity: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x412 + +.global _Serial_ClearReceiveBuffer +_Serial_ClearReceiveBuffer: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x413 + +.global _Serial_ClearTransmitBuffer +_Serial_ClearTransmitBuffer: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x414 + +.global _Serial_Open +_Serial_Open: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x418 + +.global _Serial_Close +_Serial_Close: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x419 + +.global _Serial_IsOpen +_Serial_IsOpen: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x425 + +.global _Timer_Install +_Timer_Install: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x118 + +.global _Timer_Start +_Timer_Start: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x11A + +.global _Timer_Stop +_Timer_Stop: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x11B + +.global _RTC_GetTicks +_RTC_GetTicks: + mov.l sc_addr, r2 + mov.l 1f, r0 + jmp @r2 + nop +1: .long 0x03B + +sc_addr: .long 0x80010070 + diff --git a/src/syscall.src b/src/syscall.src new file mode 100644 index 0000000..436ab43 --- /dev/null +++ b/src/syscall.src @@ -0,0 +1,29 @@ + .SECTION P,CODE,ALIGN=4 + + .MACRO SYSCALL FUNO, SYSCALLNAME, TAIL=nop + .export \SYSCALLNAME' +\SYSCALLNAME' + mov.l #h'\FUNO, r0 + mov.l #H'80010070, r2 + jmp @r2 + \TAIL' + .ENDM + + SYSCALL 040C, _Serial_ReadByte + SYSCALL 040D, _Serial_ReadBytes + SYSCALL 040E, _Serial_WriteByte + SYSCALL 040F, _Serial_WriteBytes + SYSCALL 0410, _Serial_WriteByteFIFO + SYSCALL 0411, _Serial_GetRxBufferSize + SYSCALL 0412, _Serial_GetTxBufferFreeCapacity + SYSCALL 0413, _Serial_ClearReceiveBuffer + SYSCALL 0414, _Serial_ClearTransmitBuffer + SYSCALL 0418, _Serial_Open + SYSCALL 0419, _Serial_Close + SYSCALL 0422, _Serial_Peek + SYSCALL 0425, _Serial_IsOpen + SYSCALL 0118, _Timer_Install + SYSCALL 011A, _Timer_Start + SYSCALL 011B, _Timer_Stop + SYSCALL 003B, _RTC_GetTicks(); + .end