Merge branch 'master' of github.com:r0ket/r0ket

This commit is contained in:
schneider 2012-04-02 13:47:15 +02:00
commit 11903db97c
41 changed files with 1457 additions and 331 deletions

5
firmware/.gitignore vendored
View File

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

View File

@ -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
@ -74,7 +74,7 @@ l0dables: table.c
@cd l0dable && $(MAKE)
clean:
rm -f $(OBJS) $(LD_TEMP) $(OUTFILE).elf $(OUTFILE).bin $(OUTFILE).hex table.c table.h
rm -f $(OBJS) $(LD_TEMP) $(OUTFILE).elf $(OUTFILE).bin $(OUTFILE).hex $(OUTFILE).map table.c table.h
for dir in $(SUBDIRS); do \
$(MAKE) $(CONFIG_MAKE_PRINTDIRECTORY) -C $$dir clean; \
done
@ -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) -Map=$(OUTFILE).map -T $(LD_TEMP) -o $(OUTFILE).elf $(OBJS) $(LDLIBS)
-@echo ""
$(SIZE) $(OUTFILE).elf
-@echo ""

View File

@ -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"

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>
- builds "application" foo (check <foo>.c and the <foo> subdir in applications/)

View File

@ -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'){

View File

@ -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,

View File

@ -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[];
};

View File

@ -1,5 +1,6 @@
#ifndef _ECC_H_
#define _ECC_H_H
#include <sysdefs.h>
#include <stdint.h>
/******************************************************************************/

0
firmware/core/libc/stdio.c Executable file → Normal file
View File

5
firmware/core/libc/string.c Executable file → Normal file
View File

@ -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++;

View File

@ -39,20 +39,12 @@
#ifndef _SYSDEFS_H_
#define _SYSDEFS_H_
#include "../sysdefs.h"
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
// Stay compatible with ugly "windows" style
#define BOOL bool
#define TRUE true
#define FALSE false
typedef volatile uint8_t REG8;
typedef volatile uint16_t REG16;
typedef volatile uint32_t REG32;
typedef unsigned char byte_t;
#define pREG8 (REG8 *)
#define pREG16 (REG16 *)
#define pREG32 (REG32 *)

View File

@ -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;
while(1){
char files[PERPAGE][FLEN];
int count = getFiles(files, PERPAGE, skip, extension);
if(!count){
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<PERPAGE && selected==count){
skip--;
@ -88,14 +93,17 @@ 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{
if(skip == file_count - PERPAGE) { // wrap to top
selected = 0;
skip = 0;
} else
skip++;
}
break;
@ -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;
}
}

View File

@ -13,6 +13,10 @@ char meshgen=0; // Generation
char meshincctr=0;
char meshmsg=0;
char meshnice=0;
char mesh_mode=0;
#define MM_TIME (1<<0)
#define MM_ENC (1<<1)
MPKT meshbuffer[MESHBUFSIZE];
#include "SECRETS"
@ -23,6 +27,8 @@ static int mesh_gt(char curgen, char newgen){
unsigned char dif=curgen-newgen;
if(curgen==0)
return 1;
if(newgen==0)
return 0;
return (dif>128);
};
@ -43,21 +49,24 @@ void initMesh(void){
int mesh_sanity(uint8_t * pkt){
if(MO_TYPE(pkt)>0x7f || MO_TYPE(pkt)<0x20)
return MP_SEND;
if(MO_TYPE(pkt)=='T' && MO_BODY(pkt)[5])
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)>1326409200)
if(MO_TIME(pkt)>1370340000) /* 4.Jun 2013 */
return MP_SEND;
if(MO_TIME(pkt)<1324602000)
if(MO_TIME(pkt)<1325376000) /* 1.1.2012 */
return MP_SEND;
}else if(MO_TYPE(pkt)>='a' && MO_TYPE(pkt)<='z'){
if(MO_TIME(pkt)>16777216)
if(MO_TIME(pkt)>16777216) /* 3-byte only */
return MP_SEND;
if(MO_TIME(pkt)<0)
return MP_SEND;
};
if(MO_TYPE(pkt)!='A' &&
MO_TYPE(pkt)!='a' &&
MO_TYPE(pkt)!='i' &&
MO_TYPE(pkt)!='B' &&
MO_TYPE(pkt)!='E' &&
MO_TYPE(pkt)!='F' &&
@ -97,6 +106,7 @@ void meshPanic(uint8_t * pkt,int bufno){
#if 0
static int done=0;
if(!done){
gpioSetValue (RB_LED0, 1-gpioGetValue(RB_LED0));
setSystemFont();
lcdClear();
lcdPrint("PANIC[");
@ -105,9 +115,15 @@ void meshPanic(uint8_t * pkt,int bufno){
lcdNl();
for(int i=0;i<32;i++){
lcdPrint(IntToStrX(pkt[i],2));
if(i%6==5)
if(i%6==2){
lcdPrint(" ");
};
if(i%6==5){
lcdNl();
};
}
lcdPrint(" ");
lcdPrint(IntToStrX(crc16(pkt,30),4));
lcdRefresh();
while ((getInputRaw())==BTN_NONE);
};
@ -156,10 +172,13 @@ void mesh_sendloop(void){
// Update [T]ime packet
MO_TIME_set(meshbuffer[0].pkt,getSeconds());
MO_GEN_set(meshbuffer[0].pkt,meshgen);
if(GLOBAL(privacy)==0)
if(GLOBAL(privacy)==0){
uint32touint8p(GetUUID32(),meshbuffer[0].pkt+26);
else
uint32touint8p(getrelease(),meshbuffer[0].pkt+22);
}else{
uint32touint8p(0,meshbuffer[0].pkt+26);
uint32touint8p(0,meshbuffer[0].pkt+22);
};
MO_BODY(meshbuffer[0].pkt)[4]=meshnice;
@ -223,7 +242,7 @@ uint8_t mesh_recvqloop_work(void){
if(mesh_sanity(buf)){
meshincctr++;
if((mesh_sanity(buf)&MP_RECV)!=0){
meshPanic(buf,-1);
meshPanic(buf,-len);
};
return 0;
};
@ -235,6 +254,7 @@ uint8_t mesh_recvqloop_work(void){
meshincctr=0;
meshnice=MO_BODY(buf)[4];
meshgen=MO_GEN(buf);
mesh_mode&=~MM_TIME;
};
};
@ -243,15 +263,19 @@ uint8_t mesh_recvqloop_work(void){
return 0;
};
// Set new time iff newer
// Set new time iff I don't have a valid one.
if((mesh_mode & MM_TIME)==0){
if(MO_TYPE(buf)=='T'){
time_t toff=MO_TIME(buf)-((getTimer()+(600/SYSTICKSPEED))/(1000/SYSTICKSPEED));
if (toff>_timet){ // Do not live in the past.
_timet = toff;
meshincctr++;
if(meshgen==0 && MO_TIME(buf)<60*60*24){
; // still not valid
}else{
mesh_mode|=MM_TIME; // Got a time now.
};
return 1;
};
};
// Safety: Truncate ascii packets by 0-ing the CRC
buf[MESHPKTSIZE-2]=0;
@ -318,7 +342,7 @@ void mesh_recvqloop_end(void){
nrf_config_set(&oldconfig);
}
void mesh_recvloop(void){
void mesh_recvloop(void){ /* unused: replaced by mesh_recvloop_plus */
int recvend=M_RECVTIM/SYSTICKSPEED+getTimer();
int pktctr=0;
@ -329,7 +353,7 @@ void mesh_recvloop(void){
}else{
delayms_power(10);
};
}while(getTimer()<recvend || pktctr>MESHBUFSIZE);
}while(getTimer()<recvend && pktctr<MESHBUFSIZE);
mesh_recvqloop_end();
};

View File

@ -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));

View File

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

View File

@ -43,8 +43,8 @@ $(LDFILE):
%.o : %.c
$(CC) $(CFLAGS) -o $@ $<
%.elf: %.o $(FIRMWARE) $(LDFILE)
$(LD) $(LDFLAGS) -T $(LDFILE) -o $@ $<
%.elf: %.o $(FIRMWARE) $(LDFILE) libmemcpy.a
$(LD) $(LDFLAGS) -T $(LDFILE) -o $@ $< -L. -lmemcpy
$(SIZE) $@
%.bin: %.elf
@ -85,6 +85,13 @@ $(OBJS): usetable.h
usetable.h:
./mktable.pl
help/memcpy.o: help/memcpy.c
libmemcpy.a: help/memcpy.o
$(AR) rcs $@ $<
$(RANLIB) $(RANLIBFLAGS) $@
.SUFFIXES:
.PHONY: $(LDFILE)

View File

@ -83,6 +83,7 @@ void m_time(void){
struct tm* tm;
int select=0;
char c[2]={0,0};
int sp;
getInputWaitRelease();
delayms(100);
while(1) {
@ -95,6 +96,7 @@ void m_time(void){
lcdPrint(":");
lcdPrint(IntToStr(tm->tm_sec,2,F_LONG|F_ZEROS));
lcdNl();
lcdPrint(" ");
lcdPrint(IntToStr(tm->tm_mday,2,F_LONG));
lcdPrint(".");
lcdPrint(IntToStr(tm->tm_mon+1,2,0));
@ -132,6 +134,11 @@ void m_time(void){
lcdNl();
lcdPrint("Inc:");
lcdPrintInt(meshincctr);
lcdPrint(" SP:");
__asm( "mov %0, sp\n" : "=r" (sp) :);
lcdPrint(IntToStrX(sp,4));
lcdNl();
lcdPrint("Nice:");
lcdPrintInt(meshnice);
@ -168,6 +175,8 @@ void m_time(void){
case BTN_UP:
active=1;
break;
case BTN_NONE:
break;
default:
return;
};

View File

@ -0,0 +1,10 @@
#include <string.h>
#include "../usetable.h"
#undef memcpy
void * memcpy(void *dst, const void *src, size_t len){
return
(*(void * (*)(void *, const void *, size_t ))(*(TheTable+_memcpy_nr)))
(dst, src, len);
};

View File

@ -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 ){

View File

@ -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;
}

View File

@ -5,6 +5,7 @@
use strict;
my $DIR="l0dable";
my $memcpy;
if( -d "../$DIR"){
chdir("..");
@ -105,10 +106,16 @@ for my $idx (0..$#symb){
print C "$_,";
};
print I "#define $_ ($types{$_}(TheTable[$idx]))";
if($_ eq "memcpy" || $_ eq "memmove"){
$memcpy=$idx
};
};
print C "};";
if (defined($memcpy)){
print I "#define _memcpy_nr $memcpy";
};
close(I);
close(H);
close(C);

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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();
}

View File

@ -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;
}
}

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);
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();

View File

@ -11,41 +11,111 @@
/**************************************************************************/
// Improved version by Ikarus:
// Added graphical battery.
// hLine and vLine code from Juna, nougad and fu86
// (camp 2011, CTHN Village)
void hLine(int y, int x1, int x2, bool pixel);
void vLine(int x, int y1, int y2, bool pixel);
void drawCommonThings(int c);
void rectFill(int x, int y, int width, int heigth, bool pixel);
void ram(void) {
int v,mv,c;
char old_state=-1;
do{
lcdClear();
lcdPrintln("Battery status:");
c = gpioGetValue(RB_PWR_CHRG);
mv = GetVoltage();
v=mv/1000;
lcdNl();
if(!c){
lcdPrintln("CHARGING");
}else if (mv<3550){
// Print state and draw battery (only if state changed).
if(!c && old_state != 0){
drawCommonThings(c);
DoString(17, 29, "Charging");
old_state = 0;
}else if (c && mv<3550 && old_state != 1){
drawCommonThings(c);
lcdPrintln(" Charge NOW!");
}else if (mv<3650){
old_state = 1;
}else if (c && mv<3650 && mv>=3550 && old_state != 2){
drawCommonThings(c);
lcdPrintln(" Charge soon");
}else if (mv<4000){
rectFill(16, 25, 12, 16, true);
old_state = 2;
}else if (c && mv<4000 && mv>=3650 && old_state != 3){
drawCommonThings(c);
lcdPrintln(" OK");
}else if(mv<4200){
rectFill(16, 25, 12, 16, true);
rectFill(30, 25, 12, 16, true);
old_state = 3;
}else if (c && mv<4120 && mv>=4000 && old_state != 4){
drawCommonThings(c);
lcdPrintln(" Good");
}else{
rectFill(16, 25, 12, 16, true);
rectFill(30, 25, 12, 16, true);
rectFill(44, 25, 12, 16, true);
old_state = 4;
}else if (c && mv>=4120 && old_state != 5){
drawCommonThings(c);
lcdPrintln(" Full");
};
rectFill(16, 25, 12, 16, true);
rectFill(30, 25, 12, 16, true);
rectFill(44, 25, 12, 16, true);
rectFill(58, 25, 12, 16, true);
old_state = 5;
}
lcdNl();
// Print voltage. (Every frame).
lcdSetCrsr(0, 50);
v = mv/1000;
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();
if(c){
lcdPrintln("(not charging)");
};
lcdSetCrsr(0, 0);
lcdRefresh();
} while ((getInputWaitTimeout(242))==BTN_NONE);
}
void drawCommonThings(int c) {
lcdClear();
// Print header.
lcdPrintln("Battery status:");
// Draw battery frame.
hLine(23, 14, 72, true);
hLine(43, 14, 72, true);
vLine(14, 23, 43, true);
vLine(72, 23, 28, true);
vLine(72, 38, 43, true);
hLine(28, 72, 78, true);
hLine(38, 72, 78, true);
vLine(78, 28, 38, true);
// Print if not charging.
lcdSetCrsr(0, 60);
if(c){
lcdPrintln("(not charging)");
};
lcdSetCrsr(0, 10);
}
void hLine(int y, int x1, int x2, bool pixel) {
for (int i=x1; i<=x2; ++i) {
lcdSetPixel(i, y, pixel);
}
}
void vLine(int x, int y1, int y2, bool pixel) {
for (int i=y1; i<=y2; ++i) {
lcdSetPixel(x, i, pixel);
}
}
void rectFill(int x, int y, int width, int heigth, bool pixel) {
for (int i=y; i<=y+heigth; ++i) {
hLine(i, x, x+width, pixel);
}
}

View File

@ -166,7 +166,16 @@ void lcdInit(void) {
lcd_select();
if(displayType==DISPLAY_N1200){
uint8_t initseq[]= { 0xE2,0xAF, // Display ON
/* Decoded:
* E2: Internal reset
* AF: Display on/off: DON = 1
* A1: undefined?
* A4: all on/normal: DAL = 0
* 2F: charge pump on/off: PC = 1
* B0: set y address: Y[0-3] = 0
* 10: set x address (upper bits): X[6-4] = 0
*/
static uint8_t initseq[]= { 0xE2,0xAF, // Display ON
0xA1, // Mirror-X
0xA4, 0x2F, 0xB0, 0x10};
int i = 0;
@ -175,7 +184,29 @@ void lcdInit(void) {
delayms(5); // actually only needed after the first
}
}else{ /* displayType==DISPLAY_N1600 */
uint8_t initseq_d[] = {
static uint8_t initseq_d[] = {
/* Decoded:
* CMD 36: MADCTL (argument missing!)
* CMD 29: DISPON
* CMD BA: Data order (1)
* DAT 07: ignored?
* CMD 15: undefined?
* DAT 25: ignored?
* DAT 3F: ignored?
* CMD 11: sleep out
* CMD 13: normal display mode on
* CMD 37: set scroll entry point
* DAT 00: scroll entry point
* CMD 3A: interface pixel format
* DAT 05: 16 bit/pixel
* CMD 2A: column address set
* DAT 0 : xs
* DAT 98-1 : xe
* CMD 2B: page address set
* DAT 0 : ys
* DAT 70-1 : ye
*/
0x36,
0x29, 0xBA, 0x07,
0x15, 0x25, 0x3f,
@ -239,9 +270,12 @@ static void _helper_hline(uint16_t color){
_helper_pixel16(color);
}
#define THECOLOR_R 0x0
#define THECOLOR_G 0x60
#define THECOLOR_B 0x0
#define COLORPACK_RGB565(r,g,b) (((r&0xF8) << 8) | ((g&0xFC)<<3) | ((b&0xF8) >> 3))
static const uint16_t COLOR_FG = COLORPACK_RGB565(0x00, 0x60, 0x00);
static const uint16_t COLOR_BG = COLORPACK_RGB565(0xff, 0xff, 0xff);
static const uint16_t COLOR_FRAME = COLORPACK_RGB565(0x00, 0x00, 0x80);
void lcdDisplay(void) {
char byte;
@ -266,25 +300,17 @@ void lcdDisplay(void) {
}
}
} else { /* displayType==DISPLAY_N1600 */
unsigned char r=THECOLOR_R,g=THECOLOR_G,b=THECOLOR_B;
unsigned char br=0xFF, bg=0xFF, bb=0xFF;
unsigned char frame_r=0x00, frame_g=0x00, frame_b=0x80;
uint16_t color,framecolor,backcolor;
uint16_t x,y;
bool px;
uint16_t actualcolor;
color = ((r&0xF8) << 8) | ((g&0xFC)<<3) | ((b&0xF8) >> 3);
framecolor= ((frame_r&0xF8) << 8) | ((frame_g&0xFC)<<3) | ((frame_b&0xF8) >> 3);
backcolor= ((br&0xF8) << 8) | ((bg&0xFC)<<3) | ((bb&0xF8) >> 3);
lcdWrite(TYPE_CMD,0x2C);
//top line of the frame...
_helper_hline(framecolor);
_helper_hline(COLOR_FRAME);
for(y=RESY;y>0;y--){
//left line of the frame
_helper_pixel16(framecolor);
_helper_pixel16(COLOR_FRAME);
for(x=RESX;x>0;x--){
if(GLOBAL(lcdmirror))
@ -292,17 +318,19 @@ void lcdDisplay(void) {
else
px=lcdGetPixel(x-1,y-1);
if((!px)^(!GLOBAL(lcdinvert))) actualcolor=color;
else actualcolor=backcolor; /* white */
if((!px)^(!GLOBAL(lcdinvert))) {
_helper_pixel16(COLOR_FG); /* foreground */
} else {
_helper_pixel16(COLOR_BG); /* background */
}
_helper_pixel16(actualcolor);
}
//right line of the frame
_helper_pixel16(framecolor);
_helper_pixel16(COLOR_FRAME);
}
//bottom line of the frame
_helper_hline(framecolor);
_helper_hline(COLOR_FRAME);
}
lcd_deselect();
}

View File

@ -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
@ -77,5 +80,5 @@ int main(void) {
}
int getrelease(void){
return 0x00000108;
return 0x0000010d;
};

View File

@ -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"

View File

@ -36,10 +36,10 @@
*/
/**************************************************************************/
#ifndef _SYSDEFS_H_
#define _SYSDEFS_H_
#ifndef _GLOBAL_SYSDEFS_H_
#define _GLOBAL_SYSDEFS_H_
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
@ -53,18 +53,9 @@ typedef volatile uint16_t REG16;
typedef volatile uint32_t REG32;
typedef unsigned char byte_t;
#define pREG8 (REG8 *)
#define pREG16 (REG16 *)
#define pREG32 (REG32 *)
#ifndef NULL
#define NULL ((void *) 0)
#endif
// Save some space
#ifndef SIMULATOR
#define memcpy memmove
#endif
#endif

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;
};

View File

@ -138,6 +138,7 @@ if($cmd =~ /^r/){
# print unpack("N",substr($str,2,4))," ";
print strftime("%Y-%m-%d %H:%M:%S",gmtime unpack("N",substr($str,2,4)));
printf " (%+3d)",unpack("N",substr($str,2,4))-(time+3600);
print " rel=",unpack("H*",substr($str,24,2));
print " beacon=",resolvebeacon(unpack("H*",substr($str,26,4)))," ";
}elsif($i eq "i"){
print "score=",unpack("N",substr($str,2,4))," ";

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: <", r0ket::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

View File

@ -1,7 +1,20 @@
default: build setup
all: build setup run
redo: rebuild setup run
build: cleanbuild rebuild
cleanbuild:
cd ../../firmware && make clean
rebuild:
cd ../../firmware && make && make l0dables
setup:
cd ../../firmware && make clean && make && make l0dables
cp ../../firmware/firmware.bin .
-mkdir files
mkdir -p files
cp ../../firmware/l0dable/*c0d files
cp ../../firmware/l0dable/*nik files
cp ../../firmware/l0dable/*int files
@ -12,10 +25,11 @@ setup:
cd ../crypto && make clean && make generate-keys
cp ../crypto/generate-keys .
@echo
@echo Now run ./smartflash
@echo "Now run ./smartflash (as root)"
run:
sudo ./smartflash
clean:
rm -f firmware.bin generate-keys
rm -rf files