Merge branch 'master' into meshdebug
This commit is contained in:
commit
54d4c31250
|
@ -1,5 +1,5 @@
|
||||||
firmware.bin
|
*.bin
|
||||||
firmware.elf
|
*.elf
|
||||||
lpc1xxx/memory.ld
|
lpc1xxx/memory.ld
|
||||||
applications/wrapper.c
|
applications/wrapper.c
|
||||||
lcd/allfonts.h
|
lcd/allfonts.h
|
||||||
|
|
|
@ -37,13 +37,13 @@ ifdef APP
|
||||||
OUTFILE=$(APP)
|
OUTFILE=$(APP)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LDFLAGS+= -Wl,--gc-sections
|
LDFLAGS+= --gc-sections
|
||||||
OBJS += lpc1xxx/$(TARGET)_handlers.o lpc1xxx/LPC1xxx_startup.o
|
OBJS += lpc1xxx/$(TARGET)_handlers.o lpc1xxx/LPC1xxx_startup.o
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# Startup files
|
# Startup files
|
||||||
##########################################################################
|
##########################################################################
|
||||||
LDLIBS = -lm
|
LDLIBS =
|
||||||
LDLIBS += -Lapplications -lapp
|
LDLIBS += -Lapplications -lapp
|
||||||
LDLIBS += -Lfunk -lfunk
|
LDLIBS += -Lfunk -lfunk
|
||||||
LDLIBS += -Lusbcdc -lusbcdc
|
LDLIBS += -Lusbcdc -lusbcdc
|
||||||
|
@ -111,7 +111,7 @@ $(LD_TEMP):
|
||||||
-@echo "INCLUDE $(LD_SCRIPT)" >> $(LD_TEMP)
|
-@echo "INCLUDE $(LD_SCRIPT)" >> $(LD_TEMP)
|
||||||
|
|
||||||
$(OUTFILE).elf: $(OBJS) $(SYS_OBJS) $(SUBDIRS) $(LPCFIX) $(LD_TEMP)
|
$(OUTFILE).elf: $(OBJS) $(SYS_OBJS) $(SUBDIRS) $(LPCFIX) $(LD_TEMP)
|
||||||
$(CC) $(LDFLAGS) -T $(LD_TEMP) -o $(OUTFILE).elf $(OBJS) $(LDLIBS)
|
$(LD) $(LDFLAGS) -T $(LD_TEMP) -o $(OUTFILE).elf $(OBJS) $(LDLIBS)
|
||||||
-@echo ""
|
-@echo ""
|
||||||
$(SIZE) $(OUTFILE).elf
|
$(SIZE) $(OUTFILE).elf
|
||||||
-@echo ""
|
-@echo ""
|
||||||
|
|
|
@ -42,7 +42,7 @@ CPU_TYPE = cortex-$(CORTEX_TYPE)
|
||||||
# Compiler settings, parameters and flags
|
# Compiler settings, parameters and flags
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
CFLAGS = -std=c99 -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -DRAMCODE=$(RAMCODE) -fno-builtin -Wno-unused-function
|
CFLAGS = -std=c99 -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -DRAMCODE=$(RAMCODE) -fno-builtin -Wno-unused-function -ffreestanding
|
||||||
LDFLAGS = -nostartfiles
|
LDFLAGS = -nostartfiles
|
||||||
|
|
||||||
ifeq "$(USBSERIAL)" "YES"
|
ifeq "$(USBSERIAL)" "YES"
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
make flags supported by this Makefile
|
### A note on the compiler
|
||||||
|
We are currently using the CodeSourcery gcc (see wiki for link).
|
||||||
|
You can also use a standard arm cross-gcc
|
||||||
|
(https://github.com/esden/summon-arm-toolchain)
|
||||||
|
but please note that this creates larger binaries.
|
||||||
|
We are talking about 100-200 bytes for firmware.bin,
|
||||||
|
you will run into space problems with the default firmware.
|
||||||
|
Sorry about that.
|
||||||
|
|
||||||
|
### Make flags supported by this Makefile
|
||||||
|
|
||||||
APP=<foo>
|
APP=<foo>
|
||||||
- builds "application" foo (check <foo>.c and the <foo> subdir in applications/)
|
- builds "application" foo (check <foo>.c and the <foo> subdir in applications/)
|
||||||
|
|
|
@ -186,6 +186,9 @@ void m_choose(){
|
||||||
case('r'):
|
case('r'):
|
||||||
strcpy(p,"r0type");
|
strcpy(p,"r0type");
|
||||||
break;
|
break;
|
||||||
|
case('s'):
|
||||||
|
strcpy(p,"Snake");
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
p[0]=*mm;
|
p[0]=*mm;
|
||||||
|
@ -233,6 +236,9 @@ void m_choose(){
|
||||||
case('r'):
|
case('r'):
|
||||||
strcpy(p,"r0type");
|
strcpy(p,"r0type");
|
||||||
break;
|
break;
|
||||||
|
case('s'):
|
||||||
|
strcpy(p,"Snake");
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
if(tmm[i]>='a' && tmm[i]<='z'){
|
if(tmm[i]>='a' && tmm[i]<='z'){
|
||||||
|
|
|
@ -18,7 +18,7 @@ void rbInit() {
|
||||||
gpioSetDir(USB_CONNECT, gpioDirection_Output);
|
gpioSetDir(USB_CONNECT, gpioDirection_Output);
|
||||||
gpioSetValue(USB_CONNECT, 1);
|
gpioSetValue(USB_CONNECT, 1);
|
||||||
|
|
||||||
uint8_t ports[] = { RB_BTN0, RB_BTN1, RB_BTN2, RB_BTN3, RB_BTN4,
|
static uint8_t ports[] = { RB_BTN0, RB_BTN1, RB_BTN2, RB_BTN3, RB_BTN4,
|
||||||
RB_LED0, RB_LED1, RB_LED2,
|
RB_LED0, RB_LED1, RB_LED2,
|
||||||
RB_SPI_SS0, RB_SPI_SS1, RB_SPI_SS2,
|
RB_SPI_SS0, RB_SPI_SS1, RB_SPI_SS2,
|
||||||
RB_SPI_SS3, RB_SPI_SS4, RB_SPI_SS5,
|
RB_SPI_SS3, RB_SPI_SS4, RB_SPI_SS5,
|
||||||
|
|
|
@ -171,12 +171,12 @@ uint16_t crc16(uint8_t * buf, int len);
|
||||||
// menu.c
|
// menu.c
|
||||||
|
|
||||||
struct MENU_DEF {
|
struct MENU_DEF {
|
||||||
char *text;
|
const char *text;
|
||||||
void (*callback)(void);
|
void (*callback)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MENU {
|
struct MENU {
|
||||||
char *title;
|
const char *title;
|
||||||
struct MENU_DEF entries[];
|
struct MENU_DEF entries[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ void * memcpy(void *pDestination, const void *pSource, size_t num)
|
||||||
{
|
{
|
||||||
unsigned char *pByteDestination;
|
unsigned char *pByteDestination;
|
||||||
unsigned char *pByteSource;
|
unsigned char *pByteSource;
|
||||||
|
#ifdef FAST_MEMCPY
|
||||||
unsigned int *pAlignedSource = (unsigned int *) pSource;
|
unsigned int *pAlignedSource = (unsigned int *) pSource;
|
||||||
unsigned int *pAlignedDestination = (unsigned int *) pDestination;
|
unsigned int *pAlignedDestination = (unsigned int *) pDestination;
|
||||||
|
|
||||||
|
@ -71,6 +72,10 @@ void * memcpy(void *pDestination, const void *pSource, size_t num)
|
||||||
// Copy remaining bytes
|
// Copy remaining bytes
|
||||||
pByteDestination = (unsigned char *) pAlignedDestination;
|
pByteDestination = (unsigned char *) pAlignedDestination;
|
||||||
pByteSource = (unsigned char *) pAlignedSource;
|
pByteSource = (unsigned char *) pAlignedSource;
|
||||||
|
#else
|
||||||
|
pByteDestination = (unsigned char *) pDestination;
|
||||||
|
pByteSource = (unsigned char *) pSource;
|
||||||
|
#endif
|
||||||
while (num--) {
|
while (num--) {
|
||||||
|
|
||||||
*pByteDestination++ = *pByteSource++;
|
*pByteDestination++ = *pByteSource++;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#define FLEN 13
|
#define FLEN 13
|
||||||
|
|
||||||
|
/* if count is 0xff (-1) do not fill files and return the count instead */
|
||||||
int getFiles(char files[][FLEN], uint8_t count, uint16_t skip, const char *ext)
|
int getFiles(char files[][FLEN], uint8_t count, uint16_t skip, const char *ext)
|
||||||
{
|
{
|
||||||
DIR dir; /* Directory object */
|
DIR dir; /* Directory object */
|
||||||
|
@ -37,7 +38,9 @@ int getFiles(char files[][FLEN], uint8_t count, uint16_t skip, const char *ext)
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
strcpy(files[pos++],Finfo.fname);
|
if(count != 0xff)
|
||||||
|
strcpy(files[pos],Finfo.fname);
|
||||||
|
pos++;
|
||||||
if( pos == count )
|
if( pos == count )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -50,17 +53,19 @@ int selectFile(char *filename, const char *extension)
|
||||||
int skip = 0;
|
int skip = 0;
|
||||||
char key;
|
char key;
|
||||||
int selected = 0;
|
int selected = 0;
|
||||||
|
int file_count = getFiles(NULL, 0xff, 0, extension);
|
||||||
|
|
||||||
font=&Font_7x8;
|
font=&Font_7x8;
|
||||||
while(1){
|
if(!file_count){
|
||||||
char files[PERPAGE][FLEN];
|
|
||||||
int count = getFiles(files, PERPAGE, skip, extension);
|
|
||||||
if(!count){
|
|
||||||
lcdPrintln("No Files?");
|
lcdPrintln("No Files?");
|
||||||
lcdRefresh();
|
lcdRefresh();
|
||||||
getInputWait();
|
getInputWait();
|
||||||
getInputWaitRelease();
|
getInputWaitRelease();
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
while(1){
|
||||||
|
char files[PERPAGE][FLEN];
|
||||||
|
int count = getFiles(files, PERPAGE, skip, extension);
|
||||||
|
|
||||||
if(count<PERPAGE && selected==count){
|
if(count<PERPAGE && selected==count){
|
||||||
skip--;
|
skip--;
|
||||||
|
@ -88,14 +93,17 @@ int selectFile(char *filename, const char *extension)
|
||||||
files[i][dot]='.';
|
files[i][dot]='.';
|
||||||
}
|
}
|
||||||
lcdRefresh();
|
lcdRefresh();
|
||||||
key=getInputWait();
|
key=getInputWaitRepeat();
|
||||||
getInputWaitRelease();
|
|
||||||
switch(key){
|
switch(key){
|
||||||
case BTN_DOWN:
|
case BTN_DOWN:
|
||||||
if( selected < count-1 ){
|
if( selected < count-1 ){
|
||||||
selected++;
|
selected++;
|
||||||
goto redraw;
|
goto redraw;
|
||||||
}else{
|
}else{
|
||||||
|
if(skip == file_count - PERPAGE) { // wrap to top
|
||||||
|
selected = 0;
|
||||||
|
skip = 0;
|
||||||
|
} else
|
||||||
skip++;
|
skip++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -106,14 +114,20 @@ int selectFile(char *filename, const char *extension)
|
||||||
}else{
|
}else{
|
||||||
if( skip > 0 ){
|
if( skip > 0 ){
|
||||||
skip--;
|
skip--;
|
||||||
|
} else { // wrap to bottom
|
||||||
|
skip = file_count - PERPAGE;
|
||||||
|
if(skip < 0) skip = 0;
|
||||||
|
selected = file_count - skip - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BTN_LEFT:
|
case BTN_LEFT:
|
||||||
|
getInputWaitRelease();
|
||||||
return -1;
|
return -1;
|
||||||
case BTN_ENTER:
|
case BTN_ENTER:
|
||||||
case BTN_RIGHT:
|
case BTN_RIGHT:
|
||||||
strcpy(filename, files[selected]);
|
strcpy(filename, files[selected]);
|
||||||
|
getInputWaitRelease();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,16 +48,16 @@ void initMesh(void){
|
||||||
#define MP_IGNORE 4
|
#define MP_IGNORE 4
|
||||||
int mesh_sanity(uint8_t * pkt){
|
int mesh_sanity(uint8_t * pkt){
|
||||||
if(MO_TYPE(pkt)>0x7f || MO_TYPE(pkt)<0x20)
|
if(MO_TYPE(pkt)>0x7f || MO_TYPE(pkt)<0x20)
|
||||||
return MP_SEND|MP_RECV;
|
return MP_SEND;
|
||||||
if(MO_TYPE(pkt)=='T' && MO_BODY(pkt)[5])
|
if(MO_TYPE(pkt)=='T' && MO_BODY(pkt)[5])
|
||||||
return MP_SEND|MP_RECV;
|
return MP_SEND;
|
||||||
if(MO_TYPE(pkt)=='T' && MO_TIME(pkt)<86400)
|
if(MO_TYPE(pkt)=='T' && MO_TIME(pkt)<86400)
|
||||||
return MP_OK;
|
return MP_OK;
|
||||||
if(MO_TYPE(pkt)>='A' && MO_TYPE(pkt)<='Z'){
|
if(MO_TYPE(pkt)>='A' && MO_TYPE(pkt)<='Z'){
|
||||||
if(MO_TIME(pkt)>1370340000) /* 4.Jun 2013 */
|
if(MO_TIME(pkt)>1370340000) /* 4.Jun 2013 */
|
||||||
return MP_SEND|MP_RECV;
|
return MP_SEND;
|
||||||
if(MO_TIME(pkt)<1325376000) /* 1.1.2012 */
|
if(MO_TIME(pkt)<1325376000) /* 1.1.2012 */
|
||||||
return MP_SEND|MP_RECV;
|
return MP_SEND;
|
||||||
}else if(MO_TYPE(pkt)>='a' && MO_TYPE(pkt)<='z'){
|
}else if(MO_TYPE(pkt)>='a' && MO_TYPE(pkt)<='z'){
|
||||||
if(MO_TIME(pkt)>16777216) /* 3-byte only */
|
if(MO_TIME(pkt)>16777216) /* 3-byte only */
|
||||||
return MP_SEND;
|
return MP_SEND;
|
||||||
|
@ -73,7 +73,7 @@ int mesh_sanity(uint8_t * pkt){
|
||||||
MO_TYPE(pkt)!='G' &&
|
MO_TYPE(pkt)!='G' &&
|
||||||
MO_TYPE(pkt)!='T'
|
MO_TYPE(pkt)!='T'
|
||||||
){
|
){
|
||||||
return MP_IGNORE|MP_RECV;
|
return MP_IGNORE;
|
||||||
};
|
};
|
||||||
return MP_OK;
|
return MP_OK;
|
||||||
};
|
};
|
||||||
|
@ -103,7 +103,7 @@ MPKT * meshGetMessage(uint8_t type){
|
||||||
};
|
};
|
||||||
|
|
||||||
void meshPanic(uint8_t * pkt,int bufno){
|
void meshPanic(uint8_t * pkt,int bufno){
|
||||||
#if 1
|
#if 0
|
||||||
static int done=0;
|
static int done=0;
|
||||||
if(!done){
|
if(!done){
|
||||||
gpioSetValue (RB_LED0, 1-gpioGetValue(RB_LED0));
|
gpioSetValue (RB_LED0, 1-gpioGetValue(RB_LED0));
|
||||||
|
|
|
@ -117,7 +117,7 @@ static bool screen_overview() {
|
||||||
while (key != BTN_ENTER) {
|
while (key != BTN_ENTER) {
|
||||||
lcdClear();
|
lcdClear();
|
||||||
lcdPrintln("Privacy:");
|
lcdPrintln("Privacy:");
|
||||||
lcdPrintln(levels[GLOBAL(privacy)]);
|
lcdPrintln(levels[(int)GLOBAL(privacy)]);
|
||||||
lcdPrintln("");
|
lcdPrintln("");
|
||||||
lcdPrintln("Nickname:");
|
lcdPrintln("Nickname:");
|
||||||
lcdPrintln(GLOBAL(nickname));
|
lcdPrintln(GLOBAL(nickname));
|
||||||
|
|
|
@ -83,7 +83,7 @@ meshnice
|
||||||
#external
|
#external
|
||||||
strcpy
|
strcpy
|
||||||
strlen
|
strlen
|
||||||
memcpy
|
memmove
|
||||||
memset
|
memset
|
||||||
#stuff
|
#stuff
|
||||||
GetLight
|
GetLight
|
||||||
|
|
|
@ -90,6 +90,8 @@ void setLeft();
|
||||||
void setRight();
|
void setRight();
|
||||||
struct packet a;
|
struct packet a;
|
||||||
|
|
||||||
|
void setJeopardy();
|
||||||
|
|
||||||
void ram(void)
|
void ram(void)
|
||||||
{
|
{
|
||||||
int priv = GLOBAL(privacy);
|
int priv = GLOBAL(privacy);
|
||||||
|
@ -103,7 +105,7 @@ void ram(void)
|
||||||
nrf_config_set(&config);
|
nrf_config_set(&config);
|
||||||
|
|
||||||
nrf_set_strength(3);
|
nrf_set_strength(3);
|
||||||
int rnd;
|
// int rnd;
|
||||||
|
|
||||||
volatile uint16_t i;
|
volatile uint16_t i;
|
||||||
while( 1 ){
|
while( 1 ){
|
||||||
|
|
|
@ -221,7 +221,7 @@ static void draw_platforms() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_player() {
|
static void draw_player() {
|
||||||
bool* sprite;
|
const bool* sprite;
|
||||||
if(game.player_y_vel > 0) {
|
if(game.player_y_vel > 0) {
|
||||||
sprite = PLAYER_SPRITE_DOWN;
|
sprite = PLAYER_SPRITE_DOWN;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,11 +71,12 @@ int melody_timeout;
|
||||||
|
|
||||||
static void init_lilakit(void);
|
static void init_lilakit(void);
|
||||||
static void tick_lilakit(void);
|
static void tick_lilakit(void);
|
||||||
|
void melody_play(void);
|
||||||
static void mainloop();
|
static void mainloop();
|
||||||
void handler(void);
|
void handler(void);
|
||||||
|
|
||||||
void ram(void) {
|
void ram(void) {
|
||||||
timer32Callback0 = handler;
|
timer32Callback0 = (uint32_t) handler;
|
||||||
|
|
||||||
/* Enable the clock for CT32B0 */
|
/* Enable the clock for CT32B0 */
|
||||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B0);
|
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B0);
|
||||||
|
|
|
@ -29,7 +29,7 @@ void ram(void) {
|
||||||
if( nrf_rcv_pkt_time(64,sizeof(buf),buf) == 16 ){
|
if( nrf_rcv_pkt_time(64,sizeof(buf),buf) == 16 ){
|
||||||
buf[14] = 0;
|
buf[14] = 0;
|
||||||
if( buf[1] == 0x23 || buf[1] == 0x24){
|
if( buf[1] == 0x23 || buf[1] == 0x24){
|
||||||
lcdPrintln(buf+6);
|
lcdPrintln((char*)(buf+6));
|
||||||
//lcdPrintln("foo");
|
//lcdPrintln("foo");
|
||||||
}
|
}
|
||||||
lcdRefresh();
|
lcdRefresh();
|
||||||
|
|
|
@ -113,6 +113,9 @@ void init();
|
||||||
** Code Section
|
** Code Section
|
||||||
*********************************************/
|
*********************************************/
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void ram();
|
||||||
|
|
||||||
void game(void)
|
void game(void)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
|
@ -139,7 +142,7 @@ void game(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init()
|
void init()
|
||||||
{
|
{
|
||||||
// init ball
|
// init ball
|
||||||
ball1.size = PONG_BALL_SIZE;
|
ball1.size = PONG_BALL_SIZE;
|
||||||
|
|
|
@ -34,11 +34,11 @@ struct packet{
|
||||||
uint8_t x;
|
uint8_t x;
|
||||||
uint8_t y;
|
uint8_t y;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint8_t text[16];
|
char text[16];
|
||||||
}__attribute__((packed)) text;
|
}__attribute__((packed)) text;
|
||||||
struct nick{
|
struct nick{
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint8_t nick[18];
|
char nick[18];
|
||||||
}__attribute__((packed)) nick;
|
}__attribute__((packed)) nick;
|
||||||
struct nickrequest{
|
struct nickrequest{
|
||||||
uint8_t reserved[19];
|
uint8_t reserved[19];
|
||||||
|
@ -55,7 +55,7 @@ struct packet{
|
||||||
uint8_t gameFlags;
|
uint8_t gameFlags;
|
||||||
uint8_t interval;
|
uint8_t interval;
|
||||||
uint8_t jitter;
|
uint8_t jitter;
|
||||||
uint8_t gameTitle[8];
|
char gameTitle[8];
|
||||||
}__attribute__((packed)) announce;
|
}__attribute__((packed)) announce;
|
||||||
struct join{
|
struct join{
|
||||||
uint16_t gameId;
|
uint16_t gameId;
|
||||||
|
@ -93,7 +93,7 @@ uint16_t gameId;
|
||||||
uint8_t interval;
|
uint8_t interval;
|
||||||
uint8_t jitter;
|
uint8_t jitter;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint8_t *gameTitle;
|
char *gameTitle;
|
||||||
|
|
||||||
void sendButton(uint8_t button);
|
void sendButton(uint8_t button);
|
||||||
void sendJoin(uint32_t game);
|
void sendJoin(uint32_t game);
|
||||||
|
@ -321,7 +321,7 @@ void processNickRequest( struct nickrequest *nq)
|
||||||
p.id= id;
|
p.id= id;
|
||||||
p.ctr= ++ctr;
|
p.ctr= ++ctr;
|
||||||
p.c.nick.flags = 0;
|
p.c.nick.flags = 0;
|
||||||
uint8_t *nick = GLOBAL(nickname);
|
char *nick = GLOBAL(nickname);
|
||||||
strcpy(p.c.nick.nick, nick);
|
strcpy(p.c.nick.nick, nick);
|
||||||
nrf_snd_pkt_crc(sizeof(p),(uint8_t*)&p);
|
nrf_snd_pkt_crc(sizeof(p),(uint8_t*)&p);
|
||||||
}
|
}
|
||||||
|
@ -374,7 +374,7 @@ void processText(struct text *t)
|
||||||
if( t->flags & FLAGS_CLS )
|
if( t->flags & FLAGS_CLS )
|
||||||
lcdClear() ;
|
lcdClear() ;
|
||||||
lcdSetCrsr(t->x, t->y);
|
lcdSetCrsr(t->x, t->y);
|
||||||
t->text[16] = 0;
|
t->text[16] = 0; // XXX:Actually ok, beause the CRC is there. But evil!
|
||||||
lcdPrint(t->text);
|
lcdPrint(t->text);
|
||||||
lcdRefresh();
|
lcdRefresh();
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ void ram(void) {
|
||||||
case BTN_RIGHT: if (kok) { xs++; xs&=63; kok=0; } break;
|
case BTN_RIGHT: if (kok) { xs++; xs&=63; kok=0; } break;
|
||||||
case BTN_UP: if (kok) { ch++; ch&=7; kok=0; } break;
|
case BTN_UP: if (kok) { ch++; ch&=7; kok=0; } break;
|
||||||
case BTN_DOWN: if (kok) { ch--; ch&=7; kok=0; } break;
|
case BTN_DOWN: if (kok) { ch--; ch&=7; kok=0; } break;
|
||||||
case BTN_ENTER: return 0;
|
case BTN_ENTER: return;
|
||||||
default: kok=1;
|
default: kok=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
size_t strlen(const char *s);
|
||||||
char strcpy(char * restrict dst, const char * restrict src);
|
char* strcpy(char * restrict dst, const char * restrict src);
|
||||||
void memcpy(void *dst, const void *src, size_t len);
|
void* memmove(void *dst, const void *src, size_t len);
|
||||||
void memset(void *s, int c, size_t n);
|
void* memset(void *s, int c, size_t n);
|
||||||
int getrelease();
|
int getrelease();
|
||||||
|
|
|
@ -39,7 +39,7 @@ void ram(void) {
|
||||||
lcdPrint(" ");
|
lcdPrint(" ");
|
||||||
lcdPrint(IntToStr(v,2,0));
|
lcdPrint(IntToStr(v,2,0));
|
||||||
lcdPrint(".");
|
lcdPrint(".");
|
||||||
lcdPrint(IntToStr(mv%1000,3,F_ZEROS));
|
lcdPrint(IntToStr(mv%1000,3,F_ZEROS|F_LONG));
|
||||||
lcdPrintln("V");
|
lcdPrintln("V");
|
||||||
|
|
||||||
lcdNl();
|
lcdNl();
|
||||||
|
|
|
@ -166,7 +166,7 @@ void lcdInit(void) {
|
||||||
lcd_select();
|
lcd_select();
|
||||||
|
|
||||||
if(displayType==DISPLAY_N1200){
|
if(displayType==DISPLAY_N1200){
|
||||||
uint8_t initseq[]= { 0xE2,0xAF, // Display ON
|
static uint8_t initseq[]= { 0xE2,0xAF, // Display ON
|
||||||
0xA1, // Mirror-X
|
0xA1, // Mirror-X
|
||||||
0xA4, 0x2F, 0xB0, 0x10};
|
0xA4, 0x2F, 0xB0, 0x10};
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -175,7 +175,7 @@ void lcdInit(void) {
|
||||||
delayms(5); // actually only needed after the first
|
delayms(5); // actually only needed after the first
|
||||||
}
|
}
|
||||||
}else{ /* displayType==DISPLAY_N1600 */
|
}else{ /* displayType==DISPLAY_N1600 */
|
||||||
uint8_t initseq_d[] = {
|
static uint8_t initseq_d[] = {
|
||||||
0x36,
|
0x36,
|
||||||
0x29, 0xBA, 0x07,
|
0x29, 0xBA, 0x07,
|
||||||
0x15, 0x25, 0x3f,
|
0x15, 0x25, 0x3f,
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
#include "core/pmu/pmu.h"
|
#include "core/pmu/pmu.h"
|
||||||
|
|
||||||
#include "basic/basic.h"
|
#include "basic/basic.h"
|
||||||
|
#include "basic/config.h"
|
||||||
#include "lcd/render.h"
|
#include "lcd/render.h"
|
||||||
|
#include "lcd/print.h"
|
||||||
|
#include "usb/usbmsc.h"
|
||||||
#include "filesystem/ff.h"
|
#include "filesystem/ff.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,7 +37,7 @@
|
||||||
|
|
||||||
void wrapper(void);
|
void wrapper(void);
|
||||||
|
|
||||||
int main(void) {
|
void main(void) {
|
||||||
// Configure cpu and mandatory peripherals
|
// Configure cpu and mandatory peripherals
|
||||||
cpuInit(); // Configure the CPU
|
cpuInit(); // Configure the CPU
|
||||||
// we do it later
|
// we do it later
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
# We currently don't use crypto, so this script is deprecated.
|
||||||
|
|
||||||
|
if [ -z ${MAKE} ]; then
|
||||||
|
which gmake >/dev/null && MAKE=gmake || MAKE=make
|
||||||
|
fi
|
||||||
|
|
||||||
TARG=../release
|
TARG=../release
|
||||||
|
|
||||||
if [ ! -d ../firmware ] ; then
|
if [ ! -d ../firmware ] ; then
|
||||||
|
@ -32,9 +38,9 @@ echo "###"
|
||||||
echo "### Building final"
|
echo "### Building final"
|
||||||
echo "###"
|
echo "###"
|
||||||
export FINAL=y
|
export FINAL=y
|
||||||
make clean
|
$MAKE clean
|
||||||
./l0dable/mktable.pl
|
./l0dable/mktable.pl
|
||||||
make APP=final
|
$MAKE APP=final
|
||||||
cp firmware.elf $TARG/final.elf
|
cp firmware.elf $TARG/final.elf
|
||||||
cp firmware.bin $TARG/final.bin
|
cp firmware.bin $TARG/final.bin
|
||||||
|
|
||||||
|
@ -48,7 +54,7 @@ cp ../tools/image/lcd/i42.lcd $TARG/files/nick.lcd
|
||||||
echo "###"
|
echo "###"
|
||||||
echo "### Gathering loadables"
|
echo "### Gathering loadables"
|
||||||
echo "###"
|
echo "###"
|
||||||
(cd l0dable && make)
|
(cd l0dable && $MAKE)
|
||||||
mv l0dable/*.c0d $TARG/files/
|
mv l0dable/*.c0d $TARG/files/
|
||||||
mv l0dable/*.int $TARG/files/
|
mv l0dable/*.int $TARG/files/
|
||||||
mv l0dable/*.nik $TARG/files/
|
mv l0dable/*.nik $TARG/files/
|
||||||
|
@ -59,7 +65,7 @@ if grep -q 'define ENCRYPT_L0DABLE' SECRETS ; then
|
||||||
echo "###"
|
echo "###"
|
||||||
echo "### Building crypto"
|
echo "### Building crypto"
|
||||||
echo "###"
|
echo "###"
|
||||||
(cd ../tools/crypto && make)
|
(cd ../tools/crypto && $MAKE)
|
||||||
|
|
||||||
echo "###"
|
echo "###"
|
||||||
echo "### Crypting loadables"
|
echo "### Crypting loadables"
|
||||||
|
|
|
@ -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