Merge branch 'master' into meshdebug

This commit is contained in:
Stefan `Sec` Zehl 2012-01-31 18:09:01 +01:00
commit 54d4c31250
31 changed files with 1218 additions and 247 deletions

4
firmware/.gitignore vendored
View File

@ -1,5 +1,5 @@
firmware.bin *.bin
firmware.elf *.elf
lpc1xxx/memory.ld lpc1xxx/memory.ld
applications/wrapper.c applications/wrapper.c
lcd/allfonts.h lcd/allfonts.h

View File

@ -37,13 +37,13 @@ ifdef APP
OUTFILE=$(APP) OUTFILE=$(APP)
endif endif
LDFLAGS+= -Wl,--gc-sections LDFLAGS+= --gc-sections
OBJS += lpc1xxx/$(TARGET)_handlers.o lpc1xxx/LPC1xxx_startup.o OBJS += lpc1xxx/$(TARGET)_handlers.o lpc1xxx/LPC1xxx_startup.o
########################################################################## ##########################################################################
# Startup files # Startup files
########################################################################## ##########################################################################
LDLIBS = -lm LDLIBS =
LDLIBS += -Lapplications -lapp LDLIBS += -Lapplications -lapp
LDLIBS += -Lfunk -lfunk LDLIBS += -Lfunk -lfunk
LDLIBS += -Lusbcdc -lusbcdc LDLIBS += -Lusbcdc -lusbcdc
@ -111,7 +111,7 @@ $(LD_TEMP):
-@echo "INCLUDE $(LD_SCRIPT)" >> $(LD_TEMP) -@echo "INCLUDE $(LD_SCRIPT)" >> $(LD_TEMP)
$(OUTFILE).elf: $(OBJS) $(SYS_OBJS) $(SUBDIRS) $(LPCFIX) $(LD_TEMP) $(OUTFILE).elf: $(OBJS) $(SYS_OBJS) $(SUBDIRS) $(LPCFIX) $(LD_TEMP)
$(CC) $(LDFLAGS) -T $(LD_TEMP) -o $(OUTFILE).elf $(OBJS) $(LDLIBS) $(LD) $(LDFLAGS) -T $(LD_TEMP) -o $(OUTFILE).elf $(OBJS) $(LDLIBS)
-@echo "" -@echo ""
$(SIZE) $(OUTFILE).elf $(SIZE) $(OUTFILE).elf
-@echo "" -@echo ""

View File

@ -42,7 +42,7 @@ CPU_TYPE = cortex-$(CORTEX_TYPE)
# Compiler settings, parameters and flags # Compiler settings, parameters and flags
########################################################################## ##########################################################################
CFLAGS = -std=c99 -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -DRAMCODE=$(RAMCODE) -fno-builtin -Wno-unused-function CFLAGS = -std=c99 -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -DRAMCODE=$(RAMCODE) -fno-builtin -Wno-unused-function -ffreestanding
LDFLAGS = -nostartfiles LDFLAGS = -nostartfiles
ifeq "$(USBSERIAL)" "YES" ifeq "$(USBSERIAL)" "YES"

View File

@ -1,4 +1,13 @@
make flags supported by this Makefile ### A note on the compiler
We are currently using the CodeSourcery gcc (see wiki for link).
You can also use a standard arm cross-gcc
(https://github.com/esden/summon-arm-toolchain)
but please note that this creates larger binaries.
We are talking about 100-200 bytes for firmware.bin,
you will run into space problems with the default firmware.
Sorry about that.
### Make flags supported by this Makefile
APP=<foo> APP=<foo>
- builds "application" foo (check <foo>.c and the <foo> subdir in applications/) - builds "application" foo (check <foo>.c and the <foo> subdir in applications/)
@ -28,5 +37,5 @@ make APP=l0dable LAPP=<l0dablename> (=l0dable.bin)
# build all l0dables # build all l0dables
make l0dables make l0dables
#build one l0dable # build one l0dable
cd l0dables && make <l0dablename>.c0d cd l0dables && make <l0dablename>.c0d

View File

@ -186,6 +186,9 @@ void m_choose(){
case('r'): case('r'):
strcpy(p,"r0type"); strcpy(p,"r0type");
break; break;
case('s'):
strcpy(p,"Snake");
break;
#endif #endif
default: default:
p[0]=*mm; p[0]=*mm;
@ -233,6 +236,9 @@ void m_choose(){
case('r'): case('r'):
strcpy(p,"r0type"); strcpy(p,"r0type");
break; break;
case('s'):
strcpy(p,"Snake");
break;
#endif #endif
}; };
if(tmm[i]>='a' && tmm[i]<='z'){ if(tmm[i]>='a' && tmm[i]<='z'){

View File

@ -18,7 +18,7 @@ void rbInit() {
gpioSetDir(USB_CONNECT, gpioDirection_Output); gpioSetDir(USB_CONNECT, gpioDirection_Output);
gpioSetValue(USB_CONNECT, 1); gpioSetValue(USB_CONNECT, 1);
uint8_t ports[] = { RB_BTN0, RB_BTN1, RB_BTN2, RB_BTN3, RB_BTN4, static uint8_t ports[] = { RB_BTN0, RB_BTN1, RB_BTN2, RB_BTN3, RB_BTN4,
RB_LED0, RB_LED1, RB_LED2, RB_LED0, RB_LED1, RB_LED2,
RB_SPI_SS0, RB_SPI_SS1, RB_SPI_SS2, RB_SPI_SS0, RB_SPI_SS1, RB_SPI_SS2,
RB_SPI_SS3, RB_SPI_SS4, RB_SPI_SS5, RB_SPI_SS3, RB_SPI_SS4, RB_SPI_SS5,

View File

@ -171,12 +171,12 @@ uint16_t crc16(uint8_t * buf, int len);
// menu.c // menu.c
struct MENU_DEF { struct MENU_DEF {
char *text; const char *text;
void (*callback)(void); void (*callback)(void);
}; };
struct MENU { struct MENU {
char *title; const char *title;
struct MENU_DEF entries[]; struct MENU_DEF entries[];
}; };

View File

@ -52,6 +52,7 @@ void * memcpy(void *pDestination, const void *pSource, size_t num)
{ {
unsigned char *pByteDestination; unsigned char *pByteDestination;
unsigned char *pByteSource; unsigned char *pByteSource;
#ifdef FAST_MEMCPY
unsigned int *pAlignedSource = (unsigned int *) pSource; unsigned int *pAlignedSource = (unsigned int *) pSource;
unsigned int *pAlignedDestination = (unsigned int *) pDestination; unsigned int *pAlignedDestination = (unsigned int *) pDestination;
@ -71,6 +72,10 @@ void * memcpy(void *pDestination, const void *pSource, size_t num)
// Copy remaining bytes // Copy remaining bytes
pByteDestination = (unsigned char *) pAlignedDestination; pByteDestination = (unsigned char *) pAlignedDestination;
pByteSource = (unsigned char *) pAlignedSource; pByteSource = (unsigned char *) pAlignedSource;
#else
pByteDestination = (unsigned char *) pDestination;
pByteSource = (unsigned char *) pSource;
#endif
while (num--) { while (num--) {
*pByteDestination++ = *pByteSource++; *pByteDestination++ = *pByteSource++;

View File

@ -8,6 +8,7 @@
#define FLEN 13 #define FLEN 13
/* if count is 0xff (-1) do not fill files and return the count instead */
int getFiles(char files[][FLEN], uint8_t count, uint16_t skip, const char *ext) int getFiles(char files[][FLEN], uint8_t count, uint16_t skip, const char *ext)
{ {
DIR dir; /* Directory object */ DIR dir; /* Directory object */
@ -37,7 +38,9 @@ int getFiles(char files[][FLEN], uint8_t count, uint16_t skip, const char *ext)
continue; continue;
}; };
strcpy(files[pos++],Finfo.fname); if(count != 0xff)
strcpy(files[pos],Finfo.fname);
pos++;
if( pos == count ) if( pos == count )
break; break;
} }
@ -50,17 +53,19 @@ int selectFile(char *filename, const char *extension)
int skip = 0; int skip = 0;
char key; char key;
int selected = 0; int selected = 0;
int file_count = getFiles(NULL, 0xff, 0, extension);
font=&Font_7x8; font=&Font_7x8;
if(!file_count){
lcdPrintln("No Files?");
lcdRefresh();
getInputWait();
getInputWaitRelease();
return -1;
};
while(1){ while(1){
char files[PERPAGE][FLEN]; char files[PERPAGE][FLEN];
int count = getFiles(files, PERPAGE, skip, extension); int count = getFiles(files, PERPAGE, skip, extension);
if(!count){
lcdPrintln("No Files?");
lcdRefresh();
getInputWait();
getInputWaitRelease();
return -1;
};
if(count<PERPAGE && selected==count){ if(count<PERPAGE && selected==count){
skip--; skip--;
@ -88,15 +93,18 @@ int selectFile(char *filename, const char *extension)
files[i][dot]='.'; files[i][dot]='.';
} }
lcdRefresh(); lcdRefresh();
key=getInputWait(); key=getInputWaitRepeat();
getInputWaitRelease();
switch(key){ switch(key){
case BTN_DOWN: case BTN_DOWN:
if( selected < count-1 ){ if( selected < count-1 ){
selected++; selected++;
goto redraw; goto redraw;
}else{ }else{
skip++; if(skip == file_count - PERPAGE) { // wrap to top
selected = 0;
skip = 0;
} else
skip++;
} }
break; break;
case BTN_UP: case BTN_UP:
@ -106,14 +114,20 @@ int selectFile(char *filename, const char *extension)
}else{ }else{
if( skip > 0 ){ if( skip > 0 ){
skip--; skip--;
} else { // wrap to bottom
skip = file_count - PERPAGE;
if(skip < 0) skip = 0;
selected = file_count - skip - 1;
} }
} }
break; break;
case BTN_LEFT: case BTN_LEFT:
getInputWaitRelease();
return -1; return -1;
case BTN_ENTER: case BTN_ENTER:
case BTN_RIGHT: case BTN_RIGHT:
strcpy(filename, files[selected]); strcpy(filename, files[selected]);
getInputWaitRelease();
return 0; return 0;
} }
} }

View File

@ -48,16 +48,16 @@ void initMesh(void){
#define MP_IGNORE 4 #define MP_IGNORE 4
int mesh_sanity(uint8_t * pkt){ int mesh_sanity(uint8_t * pkt){
if(MO_TYPE(pkt)>0x7f || MO_TYPE(pkt)<0x20) if(MO_TYPE(pkt)>0x7f || MO_TYPE(pkt)<0x20)
return MP_SEND|MP_RECV; return MP_SEND;
if(MO_TYPE(pkt)=='T' && MO_BODY(pkt)[5]) if(MO_TYPE(pkt)=='T' && MO_BODY(pkt)[5])
return MP_SEND|MP_RECV; return MP_SEND;
if(MO_TYPE(pkt)=='T' && MO_TIME(pkt)<86400) if(MO_TYPE(pkt)=='T' && MO_TIME(pkt)<86400)
return MP_OK; return MP_OK;
if(MO_TYPE(pkt)>='A' && MO_TYPE(pkt)<='Z'){ if(MO_TYPE(pkt)>='A' && MO_TYPE(pkt)<='Z'){
if(MO_TIME(pkt)>1370340000) /* 4.Jun 2013 */ if(MO_TIME(pkt)>1370340000) /* 4.Jun 2013 */
return MP_SEND|MP_RECV; return MP_SEND;
if(MO_TIME(pkt)<1325376000) /* 1.1.2012 */ if(MO_TIME(pkt)<1325376000) /* 1.1.2012 */
return MP_SEND|MP_RECV; return MP_SEND;
}else if(MO_TYPE(pkt)>='a' && MO_TYPE(pkt)<='z'){ }else if(MO_TYPE(pkt)>='a' && MO_TYPE(pkt)<='z'){
if(MO_TIME(pkt)>16777216) /* 3-byte only */ if(MO_TIME(pkt)>16777216) /* 3-byte only */
return MP_SEND; return MP_SEND;
@ -73,7 +73,7 @@ int mesh_sanity(uint8_t * pkt){
MO_TYPE(pkt)!='G' && MO_TYPE(pkt)!='G' &&
MO_TYPE(pkt)!='T' MO_TYPE(pkt)!='T'
){ ){
return MP_IGNORE|MP_RECV; return MP_IGNORE;
}; };
return MP_OK; return MP_OK;
}; };
@ -103,7 +103,7 @@ MPKT * meshGetMessage(uint8_t type){
}; };
void meshPanic(uint8_t * pkt,int bufno){ void meshPanic(uint8_t * pkt,int bufno){
#if 1 #if 0
static int done=0; static int done=0;
if(!done){ if(!done){
gpioSetValue (RB_LED0, 1-gpioGetValue(RB_LED0)); gpioSetValue (RB_LED0, 1-gpioGetValue(RB_LED0));

View File

@ -117,7 +117,7 @@ static bool screen_overview() {
while (key != BTN_ENTER) { while (key != BTN_ENTER) {
lcdClear(); lcdClear();
lcdPrintln("Privacy:"); lcdPrintln("Privacy:");
lcdPrintln(levels[GLOBAL(privacy)]); lcdPrintln(levels[(int)GLOBAL(privacy)]);
lcdPrintln(""); lcdPrintln("");
lcdPrintln("Nickname:"); lcdPrintln("Nickname:");
lcdPrintln(GLOBAL(nickname)); lcdPrintln(GLOBAL(nickname));

View File

@ -83,7 +83,7 @@ meshnice
#external #external
strcpy strcpy
strlen strlen
memcpy memmove
memset memset
#stuff #stuff
GetLight GetLight

View File

@ -90,6 +90,8 @@ void setLeft();
void setRight(); void setRight();
struct packet a; struct packet a;
void setJeopardy();
void ram(void) void ram(void)
{ {
int priv = GLOBAL(privacy); int priv = GLOBAL(privacy);
@ -103,7 +105,7 @@ void ram(void)
nrf_config_set(&config); nrf_config_set(&config);
nrf_set_strength(3); nrf_set_strength(3);
int rnd; // int rnd;
volatile uint16_t i; volatile uint16_t i;
while( 1 ){ while( 1 ){

View File

@ -221,7 +221,7 @@ static void draw_platforms() {
} }
static void draw_player() { static void draw_player() {
bool* sprite; const bool* sprite;
if(game.player_y_vel > 0) { if(game.player_y_vel > 0) {
sprite = PLAYER_SPRITE_DOWN; sprite = PLAYER_SPRITE_DOWN;
} }

View File

@ -71,11 +71,12 @@ int melody_timeout;
static void init_lilakit(void); static void init_lilakit(void);
static void tick_lilakit(void); static void tick_lilakit(void);
void melody_play(void);
static void mainloop(); static void mainloop();
void handler(void); void handler(void);
void ram(void) { void ram(void) {
timer32Callback0 = handler; timer32Callback0 = (uint32_t) handler;
/* Enable the clock for CT32B0 */ /* Enable the clock for CT32B0 */
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B0); SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B0);

View File

@ -29,7 +29,7 @@ void ram(void) {
if( nrf_rcv_pkt_time(64,sizeof(buf),buf) == 16 ){ if( nrf_rcv_pkt_time(64,sizeof(buf),buf) == 16 ){
buf[14] = 0; buf[14] = 0;
if( buf[1] == 0x23 || buf[1] == 0x24){ if( buf[1] == 0x23 || buf[1] == 0x24){
lcdPrintln(buf+6); lcdPrintln((char*)(buf+6));
//lcdPrintln("foo"); //lcdPrintln("foo");
} }
lcdRefresh(); lcdRefresh();

View File

@ -113,6 +113,9 @@ void init();
** Code Section ** Code Section
*********************************************/ *********************************************/
void init();
void ram();
void game(void) void game(void)
{ {
init(); init();
@ -139,7 +142,7 @@ void game(void)
} }
} }
init() void init()
{ {
// init ball // init ball
ball1.size = PONG_BALL_SIZE; ball1.size = PONG_BALL_SIZE;

View File

@ -34,11 +34,11 @@ struct packet{
uint8_t x; uint8_t x;
uint8_t y; uint8_t y;
uint8_t flags; uint8_t flags;
uint8_t text[16]; char text[16];
}__attribute__((packed)) text; }__attribute__((packed)) text;
struct nick{ struct nick{
uint8_t flags; uint8_t flags;
uint8_t nick[18]; char nick[18];
}__attribute__((packed)) nick; }__attribute__((packed)) nick;
struct nickrequest{ struct nickrequest{
uint8_t reserved[19]; uint8_t reserved[19];
@ -55,7 +55,7 @@ struct packet{
uint8_t gameFlags; uint8_t gameFlags;
uint8_t interval; uint8_t interval;
uint8_t jitter; uint8_t jitter;
uint8_t gameTitle[8]; char gameTitle[8];
}__attribute__((packed)) announce; }__attribute__((packed)) announce;
struct join{ struct join{
uint16_t gameId; uint16_t gameId;
@ -93,7 +93,7 @@ uint16_t gameId;
uint8_t interval; uint8_t interval;
uint8_t jitter; uint8_t jitter;
uint8_t flags; uint8_t flags;
uint8_t *gameTitle; char *gameTitle;
void sendButton(uint8_t button); void sendButton(uint8_t button);
void sendJoin(uint32_t game); void sendJoin(uint32_t game);
@ -321,7 +321,7 @@ void processNickRequest( struct nickrequest *nq)
p.id= id; p.id= id;
p.ctr= ++ctr; p.ctr= ++ctr;
p.c.nick.flags = 0; p.c.nick.flags = 0;
uint8_t *nick = GLOBAL(nickname); char *nick = GLOBAL(nickname);
strcpy(p.c.nick.nick, nick); strcpy(p.c.nick.nick, nick);
nrf_snd_pkt_crc(sizeof(p),(uint8_t*)&p); nrf_snd_pkt_crc(sizeof(p),(uint8_t*)&p);
} }
@ -374,7 +374,7 @@ void processText(struct text *t)
if( t->flags & FLAGS_CLS ) if( t->flags & FLAGS_CLS )
lcdClear() ; lcdClear() ;
lcdSetCrsr(t->x, t->y); lcdSetCrsr(t->x, t->y);
t->text[16] = 0; t->text[16] = 0; // XXX:Actually ok, beause the CRC is there. But evil!
lcdPrint(t->text); lcdPrint(t->text);
lcdRefresh(); lcdRefresh();
} }

View File

@ -116,7 +116,7 @@ void ram(void) {
case BTN_RIGHT: if (kok) { xs++; xs&=63; kok=0; } break; case BTN_RIGHT: if (kok) { xs++; xs&=63; kok=0; } break;
case BTN_UP: if (kok) { ch++; ch&=7; kok=0; } break; case BTN_UP: if (kok) { ch++; ch&=7; kok=0; } break;
case BTN_DOWN: if (kok) { ch--; ch&=7; kok=0; } break; case BTN_DOWN: if (kok) { ch--; ch&=7; kok=0; } break;
case BTN_ENTER: return 0; case BTN_ENTER: return;
default: kok=1; default: kok=1;
} }
} }

322
firmware/l0dable/snake.c Normal file
View File

@ -0,0 +1,322 @@
/*
* snake
********
* a snake clone for the r0ket
* created by Flori4n (DrivenHoliday) & MascH (CCCHB tent)
***************************************/
#include <sysinit.h>
#include <string.h>
#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 "lcd/lcd.h"
//#include "lcd/print.h"
#include "funk/mesh.h"
#include "usetable.h"
#define MAX_SNAKE_LEN (40)
#define SNAKE_DIM (3)
#define MIN_SPEED (25)
#define MAX_SPEED (3)
#define MIN_X 2
#define MAX_X (RESX-3)
#define MIN_Y 8
#define MAX_Y (RESY-2)
#define SIZE_X ((MAX_X-MIN_X)/SNAKE_DIM)
#define SIZE_Y ((MAX_Y-MIN_Y)/SNAKE_DIM)
#define RIGHT 0
#define LEFT 2
#define UP 3
#define DOWN 1
struct pos_s {
int x,y;
};
struct snake_s {
struct pos_s *tail;
int len, dir, speed, t_start;
};
static void reset();
static void next_level();
static void draw_block();
static void handle_input();
static void death_anim();
static struct pos_s getFood(void);
static int hitWall();
static int hitFood();
static int hitSelf();
static int showHighscore();
int points = 0;
struct snake_s snake = { NULL, 3, 0, MIN_SPEED, 2};
struct pos_s food;
void ram(void)
{
int c=0, pos=0,del=0;
struct pos_s tail[MAX_SNAKE_LEN];
snake.tail = tail;
// initially reset everything
reset();
while (1)
{
if(!(++c % snake.speed)) {
handle_input();
pos = (snake.t_start+1) % MAX_SNAKE_LEN;
snake.tail[pos].x = snake.tail[snake.t_start].x;
snake.tail[pos].y = snake.tail[snake.t_start].y;
if(snake.dir == 0)
snake.tail[pos].x++;
else if(snake.dir == 1)
snake.tail[pos].y++;
else if(snake.dir == 2)
snake.tail[pos].x--;
else if(snake.dir == 3)
snake.tail[pos].y--;
snake.t_start = pos;
if (pos < snake.len) {
del = MAX_SNAKE_LEN - (snake.len - pos);
} else
del = pos - snake.len;
// remove last, add first line
draw_block(snake.tail[del].x, snake.tail[del].y, 0);
draw_block(snake.tail[pos].x, snake.tail[pos].y, 1);
// check for obstacle hit..
if (hitWall() || hitSelf()) {
death_anim();
if (showHighscore())
break;
reset();
}
else if (hitFood())
next_level();
lcdDisplay();
}
#ifdef SIMULATOR
delayms(50);
#else
delayms(3);
#endif
}
}
static struct pos_s getFood(void)
{
int i,pos;
struct pos_s res;
tryagain:
res.x = (getRandom() % (SIZE_X-1)) + 1;
res.y = (getRandom() % (SIZE_Y-3)) + 3;
for(i=0; i<snake.len; i++) {
pos = (snake.t_start < i) ? (MAX_SNAKE_LEN - (i-snake.t_start)) : (snake.t_start-i);
if (snake.tail[pos].x == res.x && snake.tail[pos].y == res.y) // no food to be spawn in snake plz
goto tryagain;
}
return res;
}
static void reset()
{
int i;
// setup the screen
lcdClear();
for (i=MIN_X; i<MAX_X; i++) {
lcdSetPixel(i,MIN_Y,1);
lcdSetPixel(i,MAX_Y,1);
}
for (i=MIN_Y; i<MAX_Y; i++) {
lcdSetPixel(MIN_X,i,1);
lcdSetPixel(MAX_X,i,1);
}
snake.speed = MIN_SPEED;
snake.len = 3;
snake.dir = 0;
snake.t_start = 2;
points = 0;
// create snake in the middle of the field
snake.tail[0].x = SIZE_X/2;
snake.tail[0].y = SIZE_Y/2;
snake.tail[1].x = SIZE_X/2 +1;
snake.tail[1].y = SIZE_Y/2;
snake.tail[2].x = SIZE_X/2 +2;
snake.tail[2].y = SIZE_Y/2;
// print initail tail
draw_block(snake.tail[0].x, snake.tail[0].y, 1);
draw_block(snake.tail[1].x, snake.tail[1].y, 1);
draw_block(snake.tail[2].x, snake.tail[2].y, 1);
// switch to level one
next_level();
}
static void draw_block(int x, int y, int set)
{
x *= SNAKE_DIM;
y *= SNAKE_DIM;
lcdSetPixel(x , y, set);
lcdSetPixel(x+1, y, set);
lcdSetPixel(x+2, y, set);
lcdSetPixel(x, y+1, set);
lcdSetPixel(x+1, y+1, set);
lcdSetPixel(x+2, y+1, set);
lcdSetPixel(x, y+2, set);
lcdSetPixel(x+1, y+2, set);
lcdSetPixel(x+2, y+2, set);
}
static void next_level()
{
food = getFood();
draw_block( food.x, food.y, 1);
snake.len++;
snake.speed--;
DoInt(0,0,++points);
}
static void handle_input()
{
int key = getInputRaw(), dir_old = snake.dir;
if (key&BTN_UP && dir_old != 1)
snake.dir = 3;
else if (key&BTN_DOWN && dir_old != 3)
snake.dir = 1;
else if (key&BTN_LEFT && dir_old != 0)
snake.dir = 2;
else if (key&BTN_RIGHT && dir_old !=2)
snake.dir = 0;
}
static int hitWall()
{
return ( (snake.tail[snake.t_start].x*3 <= MIN_X)
|| (snake.tail[snake.t_start].x*3 >= MAX_X)
|| (snake.tail[snake.t_start].y*3 <= MIN_Y)
|| (snake.tail[snake.t_start].y*3 >= MAX_Y) ) ?
1 : 0;
}
static int hitSelf()
{
int i, pos;
for (i=1; i<snake.len; i++) {
pos = (snake.t_start < i) ? (MAX_SNAKE_LEN - (i-snake.t_start)) : (snake.t_start-i);
if (snake.tail[pos].x == snake.tail[snake.t_start].x && snake.tail[pos].y == snake.tail[snake.t_start].y)
return 1;
}
return 0;
}
static void death_anim()
{
int i,j, a=4;
while(a--) {
// lcdToggleFlag(LCD_INVERTED);
for (i=0; i<RESY; i++) {
for (j=0; j<RESX; j++) {
lcdSetPixel(j,i,!lcdGetPixel(j,i));
}
}
lcdDisplay();
#ifdef SIMULATOR
delayms(5000);
#else
delayms(250);
#endif
}
;// this is a stub
}
static bool highscore_set(uint32_t score, char nick[]) {
MPKT * mpkt= meshGetMessage('s');
if(MO_TIME(mpkt->pkt)>score)
return false;
MO_TIME_set(mpkt->pkt,score);
strcpy((char*)MO_BODY(mpkt->pkt),nick);
if(GLOBAL(privacy)==0){
uint32touint8p(GetUUID32(),mpkt->pkt+26);
mpkt->pkt[25]=0;
};
return true;
}
static uint32_t highscore_get(char nick[]){
MPKT * mpkt= meshGetMessage('s');
char * packet_nick = (char*)MO_BODY(mpkt->pkt);
// the packet crc end is already zeroed
if(MAXNICK<MESHPKTSIZE-2-6-1)
packet_nick[MAXNICK-1] = 0;
strcpy(nick, packet_nick);
return MO_TIME(mpkt->pkt);
}
static int showHighscore()
{
int key = getInputRaw(); //throw away pending keypress
char nick[20];
uint32_t score = 0;
highscore_set(points,GLOBAL(nickname));
score = highscore_get(nick);
lcdClear();
DoString(0,RESY/2-33, " Your Score");
DoInt(RESX/2-4, RESY/2-25, points);
DoString(0,RESY/2-10, " Highscore");
DoInt(RESX/2-4, RESY/2-2, score);
DoString(0, RESY/2+18, " UP to play ");
DoString(0, RESY/2+26, "DOWN to quit ");
lcdDisplay();
while(1) {
key = getInputRaw();
if (key&BTN_DOWN) {
return 1;
} else if (key&BTN_UP) {
return 0;
}
}
}
static int hitFood()
{
return ((snake.tail[snake.t_start].x == food.x) && (snake.tail[snake.t_start].y == food.y)) ? 1 : 0;
}

View File

@ -1,194 +0,0 @@
#include <sysinit.h>
#include "basic/basic.h"
#include "basic/config.h"
#include "lcd/lcd.h"
#include "lcd/print.h"
#include "usetable.h"
struct elem
{
int x,y;
};
void reset(struct elem snake[],size_t *snake_size,int *dirc,
int*speed, int*points,int*point_s);
void o_rectangle (int x0, int y0, int width, int height);
struct elem rnd(void);
#define MAX_SNAKE_LEN (40)
#define SNAKE_DEM (3)
#define MIN_SPEED (25)
#define MAX_SPEED (3)
#define SIZE_X (RESX)
#define SIZE_Y (RESY)
void ram(void)
{
int inpt,dirc,c,grows = 0,dx,dy,points,point_s=1;
size_t n = 0, snake_size = 5, speed=MIN_SPEED;
struct elem snake[MAX_SNAKE_LEN], food;
char test[512]; /* scratch space */
o_init (test, sizeof(test));
reset(snake,&snake_size,&dirc,&speed,&points,&point_s);
food = rnd();
while (1)
{
head:
if(!(++c % speed))
{
inpt = getInputRaw();
dx=DoString(0,0,IntToStrX(points,2));
dx=(SIZE_X-dx)/2;
if(dx<0)
dx=0;
dy=(SIZE_Y-getFontHeight())/2;
lcdFill(255);
o_rectangle(1,0,SIZE_X-2,SIZE_Y-2);
o_set_gray (0);
o_fill ();
//o_identity (); /* reset tranforms */
o_set_gray (50);
setExtFont("UBUNTU29");
lcdSetPixel(1,1,1);
DoString(dx,dy,IntToStrX(points,2));
o_set_gray (255);
for(n=0;n<snake_size;++n)
{
o_rectangle
(snake[n].x*SNAKE_DEM,snake[n].y*SNAKE_DEM,SNAKE_DEM,SNAKE_DEM); /*
fill background with black */
o_fill (); /* fill with 50% {
reset(snake,&snake_size);
goto head;
}gray */
}
o_rectangle
(food.x*SNAKE_DEM,food.y*SNAKE_DEM,SNAKE_DEM,SNAKE_DEM); /* fill
background with black */
o_fill ();
lcdDisplay();
if (inpt == BTN_UP && dirc != 1)
{
dirc = 3;
}
else if (inpt == BTN_DOWN && dirc != 3)
{
dirc = 1;
}
else if (inpt == BTN_LEFT && dirc != 0)
{
dirc = 2;
}
else if (inpt == BTN_RIGHT && dirc !=2)
{
dirc = 0;
}
//
struct elem t = snake[snake_size-1];
if(dirc == 0)
++t.x;
else if(dirc == 1)
++t.y;
else if(dirc == 2)
--t.x;
else if(dirc == 3)
--t.y;
if(t.x < 0 || t.y < 0 || t.y > SIZE_Y/SNAKE_DEM-1 ||
t.x > SIZE_X/SNAKE_DEM)
{
reset(snake,&snake_size,&dirc,&speed,&points,&point_s);
goto head;
}
for(n=0;n<snake_size-1;++n)
{
if(snake[n].x == t.x && snake[n].y == t.y)
{
reset(snake,&snake_size,&dirc,&speed,&points,&point_s);
goto head;
}
else if(snake[n].x == food.x && snake[n].y == food.y)
{
grows = 1;
++snake_size;
++points;
if(speed > MAX_SPEED) --speed;
food = rnd();
}
}
if(!grows)
{
for(n=0;n<snake_size-1;++n)
{
snake[n] = snake[n+1];
}
}
else
grows = 0;
snake[snake_size-1] = t;
}
else
delayms(3);
}
}
struct elem rnd(void)
{
struct elem res;
res.x = getRandom() % (SIZE_X/SNAKE_DEM-1) +1;
res.y = getRandom() % (SIZE_Y/SNAKE_DEM-1) + 1;
return res;
}
void reset(struct elem snake[],size_t *snake_size,int *dirc,
int*speed, int*points,int* point_s)
{
size_t n = 0;
for(n=0;n<MAX_SNAKE_LEN;++n)
{ snake[n].x=5;snake[n].y=5; }
*snake_size = 5;
*dirc = 0;
*speed = MIN_SPEED;
*points=0;
*point_s=1;
}
void o_rectangle (int x0, int y0, int width, int height)
{
o_path_new ();
o_move_to (x0, y0);
o_line_to (x0 + width, y0);
o_line_to (x0 + width, y0+height+1);
o_line_to (x0, y0+height+1);
o_close ();
}

View File

@ -1,5 +1,5 @@
size_t strlen(const char *s); size_t strlen(const char *s);
char strcpy(char * restrict dst, const char * restrict src); char* strcpy(char * restrict dst, const char * restrict src);
void memcpy(void *dst, const void *src, size_t len); void* memmove(void *dst, const void *src, size_t len);
void memset(void *s, int c, size_t n); void* memset(void *s, int c, size_t n);
int getrelease(); int getrelease();

View File

@ -39,7 +39,7 @@ void ram(void) {
lcdPrint(" "); lcdPrint(" ");
lcdPrint(IntToStr(v,2,0)); lcdPrint(IntToStr(v,2,0));
lcdPrint("."); lcdPrint(".");
lcdPrint(IntToStr(mv%1000,3,F_ZEROS)); lcdPrint(IntToStr(mv%1000,3,F_ZEROS|F_LONG));
lcdPrintln("V"); lcdPrintln("V");
lcdNl(); lcdNl();

View File

@ -166,7 +166,7 @@ void lcdInit(void) {
lcd_select(); lcd_select();
if(displayType==DISPLAY_N1200){ if(displayType==DISPLAY_N1200){
uint8_t initseq[]= { 0xE2,0xAF, // Display ON static uint8_t initseq[]= { 0xE2,0xAF, // Display ON
0xA1, // Mirror-X 0xA1, // Mirror-X
0xA4, 0x2F, 0xB0, 0x10}; 0xA4, 0x2F, 0xB0, 0x10};
int i = 0; int i = 0;
@ -175,7 +175,7 @@ void lcdInit(void) {
delayms(5); // actually only needed after the first delayms(5); // actually only needed after the first
} }
}else{ /* displayType==DISPLAY_N1600 */ }else{ /* displayType==DISPLAY_N1600 */
uint8_t initseq_d[] = { static uint8_t initseq_d[] = {
0x36, 0x36,
0x29, 0xBA, 0x07, 0x29, 0xBA, 0x07,
0x15, 0x25, 0x3f, 0x15, 0x25, 0x3f,

View File

@ -4,7 +4,10 @@
#include "core/pmu/pmu.h" #include "core/pmu/pmu.h"
#include "basic/basic.h" #include "basic/basic.h"
#include "basic/config.h"
#include "lcd/render.h" #include "lcd/render.h"
#include "lcd/print.h"
#include "usb/usbmsc.h"
#include "filesystem/ff.h" #include "filesystem/ff.h"
@ -34,7 +37,7 @@
void wrapper(void); void wrapper(void);
int main(void) { void main(void) {
// Configure cpu and mandatory peripherals // Configure cpu and mandatory peripherals
cpuInit(); // Configure the CPU cpuInit(); // Configure the CPU
// we do it later // we do it later

View File

@ -1,5 +1,11 @@
#!/bin/sh -e #!/bin/sh -e
# We currently don't use crypto, so this script is deprecated.
if [ -z ${MAKE} ]; then
which gmake >/dev/null && MAKE=gmake || MAKE=make
fi
TARG=../release TARG=../release
if [ ! -d ../firmware ] ; then if [ ! -d ../firmware ] ; then
@ -32,9 +38,9 @@ echo "###"
echo "### Building final" echo "### Building final"
echo "###" echo "###"
export FINAL=y export FINAL=y
make clean $MAKE clean
./l0dable/mktable.pl ./l0dable/mktable.pl
make APP=final $MAKE APP=final
cp firmware.elf $TARG/final.elf cp firmware.elf $TARG/final.elf
cp firmware.bin $TARG/final.bin cp firmware.bin $TARG/final.bin
@ -48,7 +54,7 @@ cp ../tools/image/lcd/i42.lcd $TARG/files/nick.lcd
echo "###" echo "###"
echo "### Gathering loadables" echo "### Gathering loadables"
echo "###" echo "###"
(cd l0dable && make) (cd l0dable && $MAKE)
mv l0dable/*.c0d $TARG/files/ mv l0dable/*.c0d $TARG/files/
mv l0dable/*.int $TARG/files/ mv l0dable/*.int $TARG/files/
mv l0dable/*.nik $TARG/files/ mv l0dable/*.nik $TARG/files/
@ -59,7 +65,7 @@ if grep -q 'define ENCRYPT_L0DABLE' SECRETS ; then
echo "###" echo "###"
echo "### Building crypto" echo "### Building crypto"
echo "###" echo "###"
(cd ../tools/crypto && make) (cd ../tools/crypto && $MAKE)
echo "###" echo "###"
echo "### Crypting loadables" echo "### Crypting loadables"

118
tools/mesh/beacontrace.pl Executable file
View File

@ -0,0 +1,118 @@
#!/usr/bin/perl
#
# vim:set ts=4 sw=4:
use strict;
use Curses;
use POSIX qw(strftime);
use Time::HiRes qw(time);
use lib '.';
use r0ket;
$|=1;
r0ket::r0ket_init();
# Default openbeacon settings.
r0ket::set_txmac(pack("H*","0102030201"));
r0ket::set_rxmac(pack("H*","0102030201"));
r0ket::set_channel(81);
r0ket::set_rxlen(16);
#r0ket::readbeacon();
my $str;
my %bdata;
sub do_str;
initscr;
END{endwin;}
use constant WIDTH => 80;
use constant m_height => 15;
my $win_top=subwin(2,WIDTH,0,0);
my $win=subwin(m_height,WIDTH,2,0);
noecho;
curs_set(0);
$win_top->addstr(0,0,"r0ket Beacon-Trace 0.1");
$win_top->addstr(1,0,"-"x20);
$win_top->refresh;
my $beaconctr=0;
use constant CLEAN => 10;
use constant UPDATE => 0.3;
my $lasttime;
my $lastcleantime;
my $clean;
my $crcerr=0;
while(1){
$str=r0ket::get_packet();
my $p=r0ket::nice_beacon($str);
if($p->{crc} ne "ok"){
$crcerr++;
next;
};
if($p->{type} eq "beacon"){
$bdata{$p->{beacon}}{seen}=time;
$bdata{$p->{beacon}}{beacon}=$p;
$bdata{$p->{beacon}}{stats}{$p->{strength}}++;
if(!defined($bdata{$p->{beacon}}{stats}{first})){
$bdata{$p->{beacon}}{stats}{first}=time;
};
}elsif($p->{type} eq "nick"){
$bdata{$p->{beacon}}{nick}=$p->{nick};
}else{ #unknown
;
};
if(time>$lastcleantime+CLEAN){
$clean=1;
$lastcleantime=time;
}else{
$clean=0;
};
my $line=0;
if($clean){
$win->clear;
for my $b (sort keys %bdata){
if($bdata{$b}{seen}+10<time){
delete $bdata{$b}
};
};
};
if(time>$lasttime+UPDATE){
for my $b (sort keys %bdata){
$win->addstr($line++,0,
sprintf "%s | bt=%s idx=%8s | %s | %s",
$b,
$bdata{$b}{beacon}->{button},
$bdata{$b}{beacon}->{idx},
do_str($bdata{$b}{stats}),
$bdata{$b}{nick}." "
);
};
$win_top->addstr(1,20,sprintf" cnt=%2d, crc=%d",scalar(keys %bdata),$crcerr);
$win_top->refresh;
$win->refresh;
$lasttime=time;
};
};
r0ket::rest();
sub do_str{
my $hr=shift;
my $df=time()-$hr->{first};
$df=1 if $df==0;
my $out="";
# for(sort keys %$hr){
for(qw(00 55 aa ff)){
next if $_ eq "first";
$out.=sprintf("%3d% ",($hr->{$_}/$df)*100/2);
};
return $out;
};

63
tools/mesh/meshtrace.pl Executable file
View File

@ -0,0 +1,63 @@
#!/usr/bin/perl
#
# vim:set ts=4 sw=4:
use strict;
use Curses;
use POSIX qw(strftime);
use lib '.';
use r0ket;
$|=1;
r0ket::r0ket_init();
# Default mesh settings.
r0ket::set_txmac("ORBIT");
r0ket::set_rxmac("ORBIT");
r0ket::set_channel(83);
r0ket::set_rxlen(32);
r0ket::readbeacon();
my $str;
my %bdata;
initscr;
END{endwin;}
use constant WIDTH => 80;
use constant m_height => 15;
my $win_top=subwin(2,WIDTH,0,0);
my $win=subwin(m_height,WIDTH,2,0);
noecho;
curs_set(0);
$win_top->addstr(0,0,"r0ket Mesh-Trace 0.1");
$win_top->addstr(1,0,"-"x20);
$win_top->refresh;
my $beaconctr=0;
my $crcerr=0;
while(1){
$str=r0ket::get_packet();
my $p=r0ket::nice_mesh($str);
if($p->{crc} ne "ok"){
$crcerr++;
next;
};
if(!$bdata{$p->{beacon}}){
$bdata{$p->{beacon}}=++$beaconctr;
};
$win->addstr($bdata{$p->{beacon}},0,
sprintf "%s | g=%d rel=%s time=%s =%+4d | %s",
$p->{beacon},
$p->{generation},
$p->{release},
strftime("%Y-%m-%d %H:%M:%S",gmtime $p->{time}),
$p->{time}-(time+3600),
r0ket::getbeacon($p->{beacon})
);
$win->refresh;
};
r0ket::rest();

345
tools/mesh/r0ket.pm Executable file
View File

@ -0,0 +1,345 @@
#!/usr/bin/perl
#
# vim:set ts=4 sw=4:
use strict;
use IO::Select;
package r0ket;
use Digest::CRC qw(crcccitt);
use POSIX qw(strftime);
use Time::HiRes;
our $verbose=0;
our $bridge; # Open device
### Utility
sub sprint{
return join("",map {
if (ord($_)>30 && ord($_)<127){
$_;
}else{
# "[x".unpack("H*",$_)."]";
"\\".unpack("C",$_);
}
}split(//,shift));
};
sub hprint{
return unpack("H*",shift);
};
sub flagsstr {
my $in=shift;
my @f;
my $f=1;
for (@_){
if($in & $f){
push @f,$_;
};
$f*=2;
};
return join(",",@f);
};
### Nickname/beacon helper functions
our %beacon;
sub readbeacon{
return if( ! -f "BEACON" );
open(B,"<","BEACON") || die "open: $!";
while(<B>){
/(\w+)\s+(.*)/ && do {
$beacon{$1}=$2;
};
};
close(B);
};
sub getbeacon{
my $b=shift;
if(!$beacon{$b}){
return "";
}else{
return $beacon{$b};
};
};
sub resolvebeacon{
my $b=shift;
if(!$beacon{$b}){
return $b;
}else{
return "$b ($beacon{$b})";
};
};
sub addbeacon{
my($b,$n)=@_;
if(!$beacon{$b}){
$beacon{$b}=$n;
};
};
sub writebeacon{
open(B,">","BEACON") || die "write: $!";
for(sort keys %beacon){
print B "$_ $beacon{$_}\n";
};
close(B);
};
### Packet mgmt
our $buffer;
our $firstpkt=2;
sub get_packet{
sub _get_bytes{
my $rr;
sysread($bridge,$rr,1024);
if(length($rr)<=1){
select(undef,undef,undef,0.05);
};
$buffer.=$rr;
};
my $cnt=0;
while(++$cnt<100){
if(length($buffer)<2){
_get_bytes();
}elsif($buffer !~ /^\\[12]/){
$buffer=~s/^(.[^\\]*)//s;
if($firstpkt){
$firstpkt--;
}else{
print STDERR "Unparseable stuff: <",sprint($1),">\n";
};
}elsif ($buffer =~ s/^\\2\\0//s){
return 'ack'; # In-band signalling. Evil %)
}elsif ($buffer =~ s/^\\1(.*?)\\0//s){
my $str=$1;
$str=~s/\\\\/\\/g; # dequote
return $str;
}else{
_get_bytes();
};
};
die "No packets for 5seconds?\n";
};
sub rest{
if(length($buffer)>0){
print "rest: <", sprint($buffer), ">\n";
};
};
### Pkt beautify
sub nice_mesh{
my $pkt=shift;
my $out;
my $type=substr($pkt,0,1);
# next if(defined $arg && $arg ne $i);
$out->{type}=$type;
$out->{string}="[$type]";
$out->{generation}=unpack("C",substr($pkt,1,1));
$out->{string}.= " g=".$out->{generation};
if($type eq "T"){
$out->{time}= unpack("N",substr($pkt,2,4));
$out->{release}=unpack("H*",substr($pkt,24,2));
$out->{beacon}= unpack("H*",substr($pkt,26,4));
$out->{string}.=sprintf " t=%s (%+4d) rel=%s beacon=%s",
strftime("%Y-%m-%d %H:%M:%S",gmtime $out->{time}),
$out->{time}-(Time::HiRes::time+3600),
$out->{release},
resolvebeacon($out->{beacon});
}elsif($type eq "i"){
$out->{score}=unpack("N",substr($pkt,2,4));
$out->{nick}= unpack("Z*",substr($pkt,6,length($pkt)-8));
$out->{string}.=sprintf " score=%d nick=%s",
$out->{score},
$out->{nick};
}elsif($type eq "B"){
$out->{time}=unpack("N",substr($pkt,2,4));
$out->{id}= unpack("c",substr($pkt,6,1));
$out->{hop}= unpack("n",substr($pkt,11,4));
$out->{string}.=sprintf " t=%d id=%s hop=%3d",
$out->{time},
$out->{id},
$out->{hop};
}else{
$out->{string}.= " <??: ".unpack("H*",substr($pkt,2,length($pkt)-4)).">";
};
my $pkt_crc= unpack("n",substr($pkt,length($pkt)-2,2));
my $calc_crc= crcccitt(substr($pkt,0,length($pkt)-2));
if ($pkt_crc eq $calc_crc){
$out->{crc}="ok";
}else{
$out->{crc}="fail";
$out->{string}.= " CRCFAIL";
};
return $out;
};
sub nice_game{
my $pkt=shift;
my $out;
my $type=substr($pkt,2,1);
$out->{proto}=substr($pkt,1,1);
$out->{type} =substr($pkt,2,1);
$out->{id} =unpack("V",substr($pkt,3,4));
$out->{ctr} =unpack("V",substr($pkt,7,4));
$out->{string}=sprintf "G[%s] id=%d ctr=%d",
$out->{type}, $out->{id}, $out->{ctr};
if($type eq "A"){
$out->{mac} = substr($pkt,11,5);
$out->{channel} = unpack("C" ,substr($pkt,16,1));
$out->{id} = unpack("v", substr($pkt,17,2));
$out->{flags} = unpack("C", substr($pkt,19,1));
$out->{flagsstr}=flagsstr($out->{flags},qw(mass short lrecv));
$out->{interval} = unpack("C", substr($pkt,20,1));
$out->{jitter} = unpack("C", substr($pkt,21,1));
$out->{title} = unpack("Z*",substr($pkt,22,10));
$out->{string}.=sprintf " mac=%s ch=%s id=%d fl=<%s> itvl=%d j=%d %s",
sprint($out->{mac}),
$out->{channel},
$out->{id},
$out->{flagsstr},
$out->{interval},
$out->{jitter},
$out->{title};
}else{
$out->{string}.= " <??: ".unpack("H*",substr($pkt,2,length($pkt)-4)).">";
};
my $pkt_crc= unpack("n",substr($pkt,length($pkt)-2,2));
my $calc_crc= crcccitt(substr($pkt,0,length($pkt)-2));
if ($pkt_crc eq $calc_crc){
$out->{crc}="ok";
}else{
$out->{crc}="fail";
$out->{string}.= " CRCFAIL";
};
return $out;
};
sub nice_beacon{
my $pkt=shift;
my $out;
my $type=substr($pkt,1,1);
$out->{type}=$type;
if($type eq "\x17"){
$out->{type}= "beacon";
$out->{length}= unpack("C", substr($pkt,0,1));
$out->{button}= unpack("H*",substr($pkt,2,1));
$out->{strength}=unpack("H*",substr($pkt,3,1));
$out->{idx}= unpack("N", substr($pkt,4,4));
$out->{beacon}= unpack("H*",substr($pkt,8,4));
$out->{unused}= unpack("H*",substr($pkt,12,2));
$out->{string}=sprintf "BEACON ln=%d bt=%s str=%s idx=%08x beacon=%s",
$out->{length},
$out->{button},
$out->{strength},
$out->{idx},
$out->{beacon};
if(unpack("H*",substr($pkt,12,2)) ne "ffff"){
print "unused=",unpack("H*",substr($pkt,12,2))," ";
};
}elsif($type eq "\x23"){
$out->{type}= "nick";
$out->{beacon}= unpack("H*",substr($pkt,2,4));
$out->{nick}= unpack("Z*",substr($pkt,6,length($pkt)-2));
$out->{string}=sprintf "NICK beacon=%s nick=%s",
$out->{beacon},
$out->{nick};
}else{
$out->{string}="<?:".unpack("H*",$pkt).">";
};
my $pkt_crc= unpack("n",substr($pkt,length($pkt)-2,2));
my $calc_crc= crcccitt(substr($pkt,0,length($pkt)-2));
if ($pkt_crc eq $calc_crc){
$out->{crc}="ok";
}else{
$out->{crc}="fail";
$out->{string}.= " CRCFAIL";
};
return $out;
};
sub r0ket_init{
my $ser;
if ($ARGV[0] eq "-s"){
shift;
$ser=shift;
};
if(!defined $ser){
if (defined $ENV{R0KETBRIDGE} && -e $ENV{R0KETBRIDGE}){
$ser=$ENV{R0KETBRIDGE}
};
};
if(!defined $ser){
do {$ser=$_ if ( -e $_ ) } for qw(/dev/ttyS3 /dev/ttyACM0);
};
open($bridge, "+<",$ser) || die "open serial: $!";
if($verbose){
print "using: $ser\n";
};
};
sub send_raw {
if($verbose){
print "send: ",unpack("H*",$_[0]),"\n";
};
syswrite($bridge,shift);
};
sub send_pkt_num {
my $pkt=shift;
$pkt=~s/\\/\\\\/;
send_raw('\\'.shift().$pkt.'\0');
};
sub send_pkt {
send_pkt_num(shift,1);
};
sub set_txmac {
send_pkt_num(shift,3);
};
sub set_rxmac {
send_pkt_num(shift,4);
};
sub set_channel {
send_pkt_num(pack("C",shift),5);
};
sub set_rxlen {
send_pkt_num(pack("C",shift),6);
};
sub wait_ok {
my $pkt;
$pkt=get_packet();
while($pkt ne "ack"){
print "pkt=",(sprint $pkt),"\n";
$pkt=get_packet();
};
print "ok!\n";
return 1;
};
1;

266
tools/mesh/rf Executable file
View File

@ -0,0 +1,266 @@
#!/usr/bin/perl
#
# vim:set ts=4 sw=4:
use strict;
use IO::Select;
use Digest::CRC qw(crcccitt);
use POSIX qw(strftime);
use FindBin;
use lib "$FindBin::Bin";
use r0ket;
$|=1;
r0ket::r0ket_init();
my @fh;
my $read;
if ($ARGV[0] =~ /^-?-?h/){
print STDERR "Mini-Help:\n";
print STDERR "-s <devicename> (or \$R0KETBRIDGE)\n";
print STDERR "-w write beacon2nick file\n";
print STDERR "\n";
print STDERR "recv<num>: receive (number) pakets\n";
print STDERR " - r hex : hexdump packets\n";
print STDERR " - r ascii : asciidump packets\n";
print STDERR " - r beacon : parse as openbeacon\n";
print STDERR " - r mesh : parse as mesh packet\n";
print STDERR " - r game : parse as game packet(incomplete)\n";
print STDERR "\n";
print STDERR "send<num>: send packet (number) times\n";
print STDERR " - s raw <hex>: send raw hex packet\n";
print STDERR " - s hex <hex>: send packet with crc16\n";
print STDERR " - s mesh t <gen>: send mesh time packet\n";
print STDERR " - s mesh <other>, see source :-)\n";
print STDERR "\n";
print STDERR "preset: config per preset\n";
print STDERR "- p m - preset minimesh\n";
print STDERR "- p b - preset openbeacon\n";
print STDERR "- p a - preset game announce\n";
print STDERR "- p r - preset sample game\n";
print STDERR "config: config rf chip\n";
print STDERR "- c rx - set rxmac\n";
print STDERR "- c tx - set txmac\n";
print STDERR "- c len - set rxlength\n";
print STDERR "- c ch - set channel\n";
print STDERR "- c <opt>hex - set any option via hex string\n";
print STDERR "\n";
print STDERR "etc...\n";
exit(1);
};
my $writend=0;
if ($ARGV[0] eq "-w"){
shift;
$writend=1;
};
END{
r0ket::writebeacon if($writend);
};
my $cmd=shift;
if($cmd =~ /^r/){
r0ket::readbeacon();
$cmd=~s/r(ecv)?//;
$cmd=100 if $cmd+0==0;
my $fmt=shift || "_";
my $arg=shift || undef;
my $read="";
my $str;
while($cmd>0){
$str=r0ket::get_packet();
if($fmt =~ /_/){
if(substr($str,0,1)eq "\x10"){
if(substr($str,1,1)eq"G"){
$fmt="g_";
}else{
$fmt="b_";
};
}elsif(substr($str,0,1)eq "\x20"){
$fmt="g_";
}elsif(length($str)==32){
$fmt="m_";
}else{
$fmt="x_";
};
};
if($fmt =~ /^m/){
my $p=r0ket::nice_mesh($str);
print $p->{string};
}elsif($fmt =~ /^b/){
my $p=r0ket::nice_beacon($str);
print $p->{string};
}elsif($fmt =~ /^g/){
my $p=r0ket::nice_game($str);
print $p->{string};
}elsif($fmt =~ /^(x|hex)/){
my $pkt_crc= unpack("n",substr($str,length($str)-2,2));
my $calc_crc= crcccitt(substr($str,0,length($str)-2));
print "<",unpack("H*",$str),">";
if($pkt_crc ne $calc_crc){
print " CRCFAIL";
};
}elsif($fmt =~ /^a/){
print "<", r0ket::sprint($str), ">";
}else{
die "Unknown packet format: $fmt\n";
};
print "\n";
$cmd--;
next;
};
r0ket::rest();
}elsif ($cmd =~ /^p/){ # Preset
my $sub=shift;
if ($sub =~/^m/i){ # Default mesh settings.
r0ket::set_txmac("ORBIT");
r0ket::set_rxmac("ORBIT");
r0ket::set_channel(83);
r0ket::set_rxlen(32);
}elsif ($sub =~/^b/i){ # Default OpenBeacon settings
r0ket::set_txmac(pack("H*","0102030201"));
r0ket::set_rxmac(pack("H*","0102030201"));
r0ket::set_channel(81);
r0ket::set_rxlen(16);
}elsif ($sub =~/^a/i){ # Default rem0te announce settings
r0ket::set_txmac("REM0T");
r0ket::set_rxmac("REM0T");
r0ket::set_channel(87);
r0ket::set_rxlen(32);
}elsif ($sub =~/^r/i){ # Default bpong game settings
r0ket::set_txmac("BPONG");
r0ket::set_rxmac("BPONG");
r0ket::set_channel(91);
r0ket::set_rxlen(32);
}else{
die "Unkown preset $sub\n";
};
}elsif ($cmd =~ /^c/){
my $set=shift;
if($set=~s/hex//){
$ARGV[0]=pack("H*",$ARGV[0]);
};
if ($set =~ /^tx/){
r0ket::set_txmac(shift);
}elsif ($set =~ /^rx/){
r0ket::set_rxmac(shift);
}elsif ($set =~ /^ch/){
r0ket::set_channel(shift);
}elsif ($set =~ /^len/){
r0ket::set_rxlen(shift);
}else{
die "Unknown config argument $set\n";
};
r0ket::wait_ok();
}elsif ($cmd =~ /^s/){
$cmd=~s/^//;
$cmd=1 if $cmd==0;
my $pkt;
my $sub=shift;
if($sub =~ /^raw/){
$pkt=pack("H*",shift);
}elsif($sub =~ /^hex/){
$pkt=pack("H*",shift);
$pkt.=pack("n",crcccitt($pkt));
}elsif($sub =~ /^m/){
my $scmd=shift;
if($scmd eq "t"){
$pkt.="T";
$pkt.=chr(shift); #gen
$pkt.=pack("N",scalar(time)+1*60*60);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
}elsif($scmd eq "a"){
$pkt.="A";
$pkt.=chr(shift); #gen
$pkt.=pack("N",scalar(time)+1*60*60+ 300);
$pkt.= pack("C",shift||0);
$pkt.= pack("C",0);
$pkt.= pack("C",0);
$pkt.= pack("C",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
}elsif($scmd eq "b"){
$pkt.="B";
$pkt.=chr(shift); #gen
$pkt.=pack("N",scalar(time)+1*60*60+ 600);
$pkt.= pack("C",shift||0);
$pkt.= pack("C",0);
$pkt.= pack("C",0);
$pkt.= pack("C",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
}elsif($scmd eq "c"){
$pkt.="\x1";
$pkt.=chr(shift); #gen
$pkt.=pack("N",scalar(time)+1*60*60+ 600);
$pkt.= pack("C",shift||0);
$pkt.= pack("C",0);
$pkt.= pack("C",0);
$pkt.= pack("C",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
$pkt.=pack("N",0);
}elsif($scmd eq "i"){
$pkt.="i";
$pkt.=chr(shift); #gen
$pkt.=pack("N",shift||42);
$pkt.=shift;
$pkt.="\0"x(30-length($pkt));
}else{
die "Unknown mesh subtype: $scmd\n";
};
$pkt.=pack("n",crcccitt($pkt));
}else{
die "Unknown send subtype: $sub\n";
};
print "Write: <", sprint($pkt),">, ";
print "crc: ",unpack("n",substr($pkt,length($pkt)-2,2))," ";
print "len: ",length($pkt),"\n";
while($cmd-->0){
r0ket::send_pkt($pkt);
r0ket::wait_ok;
};
}else{
die "Option not understood\n";
};
#if (@fh = $sel->can_read(10)) {
# sysread($fh[0],$read,1024);
#}
#print "PostRead: <", sprint($read), ">\n";

2
tools/smartflash/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
firmware.bin
files