diff --git a/.gitignore b/.gitignore index 2de545f..4f6b597 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.o *.a *.swp +release diff --git a/firmware/applications/default.c b/firmware/applications/default.c index ea52100..b5a357c 100644 --- a/firmware/applications/default.c +++ b/firmware/applications/default.c @@ -108,16 +108,24 @@ void tick_default(void) { EVERY(50,0){ - /* if(GLOBAL(chargeled)){ - IOCON_PIO1_11 = 0x0; - gpioSetDir(RB_LED3, gpioDirection_Output); - if(GetChrgStat()) - gpioSetValue (RB_LED3, 1); - else - gpioSetValue (RB_LED3, 0); + char iodir= (GPIO_GPIO1DIR & (1 << (11) ))?1:0; + if(GetChrgStat()) { + if (iodir == gpioDirection_Input){ + IOCON_PIO1_11 = 0x0; + gpioSetDir(RB_LED3, gpioDirection_Output); + gpioSetValue (RB_LED3, 1); + LightCheck(); + } + } else { + if (iodir != gpioDirection_Input){ + gpioSetValue (RB_LED3, 0); + gpioSetDir(RB_LED3, gpioDirection_Input); + IOCON_PIO1_11 = 0x41; + LightCheck(); + } + } }; - */ if(GetVoltage()<3600){ IOCON_PIO1_11 = 0x0; diff --git a/firmware/basic/config.c b/firmware/basic/config.c index 6ae9cdc..e0eba99 100644 --- a/firmware/basic/config.c +++ b/firmware/basic/config.c @@ -28,7 +28,7 @@ struct CDESC the_config[]= { {"flamemaxw", 255, 1, 255, 1, CFG_TYPE_FLAME}, {"flameminw", 0x8f, 1, 255, 1, CFG_TYPE_FLAME}, {"l0nick", 0, 0, 1 , 0, 0}, - {"chargeled", 0, 0, 1 , 0, CFG_TYPE_GONE}, + {"chargeled", 0, 0, 1 , 0, 0}, {"positionleds", 0, 0, 1 , 0, 0}, { NULL, 0, 0, 0 , 0, 0}, }; diff --git a/firmware/basic/night.c b/firmware/basic/night.c index 97387d4..4a6d706 100644 --- a/firmware/basic/night.c +++ b/firmware/basic/night.c @@ -15,23 +15,27 @@ void LightCheck(void){ char iodir; iocon=IOCON_PIO1_11; -// iodir=gpioGetDir(RB_LED3); //LED3 is on pin 11 iodir= (GPIO_GPIO1DIR & (1 << (11) ))?1:0; - gpioSetDir(RB_LED3, gpioDirection_Input); - IOCON_PIO1_11 = IOCON_PIO1_11_FUNC_AD7|IOCON_PIO1_11_ADMODE_ANALOG; - light-=light/SAMPCT; - light += (adcRead(7)/2); - - gpioSetDir(RB_LED3, iodir); - IOCON_PIO1_11=iocon; + //gpioSetDir(RB_LED3, gpioDirection_Input); + if (iodir == gpioDirection_Input) { + IOCON_PIO1_11 = IOCON_PIO1_11_FUNC_AD7|IOCON_PIO1_11_ADMODE_ANALOG; + light-=light/SAMPCT; + light += (adcRead(7)/2); - if(_isnight && light/SAMPCT>(threshold+RANGE)) - _isnight=0; + gpioSetDir(RB_LED3, iodir); + IOCON_PIO1_11=iocon; - if(!_isnight && light/SAMPCT(threshold+RANGE)) + _isnight=0; + + if(!_isnight && light/SAMPCT='A' && MO_TYPE(buf)<='C') || - (MO_TYPE(buf)>='A' && MO_TYPE(buf)<='C')) + (MO_TYPE(buf)>='a' && MO_TYPE(buf)<='c')) meshmsg=1; memcpy(mpkt->pkt,buf,MESHPKTSIZE); diff --git a/firmware/l0dable/debug.c b/firmware/l0dable/debug.c index 2c65d1f..b57a296 100644 --- a/firmware/l0dable/debug.c +++ b/firmware/l0dable/debug.c @@ -165,12 +165,72 @@ void getsp(void) { dx=DoString(0,dy,"Done."); }; +void m_time_details(int select) { + getInputWaitRelease(); + + while(getInputWaitTimeout(50) == BTN_NONE){ + lcdClear(); + MPKT *mpkt = &meshbuffer[select]; + uint8_t *pkt = mpkt->pkt; + + if (!mpkt->flags & MF_USED) + lcdPrint(""); + else { + lcdPrint("Type: "); + char c[2] = {0, 0}; + c[0] = mpkt->pkt[0]; + lcdPrint(c); + lcdNl(); + + lcdPrint("Gen: "); + lcdPrintInt(MO_GEN(pkt) & 0xff); + lcdNl(); + + lcdPrint("Time: "); + lcdPrintInt(MO_TIME(pkt) & 0xffff); + lcdNl(); + lcdPrint("Body: "); + lcdNl(); + + int x = 0; + for(uint8_t *body = MO_BODY(pkt); body < (pkt + 30); body++) { + if (*body >= ' ' && *body < 128) { + if (x > 12) { + lcdNl(); + x = 0; + } + + char c[2] = {*body, 0}; + lcdPrint(c); + x++; + } else { + if (x > 10) { + lcdNl(); + x = 0; + } + + lcdPrint("\\"); + lcdPrintInt(*body & 0xff); + x += 2; + if (*body > 9) + x++; + if (*body > 99) + x++; + } + } + } + + lcdRefresh(); + } +} + void m_time(void){ struct tm* tm; + int select=0; char c[2]={0,0}; getInputWaitRelease(); delayms(100); - do{ + while(1) { lcdClear(); tm= mygmtime(getSeconds()); lcdPrint(IntToStr(tm->tm_hour,2,F_LONG)); @@ -199,6 +259,12 @@ void m_time(void){ }; lcdPrintln(">"); + lcdPrint(" "); + for(int i=0; i= MESHBUFSIZE) + select = 0; + break; + case BTN_ENTER: + m_time_details(select); + break; + case BTN_UP: + case BTN_DOWN: + // Exit + return; + } + if (key != BTN_NONE) + getInputWaitRelease(); + } }; void ChkFunk(){ diff --git a/firmware/l0dable/invaders.c b/firmware/l0dable/invaders.c index 94d177c..2e9dc58 100644 --- a/firmware/l0dable/invaders.c +++ b/firmware/l0dable/invaders.c @@ -178,9 +178,11 @@ static bool highscore_set(uint32_t score, char nick[]) { static uint32_t highscore_get(char nick[]){ MPKT * mpkt= meshGetMessage('i'); - - strcpy(nick,(char*)MO_BODY(mpkt->pkt)); - + char * packet_nick = (char*)MO_BODY(mpkt->pkt); + // the packet crc end is already zeroed + if(MAXNICKpkt); } diff --git a/firmware/l0dable/mktable.pl b/firmware/l0dable/mktable.pl index ad54420..cceebe7 100755 --- a/firmware/l0dable/mktable.pl +++ b/firmware/l0dable/mktable.pl @@ -77,7 +77,12 @@ sub wanted { File::Find::find({wanted => \&wanted}, '.'); print C ""; -print C qq!__attribute__ ((used, section("table"))) const void * TheTable[]={!; +print C < +#include +#include "basic/basic.h" +#include "lcd/render.h" +#include "lcd/display.h" +#include "usetable.h" +#include "lcd/fonts.h" +#include "lcd/fonts/invaders.h" +#include "lcd/fonts/invaders.c" + +void ram(void) +{ + bool step = true; + const int minX = 10; + const int minY = 10; + const int maxX = 50; + const int maxY = 30; + const int space = 15; + const int delaytime = 150; + int x = minX; + int y = minY; + int u = 0; + int dir = 0; + int dx,dy; + + + dx=DoString(0,0,nickname); + dx=(RESX-dx)/2; + if(dx<0) + dx=0; + dy=40; + + while(1){ + lcdFill(0); + font = &Font_Invaders; + // Draw UFO + DoChar(-15+u,1,'U'); + u+=2; + if(u > 1337) u=0; + //Draw Invaders + DoChar(x,y,step?'a':'A'); + DoChar(x+space,y,step?'b':'B'); + DoChar(x+2*space,y,step?'c':'C'); + switch (dir){ + // move left + case 0: + x++; + if(x == maxX) dir++; + break; + // move down on right end + case 1: + y++; + dir++; + if(y == maxY) y=minY; + break; + // move left + case 2: + x--; + if(x==minX) dir++; + break; + // move down on left end + case 3: + y++; + dir++; + if(y == maxY) y=minY; + break; + } + dir %= 4; + font = NULL; + DoString(dx,dy,nickname); + lcdDisplay(); + if(getInputRaw()!=BTN_NONE) return; + step = !step; + delayms_queue_plus(delaytime,0); + } +} diff --git a/firmware/l0dable/nick_life.c b/firmware/l0dable/nick_life.c index 4faed8f..818c232 100644 --- a/firmware/l0dable/nick_life.c +++ b/firmware/l0dable/nick_life.c @@ -256,10 +256,6 @@ static void reset_area() { } } -#ifdef SIMULATOR -extern uint32_t getRandom(void); -#endif - static void random_area(struct bitset *area, uchar x0, uchar y0, uchar x1, uchar y1,uchar value) { for(uchar x=x0; x<=x1; ++x) { for(uchar y=y0; y<=y1; ++y) { diff --git a/firmware/l0dable/nick_matrix.c b/firmware/l0dable/nick_matrix.c new file mode 100644 index 0000000..8e6837d --- /dev/null +++ b/firmware/l0dable/nick_matrix.c @@ -0,0 +1,113 @@ +#include + +#include "basic/basic.h" +#include "basic/config.h" +#include "lcd/render.h" + +#include "usetable.h" + +#define SCREEN_WIDTH 13 +#define SCREEN_HEIGHT 8 + +#define FONT_WIDTH 7 +#define FONT_HEIGHT 8 + +#define MATRIX_LINES_LENGTH 15 + +#define MAX_LINE_LENGTH 6 + +#define TICKS_SHOW_NICKNAME 100 +#define TICKS_HIDE_NICKNAME 50 +#define NICKNAME_ACTION_SHOW 1 +#define NICKNAME_ACTION_HIDE 2 + +void ram(void){ + lcdClear(); + + // nickname helper variables + int nickname_len = strlen(GLOBAL(nickname)); + int nickname_posx = (SCREEN_WIDTH - nickname_len) / 2; + int nickname_posy = SCREEN_HEIGHT / 2; + + // state variables for show/hide effect + int ticks_until_next_nickname_action = TICKS_SHOW_NICKNAME; + int nickname_action = NICKNAME_ACTION_SHOW; + + struct matrix_line { + int head_x, head_y; + int cur_length; + int length; + } matrix_lines[MATRIX_LINES_LENGTH]; + + // initialize matrix_lines + for (int i = 0; i < MATRIX_LINES_LENGTH; i++) { + matrix_lines[i].cur_length = -1; + } + + // main loop + while (1) { + // for every matrix line + for(int i = 0; icur_length == -1) { + ml->head_x = getRandom() % SCREEN_WIDTH; + ml->head_y = getRandom() % SCREEN_HEIGHT - 1; + ml->length = getRandom() % MAX_LINE_LENGTH + 3; + ml->cur_length = 0; + } + // set new char + if (ml->head_y < SCREEN_HEIGHT-1) { + ml->head_y++; + char chr; + int chrpos = ml->head_x - nickname_posx; + if (nickname_action == NICKNAME_ACTION_SHOW + && ml->head_y == nickname_posy + && chrpos >= 0 && chrpos < nickname_len) { + // show the nickname + chr = GLOBAL(nickname)[chrpos]; + } else { + chr = getRandom() % 95 + 33; + } + DoChar(ml->head_x * FONT_WIDTH, ml->head_y * FONT_HEIGHT, chr); + ml->cur_length++; + } + // remove char (when length or bottom is reached) + if (ml->cur_length > ml->length || ml->head_y >= SCREEN_HEIGHT-1) { + int chrpos = ml->head_x - nickname_posx; + if ( ! (nickname_action == NICKNAME_ACTION_SHOW + && (ml->head_y - ml->cur_length) == nickname_posy + && chrpos >= 0 && chrpos < nickname_len + )) { + // only delete, if it's not the nickname + DoChar(ml->head_x * FONT_WIDTH, (ml->head_y - ml->cur_length) * FONT_HEIGHT, ' '); + } + ml->cur_length--; + } + } + lcdDisplay(); + // show and hide nickname + ticks_until_next_nickname_action--; + if (ticks_until_next_nickname_action <= 0) { + switch (nickname_action) { + case NICKNAME_ACTION_SHOW: + nickname_action = NICKNAME_ACTION_HIDE; + ticks_until_next_nickname_action = TICKS_HIDE_NICKNAME; + // new nickname_pos + nickname_posx = getRandom() % (SCREEN_WIDTH - nickname_len); + nickname_posy = getRandom() % SCREEN_HEIGHT; + break; + case NICKNAME_ACTION_HIDE: + nickname_action = NICKNAME_ACTION_SHOW; + ticks_until_next_nickname_action = TICKS_SHOW_NICKNAME; + break; + } + } + // Exit on any key + int key = getInputRaw(); + if(key!= BTN_NONE) + return; + // sleep and process queue (e. g. meshnetwork) + delayms_queue_plus(90,0); + }; +}; diff --git a/firmware/l0dable/nick_time.c b/firmware/l0dable/nick_time.c new file mode 100755 index 0000000..8f393a5 --- /dev/null +++ b/firmware/l0dable/nick_time.c @@ -0,0 +1,58 @@ +#include + +#include "basic/basic.h" +#include "basic/config.h" + +#include "lcd/lcd.h" +#include "lcd/print.h" + +#include "usetable.h" + +void ram(void) +{ + struct tm* tm; + char timestr[9]="00:00:00"; + int dx1=0; + int dx2=0; + int dy1=0; + int dy2=0; + setExtFont(GLOBAL(nickfont)); + + dx1=DoString(0,0,GLOBAL(nickname)); + dx1=(RESX-dx1)/2; + if(dx1<0) + { + dx1=0; + } + dy1=(RESY/2-getFontHeight())/2; + dy2=RESY/2 + dy1; + while(getInputRaw()==BTN_NONE) + { + tm = mygmtime(getSeconds()); + + timestr[0] = '0' + tm->tm_hour / 10; + timestr[1] = '0' + tm->tm_hour % 10; + + timestr[3] = '0' + tm->tm_min / 10; + timestr[4] = '0' + tm->tm_min % 10; + + timestr[6] = '0' + tm->tm_sec / 10; + timestr[7] = '0' + tm->tm_sec % 10; + + dx2=DoString(0,0,×tr[0]); + dx2=(RESX-dx2)/2; + if(dx2<0) + { + dx2=0; + } + + lcdClear(); + + DoString(dx1,dy1,GLOBAL(nickname)); + DoString(dx2,dy2,×tr[0]); + + lcdRefresh(); + delayms_queue_plus(10,0); + } + return; +} diff --git a/firmware/l0dable/snake.c b/firmware/l0dable/snake.c.disabled similarity index 100% rename from firmware/l0dable/snake.c rename to firmware/l0dable/snake.c.disabled diff --git a/firmware/l0dable/starfld.c b/firmware/l0dable/starfld.c new file mode 100644 index 0000000..1a41eef --- /dev/null +++ b/firmware/l0dable/starfld.c @@ -0,0 +1,73 @@ +#include + +#include "basic/basic.h" +#include "basic/config.h" + +#include "lcd/lcd.h" +#include "lcd/print.h" + +#include "usetable.h" + +#define NUM_STARS 150 + +typedef struct { + short x, y, z, speed; +} s_star; + +static s_star stars[NUM_STARS]; + +void init_star(s_star *star, int z); + +void ram(void) +{ + short centerx = RESX >> 1; + short centery = RESY >> 1; + short i; + + for (i = 0; i < NUM_STARS; i++) { + init_star(stars + i, i + 1); + } + + while(getInputRaw()==BTN_NONE){ + lcdClear(); + + for (i = 0; i < NUM_STARS; i++) { + stars[i].z -= stars[i].speed; + + if (stars[i].z <= 0) + init_star(stars + i, i + 1); + + short tempx = ((stars[i].x * 30) / stars[i].z) + centerx; + short tempy = ((stars[i].y * 30) / stars[i].z) + centery; + + if (tempx < 0 || tempx > RESX - 1 || tempy < 0 || tempy > RESY - 1) { + init_star(stars + i, i + 1); + continue; + } + + lcdSetPixel(tempx, tempy, 1); + if (stars[i].z < 50) { + lcdSetPixel(tempx + 1, tempy, 1); + } + if (stars[i].z < 20) { + lcdSetPixel(tempx, tempy + 1, 1); + lcdSetPixel(tempx + 1, tempy + 1, 1); + } + } + + lcdRefresh(); + + delayms_queue_plus(50,0); + } +} + +void init_star(s_star *star, int z) +{ + star->x = (getRandom() % RESX) - (RESX >> 1); + star->y = (getRandom() % RESY) - (RESY >> 1); + star->z = z; + star->speed = (getRandom() % 4) + 1; + + return; +} + diff --git a/firmware/l0dable/static.c b/firmware/l0dable/static.c new file mode 100755 index 0000000..c1610c3 --- /dev/null +++ b/firmware/l0dable/static.c @@ -0,0 +1,33 @@ +#include +#include + +#include "basic/basic.h" +#include "basic/config.h" +#include "basic/random.h" + +#include "lcd/render.h" +#include "lcd/display.h" + +#include "lcd/fonts.h" +#include "lcd/fonts/invaders.h" + +#include "funk/mesh.h" + +#include "usetable.h" + + +void ram(void) +{ + int x, y; + + while( getInputRaw() == BTN_NONE ) { + for( x = 0; x < RESX; x++ ) { + for( y = 0; y < RESY_B; y++ ) { + lcdBuffer[y*RESX+x]=getRandom()&0xff; + } + } + lcdDisplay(); + } + return; +} + diff --git a/firmware/lcd/display.c b/firmware/lcd/display.c index 40bd2ae..38b280b 100644 --- a/firmware/lcd/display.c +++ b/firmware/lcd/display.c @@ -9,6 +9,9 @@ #include "basic/config.h" #include "usb/usbmsc.h" + +#undef N1600 + /**************************************************************************/ /* Utility routines to manage nokia display */ /**************************************************************************/ @@ -143,7 +146,7 @@ void lcdInit(void) { * 0xd0+x black lines from top? (-0xdf?) * */ - +#ifndef N1600 lcdWrite(TYPE_CMD,0xE2); delayms(5); lcdWrite(TYPE_CMD,0xAF); // Display ON @@ -152,12 +155,53 @@ void lcdInit(void) { lcdWrite(TYPE_CMD,0x2F); lcdWrite(TYPE_CMD,0xB0); lcdWrite(TYPE_CMD,0x10); - lcdWrite(TYPE_CMD,0x00); + // lcdWrite(TYPE_CMD,0x00); +#else + delayms(10); + lcdWrite(TYPE_CMD,0x01); //sw reset + delayms(10); + lcdWrite(TYPE_CMD,0x11); //sleepout + delayms(10); + + lcdWrite(TYPE_CMD,0x36); //MADCTL MY MX V LAO RGB X X X + lcdWrite(TYPE_DATA,0x00); + lcdWrite(TYPE_CMD,0x25); // contrast... + lcdWrite(TYPE_DATA,0x3F); + delayms(10); + + lcdWrite(TYPE_CMD,0x29); //display on + + lcdWrite(TYPE_CMD,0xBA); //data order + lcdWrite(TYPE_DATA,0x07); + lcdWrite(TYPE_DATA,0x15); + + lcdWrite(TYPE_CMD,0x25); //contrast... again? + lcdWrite(TYPE_DATA,0x3f); + + lcdWrite(TYPE_CMD,0x11); //Sleepout + lcdWrite(TYPE_CMD,0x13); //display mode normal + + lcdWrite(TYPE_CMD,0X37); //vscroll addr + lcdWrite(TYPE_DATA,0x00); + + lcdWrite(TYPE_CMD,0x3A); // COLMOD pixel format 4=12, 5=16, 6=18 + lcdWrite(TYPE_DATA,0x05); + + lcdWrite(TYPE_CMD,0x2A); //no clue... I think it's setting up the size of the display? + lcdWrite(TYPE_DATA,0); + lcdWrite(TYPE_DATA,98-1); //98 = width + + lcdWrite(TYPE_CMD,0x2B); + lcdWrite(TYPE_DATA,0); + lcdWrite(TYPE_DATA,70-1); //70 = height + +#endif + /* uint16_t i; for(i=0; i<100; i++) lcdWrite(TYPE_DATA,0x00); - + */ lcd_deselect(); } @@ -194,13 +238,25 @@ bool lcdGetPixel(char x, char y){ return byte & (1 << y_off); } +#define THECOLOR_R 0x0 +#define THECOLOR_G 0x80 +#define THECOLOR_B 0x0 + void lcdDisplay(void) { char byte; lcd_select(); +#ifndef N1600 lcdWrite(TYPE_CMD,0xB0); lcdWrite(TYPE_CMD,0x10); lcdWrite(TYPE_CMD,0x00); +#else + lcdWrite(TYPE_CMD,0x2C); + +#endif + + +#ifndef N1600 uint16_t i,page; for(page=0; page> 3); + framecolor= ((frame_r&0xF8) << 8) | ((frame_g&0xFC)<<3) | ((frame_b&0xF8) >> 3); + backcolor= ((br&0xF8) << 8) | ((bg&0xFC)<<3) | ((bb&0xF8) >> 3); + + //top line of the frame... + for(i=0;i<98;i++){ + lcdWrite(TYPE_DATA,framecolor>>8); + lcdWrite(TYPE_DATA,framecolor&0xFF); + } + + for(y=RESY;y>0;y--){ + //left line of the frame + lcdWrite(TYPE_DATA,framecolor>>8); + lcdWrite(TYPE_DATA,framecolor&0xFF); + + for(x=RESX;x>0;x--){ + if(GLOBAL(lcdmirror)) + px=lcdGetPixel(RESX-x+1,y-1); + else + px=lcdGetPixel(x-1,y-1); + + if((!px)^(!GLOBAL(lcdinvert))) actualcolor=color; + else actualcolor=backcolor; /* white */ + + lcdWrite(TYPE_DATA,actualcolor>>8); + lcdWrite(TYPE_DATA,actualcolor&0xFF); + } + //right line of the frame + lcdWrite(TYPE_DATA,framecolor>>8); + lcdWrite(TYPE_DATA,framecolor&0xFF); + } + + //bottom line of the frame + for(i=0;i<98;i++){ + lcdWrite(TYPE_DATA,framecolor>>8); + lcdWrite(TYPE_DATA,framecolor&0xFF); + } +#endif lcd_deselect(); } @@ -225,12 +327,21 @@ inline void lcdInvert(void) { } void lcdSetContrast(int c) { + #ifndef N1600 c+=0x80; if(c>0x9F) return; lcd_select(); lcdWrite(TYPE_CMD,c); lcd_deselect(); + #else + if(c>=0x40) + return; + lcd_select(); + lcdWrite(TYPE_CMD,0x25); + lcdWrite(TYPE_DATA,4*c); + lcd_deselect(); + #endif }; void lcdSetInvert(int c) { diff --git a/firmware/lcd/render.c b/firmware/lcd/render.c index c98b147..37f0110 100644 --- a/firmware/lcd/render.c +++ b/firmware/lcd/render.c @@ -223,7 +223,9 @@ int DoChar(int sx, int sy, int c){ _getFontData(SEEK_DATA,toff); UINT res; UINT readbytes; - res = f_read(&file, charBuf, width*height, &readbytes); + UINT size = width * height; + if(size > MAXCHR) size = MAXCHR; + res = f_read(&file, charBuf, size, &readbytes); if(res != FR_OK || readbytes MAXCHR) size = MAXCHR; + res = f_read(&file, charBuf, size, &readbytes); if(res != FR_OK || readbytes