Merge branch 'master' into meshdebug
This commit is contained in:
commit
54d4c31250
|
@ -1,5 +1,5 @@
|
|||
firmware.bin
|
||||
firmware.elf
|
||||
*.bin
|
||||
*.elf
|
||||
lpc1xxx/memory.ld
|
||||
applications/wrapper.c
|
||||
lcd/allfonts.h
|
||||
|
|
|
@ -37,13 +37,13 @@ ifdef APP
|
|||
OUTFILE=$(APP)
|
||||
endif
|
||||
|
||||
LDFLAGS+= -Wl,--gc-sections
|
||||
LDFLAGS+= --gc-sections
|
||||
OBJS += lpc1xxx/$(TARGET)_handlers.o lpc1xxx/LPC1xxx_startup.o
|
||||
|
||||
##########################################################################
|
||||
# Startup files
|
||||
##########################################################################
|
||||
LDLIBS = -lm
|
||||
LDLIBS =
|
||||
LDLIBS += -Lapplications -lapp
|
||||
LDLIBS += -Lfunk -lfunk
|
||||
LDLIBS += -Lusbcdc -lusbcdc
|
||||
|
@ -111,7 +111,7 @@ $(LD_TEMP):
|
|||
-@echo "INCLUDE $(LD_SCRIPT)" >> $(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 ""
|
||||
$(SIZE) $(OUTFILE).elf
|
||||
-@echo ""
|
||||
|
|
|
@ -42,7 +42,7 @@ CPU_TYPE = cortex-$(CORTEX_TYPE)
|
|||
# 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
|
||||
|
||||
ifeq "$(USBSERIAL)" "YES"
|
||||
|
|
|
@ -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>
|
||||
- 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
|
||||
make l0dables
|
||||
|
||||
#build one l0dable
|
||||
# build one l0dable
|
||||
cd l0dables && make <l0dablename>.c0d
|
||||
|
|
|
@ -186,6 +186,9 @@ void m_choose(){
|
|||
case('r'):
|
||||
strcpy(p,"r0type");
|
||||
break;
|
||||
case('s'):
|
||||
strcpy(p,"Snake");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
p[0]=*mm;
|
||||
|
@ -233,6 +236,9 @@ void m_choose(){
|
|||
case('r'):
|
||||
strcpy(p,"r0type");
|
||||
break;
|
||||
case('s'):
|
||||
strcpy(p,"Snake");
|
||||
break;
|
||||
#endif
|
||||
};
|
||||
if(tmm[i]>='a' && tmm[i]<='z'){
|
||||
|
|
|
@ -18,7 +18,7 @@ void rbInit() {
|
|||
gpioSetDir(USB_CONNECT, gpioDirection_Output);
|
||||
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_SPI_SS0, RB_SPI_SS1, RB_SPI_SS2,
|
||||
RB_SPI_SS3, RB_SPI_SS4, RB_SPI_SS5,
|
||||
|
|
|
@ -171,12 +171,12 @@ uint16_t crc16(uint8_t * buf, int len);
|
|||
// menu.c
|
||||
|
||||
struct MENU_DEF {
|
||||
char *text;
|
||||
const char *text;
|
||||
void (*callback)(void);
|
||||
};
|
||||
|
||||
struct MENU {
|
||||
char *title;
|
||||
const char *title;
|
||||
struct MENU_DEF entries[];
|
||||
};
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ void * memcpy(void *pDestination, const void *pSource, size_t num)
|
|||
{
|
||||
unsigned char *pByteDestination;
|
||||
unsigned char *pByteSource;
|
||||
#ifdef FAST_MEMCPY
|
||||
unsigned int *pAlignedSource = (unsigned int *) pSource;
|
||||
unsigned int *pAlignedDestination = (unsigned int *) pDestination;
|
||||
|
||||
|
@ -71,6 +72,10 @@ void * memcpy(void *pDestination, const void *pSource, size_t num)
|
|||
// Copy remaining bytes
|
||||
pByteDestination = (unsigned char *) pAlignedDestination;
|
||||
pByteSource = (unsigned char *) pAlignedSource;
|
||||
#else
|
||||
pByteDestination = (unsigned char *) pDestination;
|
||||
pByteSource = (unsigned char *) pSource;
|
||||
#endif
|
||||
while (num--) {
|
||||
|
||||
*pByteDestination++ = *pByteSource++;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#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)
|
||||
{
|
||||
DIR dir; /* Directory object */
|
||||
|
@ -37,7 +38,9 @@ int getFiles(char files[][FLEN], uint8_t count, uint16_t skip, const char *ext)
|
|||
continue;
|
||||
};
|
||||
|
||||
strcpy(files[pos++],Finfo.fname);
|
||||
if(count != 0xff)
|
||||
strcpy(files[pos],Finfo.fname);
|
||||
pos++;
|
||||
if( pos == count )
|
||||
break;
|
||||
}
|
||||
|
@ -50,17 +53,19 @@ int selectFile(char *filename, const char *extension)
|
|||
int skip = 0;
|
||||
char key;
|
||||
int selected = 0;
|
||||
int file_count = getFiles(NULL, 0xff, 0, extension);
|
||||
|
||||
font=&Font_7x8;
|
||||
if(!file_count){
|
||||
lcdPrintln("No Files?");
|
||||
lcdRefresh();
|
||||
getInputWait();
|
||||
getInputWaitRelease();
|
||||
return -1;
|
||||
};
|
||||
while(1){
|
||||
char files[PERPAGE][FLEN];
|
||||
int count = getFiles(files, PERPAGE, skip, extension);
|
||||
if(!count){
|
||||
lcdPrintln("No Files?");
|
||||
lcdRefresh();
|
||||
getInputWait();
|
||||
getInputWaitRelease();
|
||||
return -1;
|
||||
};
|
||||
|
||||
if(count<PERPAGE && selected==count){
|
||||
skip--;
|
||||
|
@ -88,15 +93,18 @@ int selectFile(char *filename, const char *extension)
|
|||
files[i][dot]='.';
|
||||
}
|
||||
lcdRefresh();
|
||||
key=getInputWait();
|
||||
getInputWaitRelease();
|
||||
key=getInputWaitRepeat();
|
||||
switch(key){
|
||||
case BTN_DOWN:
|
||||
if( selected < count-1 ){
|
||||
selected++;
|
||||
goto redraw;
|
||||
}else{
|
||||
skip++;
|
||||
if(skip == file_count - PERPAGE) { // wrap to top
|
||||
selected = 0;
|
||||
skip = 0;
|
||||
} else
|
||||
skip++;
|
||||
}
|
||||
break;
|
||||
case BTN_UP:
|
||||
|
@ -106,14 +114,20 @@ int selectFile(char *filename, const char *extension)
|
|||
}else{
|
||||
if( skip > 0 ){
|
||||
skip--;
|
||||
} else { // wrap to bottom
|
||||
skip = file_count - PERPAGE;
|
||||
if(skip < 0) skip = 0;
|
||||
selected = file_count - skip - 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BTN_LEFT:
|
||||
getInputWaitRelease();
|
||||
return -1;
|
||||
case BTN_ENTER:
|
||||
case BTN_RIGHT:
|
||||
strcpy(filename, files[selected]);
|
||||
getInputWaitRelease();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,16 +48,16 @@ void initMesh(void){
|
|||
#define MP_IGNORE 4
|
||||
int mesh_sanity(uint8_t * pkt){
|
||||
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])
|
||||
return MP_SEND|MP_RECV;
|
||||
return MP_SEND;
|
||||
if(MO_TYPE(pkt)=='T' && MO_TIME(pkt)<86400)
|
||||
return MP_OK;
|
||||
if(MO_TYPE(pkt)>='A' && MO_TYPE(pkt)<='Z'){
|
||||
if(MO_TIME(pkt)>1370340000) /* 4.Jun 2013 */
|
||||
return MP_SEND|MP_RECV;
|
||||
return MP_SEND;
|
||||
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'){
|
||||
if(MO_TIME(pkt)>16777216) /* 3-byte only */
|
||||
return MP_SEND;
|
||||
|
@ -73,7 +73,7 @@ int mesh_sanity(uint8_t * pkt){
|
|||
MO_TYPE(pkt)!='G' &&
|
||||
MO_TYPE(pkt)!='T'
|
||||
){
|
||||
return MP_IGNORE|MP_RECV;
|
||||
return MP_IGNORE;
|
||||
};
|
||||
return MP_OK;
|
||||
};
|
||||
|
@ -103,7 +103,7 @@ MPKT * meshGetMessage(uint8_t type){
|
|||
};
|
||||
|
||||
void meshPanic(uint8_t * pkt,int bufno){
|
||||
#if 1
|
||||
#if 0
|
||||
static int done=0;
|
||||
if(!done){
|
||||
gpioSetValue (RB_LED0, 1-gpioGetValue(RB_LED0));
|
||||
|
|
|
@ -117,7 +117,7 @@ static bool screen_overview() {
|
|||
while (key != BTN_ENTER) {
|
||||
lcdClear();
|
||||
lcdPrintln("Privacy:");
|
||||
lcdPrintln(levels[GLOBAL(privacy)]);
|
||||
lcdPrintln(levels[(int)GLOBAL(privacy)]);
|
||||
lcdPrintln("");
|
||||
lcdPrintln("Nickname:");
|
||||
lcdPrintln(GLOBAL(nickname));
|
||||
|
|
|
@ -83,7 +83,7 @@ meshnice
|
|||
#external
|
||||
strcpy
|
||||
strlen
|
||||
memcpy
|
||||
memmove
|
||||
memset
|
||||
#stuff
|
||||
GetLight
|
||||
|
|
|
@ -90,6 +90,8 @@ void setLeft();
|
|||
void setRight();
|
||||
struct packet a;
|
||||
|
||||
void setJeopardy();
|
||||
|
||||
void ram(void)
|
||||
{
|
||||
int priv = GLOBAL(privacy);
|
||||
|
@ -103,7 +105,7 @@ void ram(void)
|
|||
nrf_config_set(&config);
|
||||
|
||||
nrf_set_strength(3);
|
||||
int rnd;
|
||||
// int rnd;
|
||||
|
||||
volatile uint16_t i;
|
||||
while( 1 ){
|
||||
|
|
|
@ -221,7 +221,7 @@ static void draw_platforms() {
|
|||
}
|
||||
|
||||
static void draw_player() {
|
||||
bool* sprite;
|
||||
const bool* sprite;
|
||||
if(game.player_y_vel > 0) {
|
||||
sprite = PLAYER_SPRITE_DOWN;
|
||||
}
|
||||
|
|
|
@ -71,11 +71,12 @@ int melody_timeout;
|
|||
|
||||
static void init_lilakit(void);
|
||||
static void tick_lilakit(void);
|
||||
void melody_play(void);
|
||||
static void mainloop();
|
||||
void handler(void);
|
||||
|
||||
void ram(void) {
|
||||
timer32Callback0 = handler;
|
||||
timer32Callback0 = (uint32_t) handler;
|
||||
|
||||
/* Enable the clock for CT32B0 */
|
||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B0);
|
||||
|
|
|
@ -29,7 +29,7 @@ void ram(void) {
|
|||
if( nrf_rcv_pkt_time(64,sizeof(buf),buf) == 16 ){
|
||||
buf[14] = 0;
|
||||
if( buf[1] == 0x23 || buf[1] == 0x24){
|
||||
lcdPrintln(buf+6);
|
||||
lcdPrintln((char*)(buf+6));
|
||||
//lcdPrintln("foo");
|
||||
}
|
||||
lcdRefresh();
|
||||
|
|
|
@ -113,6 +113,9 @@ void init();
|
|||
** Code Section
|
||||
*********************************************/
|
||||
|
||||
void init();
|
||||
void ram();
|
||||
|
||||
void game(void)
|
||||
{
|
||||
init();
|
||||
|
@ -139,7 +142,7 @@ void game(void)
|
|||
}
|
||||
}
|
||||
|
||||
init()
|
||||
void init()
|
||||
{
|
||||
// init ball
|
||||
ball1.size = PONG_BALL_SIZE;
|
||||
|
|
|
@ -34,11 +34,11 @@ struct packet{
|
|||
uint8_t x;
|
||||
uint8_t y;
|
||||
uint8_t flags;
|
||||
uint8_t text[16];
|
||||
char text[16];
|
||||
}__attribute__((packed)) text;
|
||||
struct nick{
|
||||
uint8_t flags;
|
||||
uint8_t nick[18];
|
||||
char nick[18];
|
||||
}__attribute__((packed)) nick;
|
||||
struct nickrequest{
|
||||
uint8_t reserved[19];
|
||||
|
@ -55,7 +55,7 @@ struct packet{
|
|||
uint8_t gameFlags;
|
||||
uint8_t interval;
|
||||
uint8_t jitter;
|
||||
uint8_t gameTitle[8];
|
||||
char gameTitle[8];
|
||||
}__attribute__((packed)) announce;
|
||||
struct join{
|
||||
uint16_t gameId;
|
||||
|
@ -93,7 +93,7 @@ uint16_t gameId;
|
|||
uint8_t interval;
|
||||
uint8_t jitter;
|
||||
uint8_t flags;
|
||||
uint8_t *gameTitle;
|
||||
char *gameTitle;
|
||||
|
||||
void sendButton(uint8_t button);
|
||||
void sendJoin(uint32_t game);
|
||||
|
@ -321,7 +321,7 @@ void processNickRequest( struct nickrequest *nq)
|
|||
p.id= id;
|
||||
p.ctr= ++ctr;
|
||||
p.c.nick.flags = 0;
|
||||
uint8_t *nick = GLOBAL(nickname);
|
||||
char *nick = GLOBAL(nickname);
|
||||
strcpy(p.c.nick.nick, nick);
|
||||
nrf_snd_pkt_crc(sizeof(p),(uint8_t*)&p);
|
||||
}
|
||||
|
@ -374,7 +374,7 @@ void processText(struct text *t)
|
|||
if( t->flags & FLAGS_CLS )
|
||||
lcdClear() ;
|
||||
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);
|
||||
lcdRefresh();
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ void ram(void) {
|
|||
case BTN_RIGHT: if (kok) { xs++; xs&=63; 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_ENTER: return 0;
|
||||
case BTN_ENTER: return;
|
||||
default: kok=1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 ();
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
size_t strlen(const char *s);
|
||||
char strcpy(char * restrict dst, const char * restrict src);
|
||||
void memcpy(void *dst, const void *src, size_t len);
|
||||
void memset(void *s, int c, size_t n);
|
||||
char* strcpy(char * restrict dst, const char * restrict src);
|
||||
void* memmove(void *dst, const void *src, size_t len);
|
||||
void* memset(void *s, int c, size_t n);
|
||||
int getrelease();
|
||||
|
|
|
@ -39,7 +39,7 @@ void ram(void) {
|
|||
lcdPrint(" ");
|
||||
lcdPrint(IntToStr(v,2,0));
|
||||
lcdPrint(".");
|
||||
lcdPrint(IntToStr(mv%1000,3,F_ZEROS));
|
||||
lcdPrint(IntToStr(mv%1000,3,F_ZEROS|F_LONG));
|
||||
lcdPrintln("V");
|
||||
|
||||
lcdNl();
|
||||
|
|
|
@ -166,7 +166,7 @@ void lcdInit(void) {
|
|||
lcd_select();
|
||||
|
||||
if(displayType==DISPLAY_N1200){
|
||||
uint8_t initseq[]= { 0xE2,0xAF, // Display ON
|
||||
static uint8_t initseq[]= { 0xE2,0xAF, // Display ON
|
||||
0xA1, // Mirror-X
|
||||
0xA4, 0x2F, 0xB0, 0x10};
|
||||
int i = 0;
|
||||
|
@ -175,7 +175,7 @@ void lcdInit(void) {
|
|||
delayms(5); // actually only needed after the first
|
||||
}
|
||||
}else{ /* displayType==DISPLAY_N1600 */
|
||||
uint8_t initseq_d[] = {
|
||||
static uint8_t initseq_d[] = {
|
||||
0x36,
|
||||
0x29, 0xBA, 0x07,
|
||||
0x15, 0x25, 0x3f,
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
#include "core/pmu/pmu.h"
|
||||
|
||||
#include "basic/basic.h"
|
||||
#include "basic/config.h"
|
||||
#include "lcd/render.h"
|
||||
#include "lcd/print.h"
|
||||
#include "usb/usbmsc.h"
|
||||
#include "filesystem/ff.h"
|
||||
|
||||
|
||||
|
@ -34,7 +37,7 @@
|
|||
|
||||
void wrapper(void);
|
||||
|
||||
int main(void) {
|
||||
void main(void) {
|
||||
// Configure cpu and mandatory peripherals
|
||||
cpuInit(); // Configure the CPU
|
||||
// we do it later
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
#!/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
|
||||
|
||||
if [ ! -d ../firmware ] ; then
|
||||
|
@ -32,9 +38,9 @@ echo "###"
|
|||
echo "### Building final"
|
||||
echo "###"
|
||||
export FINAL=y
|
||||
make clean
|
||||
$MAKE clean
|
||||
./l0dable/mktable.pl
|
||||
make APP=final
|
||||
$MAKE APP=final
|
||||
cp firmware.elf $TARG/final.elf
|
||||
cp firmware.bin $TARG/final.bin
|
||||
|
||||
|
@ -48,7 +54,7 @@ cp ../tools/image/lcd/i42.lcd $TARG/files/nick.lcd
|
|||
echo "###"
|
||||
echo "### Gathering loadables"
|
||||
echo "###"
|
||||
(cd l0dable && make)
|
||||
(cd l0dable && $MAKE)
|
||||
mv l0dable/*.c0d $TARG/files/
|
||||
mv l0dable/*.int $TARG/files/
|
||||
mv l0dable/*.nik $TARG/files/
|
||||
|
@ -59,7 +65,7 @@ if grep -q 'define ENCRYPT_L0DABLE' SECRETS ; then
|
|||
echo "###"
|
||||
echo "### Building crypto"
|
||||
echo "###"
|
||||
(cd ../tools/crypto && make)
|
||||
(cd ../tools/crypto && $MAKE)
|
||||
|
||||
echo "###"
|
||||
echo "### Crypting loadables"
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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();
|
|
@ -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;
|
|
@ -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";
|
|
@ -0,0 +1,2 @@
|
|||
firmware.bin
|
||||
files
|
Loading…
Reference in New Issue