Merge branch 'master' of github.com:r0ket/r0ket
|
@ -3,3 +3,4 @@
|
|||
*.a
|
||||
*.swp
|
||||
release
|
||||
*.pyc
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
Receiving:
|
||||
r->h: \1<packet data>\0
|
||||
|
||||
Sending:
|
||||
h->r: \1<packet data>\0
|
||||
r->h: \2\0
|
||||
|
||||
Settings:
|
||||
h->r:\3<TXMAC>\0
|
||||
r->h: \2\0
|
||||
h->r:\4<RXMAX>\0
|
||||
r->h: \2\0
|
||||
h->r:\5<CHANNEL>\0
|
||||
r->h: \2\0
|
||||
h->r:\6<MACLEN>\0
|
||||
r->h: \2\0
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef _SECRETS_
|
||||
#define _SECRETS_
|
||||
|
||||
#define ENCRYPT_L0DABLE 1
|
||||
#undef ENCRYPT_L0DABLE 1
|
||||
|
||||
static uint32_t const meshkey[4] = {
|
||||
0xafbbcb26, 0x39108427, 0x455ef5e5, 0x51b482d2
|
||||
|
|
|
@ -82,7 +82,7 @@ void tick_default(void) {
|
|||
gpioSetValue (RB_LED0, 1);
|
||||
gpioSetValue (RB_LED2, 1);
|
||||
posleds = 1;
|
||||
}else if( posleds = 1 ){
|
||||
}else if( posleds ){
|
||||
gpioSetValue (RB_LED0, 0);
|
||||
gpioSetValue (RB_LED2, 0);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#include <sysinit.h>
|
||||
|
||||
#include "basic/basic.h"
|
||||
|
||||
#include "lcd/print.h"
|
||||
#include "lcd/display.h"
|
||||
|
||||
#include "filesystem/ff.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
void readcfg(void) {
|
||||
readConfig();
|
||||
};
|
||||
|
||||
void savecfg(void){
|
||||
saveConfig();
|
||||
};
|
||||
|
||||
void applycfg(void){
|
||||
applyConfig();
|
||||
};
|
||||
|
||||
void show(void){
|
||||
lcdClear();
|
||||
lcdPrint("time:"); lcdPrintInt(globalconfig.time); lcdNl();
|
||||
lcdPrint("btrig:"); lcdPrintInt(globalconfig.backlighttrigger); lcdNl();
|
||||
lcdPrint("bval:"); lcdPrintInt(globalconfig.backlightvalue); lcdNl();
|
||||
lcdPrint("lcd:"); lcdPrintInt(globalconfig.lcdstate); lcdNl();
|
||||
lcdPrint("priv:"); lcdPrintInt(globalconfig.privacy); lcdNl();
|
||||
lcdRefresh();
|
||||
};
|
||||
|
||||
void lcdmirror(void){
|
||||
lcdToggleFlag(LCD_MIRRORX);
|
||||
};
|
|
@ -0,0 +1,272 @@
|
|||
#include <sysinit.h>
|
||||
|
||||
#include "basic/basic.h"
|
||||
#include "basic/byteorder.h"
|
||||
|
||||
#include "lcd/lcd.h"
|
||||
#include "lcd/print.h"
|
||||
|
||||
#include "funk/nrf24l01p.h"
|
||||
#include "usbcdc/usb.h"
|
||||
#include "usbcdc/usbcore.h"
|
||||
#include "usbcdc/usbhw.h"
|
||||
#include "usbcdc/cdcuser.h"
|
||||
#include "usbcdc/cdc_buf.h"
|
||||
#include "usbcdc/util.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define REMOTE_CHANNEL 91
|
||||
#define REMOTE_MAC "REM0T"
|
||||
|
||||
#if CFG_USBMSC
|
||||
#error "MSC is defined"
|
||||
#endif
|
||||
|
||||
#if !CFG_USBCDC
|
||||
#error "CDC is not defined"
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#include "SECRETS"
|
||||
|
||||
void r_init(void){
|
||||
nrf_init();
|
||||
|
||||
struct NRF_CFG config = {
|
||||
.channel= REMOTE_CHANNEL,
|
||||
.txmac= REMOTE_MAC,
|
||||
.nrmacs=1,
|
||||
.mac0= REMOTE_MAC,
|
||||
.maclen ="\x10",
|
||||
};
|
||||
|
||||
nrf_config_set(&config);
|
||||
};
|
||||
|
||||
void s_init(void){
|
||||
usbCDCInit();
|
||||
nrf_init();
|
||||
|
||||
struct NRF_CFG config = {
|
||||
.channel= REMOTE_CHANNEL,
|
||||
.txmac= REMOTE_MAC,
|
||||
.nrmacs=1,
|
||||
.mac0= REMOTE_MAC,
|
||||
.maclen ="\x10",
|
||||
};
|
||||
|
||||
nrf_config_set(&config);
|
||||
};
|
||||
|
||||
void process(uint8_t * input){
|
||||
__attribute__ ((aligned (4))) uint8_t buf[32];
|
||||
puts("process: ");
|
||||
puts(input);
|
||||
puts("\r\n");
|
||||
if(input[0]=='M'){
|
||||
buf[0]=0x10; // Length: 16 bytes
|
||||
buf[1]='M'; // Proto
|
||||
buf[2]=0x01;
|
||||
buf[3]=0x01; // Unused
|
||||
|
||||
uint32touint8p(0,buf+4);
|
||||
|
||||
uint32touint8p(0x41424344,buf+8);
|
||||
|
||||
buf[12]=0xff; // salt (0xffff always?)
|
||||
buf[13]=0xff;
|
||||
nrf_snd_pkt_crc_encr(16,buf,remotekey);
|
||||
nrf_rcv_pkt_start();
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#define INPUTLEN 99
|
||||
void r_recv(void){
|
||||
__attribute__ ((aligned (4))) uint8_t buf[32];
|
||||
int len;
|
||||
|
||||
uint8_t input[INPUTLEN+1];
|
||||
int inputptr=0;
|
||||
|
||||
nrf_rcv_pkt_start();
|
||||
puts("D start");
|
||||
|
||||
getInputWaitRelease();
|
||||
|
||||
while(!getInputRaw()){
|
||||
delayms(100);
|
||||
|
||||
// Input
|
||||
int l=INPUTLEN-inputptr;
|
||||
CDC_OutBufAvailChar (&l);
|
||||
|
||||
if(l>0){
|
||||
CDC_RdOutBuf (input+inputptr, &l);
|
||||
input[inputptr+l+1]=0;
|
||||
for(int i=0;i<l;i++){
|
||||
if(input[inputptr+i] =='\r'){
|
||||
input[inputptr+i]=0;
|
||||
process(input);
|
||||
if(i<l)
|
||||
memmove(input,input+inputptr+i+1,l-i);
|
||||
inputptr=-i-1;
|
||||
break;
|
||||
};
|
||||
};
|
||||
};
|
||||
inputptr+=l;
|
||||
len=nrf_rcv_pkt_poll_dec(sizeof(buf),buf,remotekey);
|
||||
|
||||
// Receive
|
||||
if(len<=0){
|
||||
delayms(10);
|
||||
continue;
|
||||
};
|
||||
|
||||
if(buf[1]=='C'){ // Cursor
|
||||
puts("C ");
|
||||
puts(IntToStrX( buf[2],2 ));
|
||||
puts(" ");
|
||||
puts(IntToStrX( uint8ptouint32(buf+4), 8 ));
|
||||
puts(" ");
|
||||
puts(IntToStrX( uint8ptouint32(buf+8), 8 ));
|
||||
}else{
|
||||
puts("U ");
|
||||
// puts("[");puts(IntToStrX(len,2));puts("] ");
|
||||
puts(IntToStrX( *(int*)(buf+ 0),2 ));
|
||||
puts(" ");
|
||||
puts(IntToStrX( *(int*)(buf+ 1),2 ));
|
||||
puts(" ");
|
||||
puts(IntToStrX( *(int*)(buf+ 2),2 ));
|
||||
puts(" ");
|
||||
puts(IntToStrX( *(int*)(buf+ 3),2 ));
|
||||
puts(" ");
|
||||
puts(IntToStrX( uint8ptouint32(buf+4),8 ));
|
||||
puts(".");
|
||||
puts(IntToStrX( uint8ptouint32(buf+8),8 ));
|
||||
puts(" ");
|
||||
puts(IntToStrX( uint8ptouint32(buf+10),4 ));
|
||||
};
|
||||
puts("\r\n");
|
||||
|
||||
};
|
||||
|
||||
nrf_rcv_pkt_end();
|
||||
puts("D exit");
|
||||
}
|
||||
|
||||
|
||||
void r_s1(void){
|
||||
static int ctr=1;
|
||||
__attribute__ ((aligned (4))) uint8_t buf[32];
|
||||
int status;
|
||||
|
||||
buf[0]=0x10; // Length: 16 bytes
|
||||
buf[1]='1'; // Proto
|
||||
buf[2]=0x00;
|
||||
buf[3]=0x00; // Unused
|
||||
|
||||
uint32touint8p(ctr++,buf+4);
|
||||
|
||||
uint32touint8p(0x5ec,buf+8);
|
||||
|
||||
buf[12]=0xff; // salt (0xffff always?)
|
||||
buf[13]=0xff;
|
||||
status=nrf_snd_pkt_crc_encr(16,buf,remotekey);
|
||||
|
||||
lcdClear();
|
||||
lcdPrint("F-St:"); lcdPrintInt(status);
|
||||
lcdDisplay();
|
||||
|
||||
};
|
||||
void r_s2(void){
|
||||
static int ctr=1;
|
||||
__attribute__ ((aligned (4))) uint8_t buf[32];
|
||||
int status;
|
||||
|
||||
buf[0]=0x10; // Length: 16 bytes
|
||||
buf[1]='C'; // Proto
|
||||
buf[2]=0x00;
|
||||
buf[3]=0x00; // Unused
|
||||
|
||||
uint32touint8p(ctr++,buf+4);
|
||||
|
||||
uint32touint8p(0x5ec,buf+8);
|
||||
|
||||
buf[12]=0xff; // salt (0xffff always?)
|
||||
buf[13]=0xff;
|
||||
status=nrf_snd_pkt_crc_encr(16,buf,remotekey);
|
||||
|
||||
buf[0]=0x10; // Length: 16 bytes
|
||||
buf[1]='I'; // Proto
|
||||
buf[2]=0x00;
|
||||
buf[3]=0x00; // Unused
|
||||
|
||||
uint32touint8p(ctr++,buf+4);
|
||||
|
||||
uint32touint8p(0x5ec,buf+8);
|
||||
|
||||
buf[12]=0xff; // salt (0xffff always?)
|
||||
buf[13]=0xff;
|
||||
status=nrf_snd_pkt_crc_encr(16,buf,remotekey);
|
||||
|
||||
lcdClear();
|
||||
lcdPrint("F-St:"); lcdPrintInt(status);
|
||||
lcdDisplay();
|
||||
|
||||
};
|
||||
|
||||
void r_send(void){
|
||||
int ctr=1;
|
||||
__attribute__ ((aligned (4))) uint8_t buf[32];
|
||||
int len;
|
||||
int status;
|
||||
|
||||
while(1){
|
||||
|
||||
buf[0]=0x10; // Length: 16 bytes
|
||||
buf[1]='C'; // Proto
|
||||
buf[2]=getInputRaw();
|
||||
buf[3]=0x00; // Unused
|
||||
|
||||
ctr++;
|
||||
*(int*)(buf+4)=ctr;
|
||||
|
||||
/*
|
||||
buf[4]=0x00; // ctr
|
||||
buf[5]=0x00; // ctr
|
||||
buf[6]=0x00; // ctr
|
||||
buf[7]=ctr++; // ctr
|
||||
*/
|
||||
|
||||
buf[8]=0x0; // Object id
|
||||
buf[9]=0x0;
|
||||
buf[10]=0x05;
|
||||
buf[11]=0xec;
|
||||
|
||||
buf[12]=0xff; // salt (0xffff always?)
|
||||
buf[13]=0xff;
|
||||
|
||||
lcdClear();
|
||||
lcdPrint("Key:"); lcdPrintInt(buf[2]); lcdNl();
|
||||
if(buf[2]==BTN_ENTER)
|
||||
break;
|
||||
|
||||
status=nrf_snd_pkt_crc_encr(16,buf,remotekey);
|
||||
|
||||
lcdPrint("F-St:"); lcdPrintInt(status);
|
||||
lcdDisplay();
|
||||
|
||||
len=nrf_rcv_pkt_time_encr(100,sizeof(buf),buf,remotekey);
|
||||
if(len>0){
|
||||
lcdPrint("Got!");
|
||||
lcdDisplay();
|
||||
break;
|
||||
};
|
||||
delayms(10);
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
#include <sysinit.h>
|
||||
|
||||
#include "basic/basic.h"
|
||||
|
||||
#include "lcd/lcd.h"
|
||||
#include "lcd/print.h"
|
||||
|
||||
#include "funk/nrf24l01p.h"
|
||||
|
||||
#include "usbcdc/usb.h"
|
||||
#include "usbcdc/usbcore.h"
|
||||
#include "usbcdc/usbhw.h"
|
||||
#include "usbcdc/cdcuser.h"
|
||||
#include "usbcdc/cdc_buf.h"
|
||||
#include "usbcdc/util.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define BEACON_CHANNEL 81
|
||||
#define BEACON_MAC "\x1\x2\x3\x2\1"
|
||||
|
||||
uint32_t const testkey[4] = {
|
||||
0xB4595344,0xD3E119B6,0xA814D0EC,0xEFF5A24E
|
||||
};
|
||||
|
||||
#if CFG_USBMSC
|
||||
#error "MSC is defined"
|
||||
#endif
|
||||
|
||||
#if !CFG_USBCDC
|
||||
#error "CDC is not defined"
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
void ser_enable(void) {
|
||||
usbCDCInit();
|
||||
};
|
||||
|
||||
void ser_disable(void) {
|
||||
usbCDCOff();
|
||||
};
|
||||
|
||||
#define myLEN 10
|
||||
void ser_read(){
|
||||
uint8_t buf[myLEN+1];
|
||||
int l=myLEN;
|
||||
|
||||
lcdPrint("Bytes:");
|
||||
CDC_OutBufAvailChar (&l);
|
||||
lcdPrintInt(l);
|
||||
lcdNl();
|
||||
|
||||
lcdPrint("read:");
|
||||
CDC_RdOutBuf (buf, &l);
|
||||
lcdPrintInt(l);
|
||||
lcdNl();
|
||||
|
||||
buf[l]=0;
|
||||
lcdPrintln(buf);
|
||||
};
|
||||
|
||||
void ser_say(){
|
||||
puts("hello world\r\n");
|
||||
};
|
||||
|
||||
void f_init(){
|
||||
nrf_init();
|
||||
struct NRF_CFG config = {
|
||||
.channel= BEACON_CHANNEL,
|
||||
.txmac= BEACON_MAC,
|
||||
.nrmacs=1,
|
||||
.mac0= BEACON_MAC,
|
||||
.maclen ="\x10",
|
||||
};
|
||||
|
||||
nrf_config_set(&config);
|
||||
};
|
||||
|
||||
void f_beacon(void){
|
||||
struct NRF_CFG config = {
|
||||
.channel= BEACON_CHANNEL,
|
||||
.txmac= BEACON_MAC,
|
||||
.nrmacs=1,
|
||||
.mac0= BEACON_MAC,
|
||||
.maclen ="\x10",
|
||||
};
|
||||
|
||||
nrf_config_set(&config);
|
||||
};
|
||||
|
||||
int enctoggle=0;
|
||||
|
||||
void f_enctog(){
|
||||
enctoggle=1-enctoggle;
|
||||
lcdClear();
|
||||
lcdPrint("Encryption:");
|
||||
if(enctoggle)
|
||||
lcdPrintln("ON");
|
||||
else
|
||||
lcdPrintln("Off");
|
||||
};
|
||||
|
||||
void f_recser(void){
|
||||
__attribute__ ((aligned (4))) uint8_t buf[32];
|
||||
int len;
|
||||
|
||||
getInputWaitRelease();
|
||||
|
||||
do{
|
||||
len=nrf_rcv_pkt_time_encr(1000,sizeof(buf),buf,enctoggle?testkey:NULL);
|
||||
|
||||
if(len==0){
|
||||
puts("(Timeout)\r\n");
|
||||
};
|
||||
puts("pkt: ");
|
||||
puts("[");puts(IntToStrX(len,2));puts("] ");
|
||||
puts(IntToStrX( *(int*)(buf+ 0),2 ));
|
||||
puts(" ");
|
||||
puts(IntToStrX( *(int*)(buf+ 1),2 ));
|
||||
puts(" ");
|
||||
puts(IntToStrX( *(int*)(buf+ 2),2 ));
|
||||
puts(" ");
|
||||
puts(IntToStrX( *(int*)(buf+ 3),2 ));
|
||||
puts(".");
|
||||
puts(IntToStrX( *(int*)(buf+ 4),8 ));
|
||||
puts(".");
|
||||
puts(IntToStrX( *(int*)(buf+ 8),8 ));
|
||||
puts(".");
|
||||
puts(IntToStrX( *(int*)(buf+ 12),4 ));
|
||||
puts(" [");
|
||||
|
||||
len=crc16(buf,14);
|
||||
puts(IntToStrX(len,4)); puts("]\r\n");
|
||||
delayms(10);
|
||||
}while ((getInputRaw())==BTN_NONE);
|
||||
|
||||
};
|
|
@ -0,0 +1,128 @@
|
|||
#include <sysinit.h>
|
||||
|
||||
#include "basic/basic.h"
|
||||
|
||||
#include "lcd/lcd.h"
|
||||
#include "lcd/print.h"
|
||||
#include "lcd/allfonts.h"
|
||||
|
||||
#include "filesystem/ff.h"
|
||||
#include "filesystem/select.h"
|
||||
#include "funk/nrf24l01p.h"
|
||||
#include "usb/usbmsc.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
void show_ticks(void) {
|
||||
int dx=0;
|
||||
int dy=8;
|
||||
lcdClear();
|
||||
dx=DoString(0,dy,"Ticks:");
|
||||
while ((getInputRaw())==BTN_NONE){
|
||||
DoInt(0,dy+8,_timectr);
|
||||
lcdDisplay();
|
||||
};
|
||||
dy+=16;
|
||||
dx=DoString(0,dy,"Done.");
|
||||
};
|
||||
|
||||
|
||||
void chrg_stat(void) {
|
||||
int stat;
|
||||
while ((getInputRaw())==BTN_NONE){
|
||||
lcdClear();
|
||||
lcdPrintln("Chrg_stat:");
|
||||
stat=gpioGetValue(RB_PWR_CHRG);
|
||||
lcdPrint(IntToStr(stat,3,0));
|
||||
lcdNl();
|
||||
lcdRefresh();
|
||||
};
|
||||
lcdPrintln("Done.");
|
||||
};
|
||||
void adc_light(void) {
|
||||
int dx=0;
|
||||
int dy=8;
|
||||
dx=DoString(0,dy,"Light:");
|
||||
DoString(0,dy+16,"Night:");
|
||||
while ((getInputRaw())==BTN_NONE){
|
||||
DoInt(dx,dy,GetLight());
|
||||
DoInt(dx,dy+16,isNight());
|
||||
DoInt(dx,dy+8,GLOBAL(daytrig));
|
||||
lcdDisplay();
|
||||
};
|
||||
dy+=8;
|
||||
dx=DoString(0,dy,"Done.");
|
||||
};
|
||||
|
||||
void uptime(void) {
|
||||
int t;
|
||||
int h;
|
||||
char flag;
|
||||
while ((getInputRaw())==BTN_NONE){
|
||||
lcdClear();
|
||||
lcdPrintln("Uptime:");
|
||||
t=getTimer()/(1000/SYSTICKSPEED);
|
||||
h=t/60/60;
|
||||
flag=F_ZEROS;
|
||||
if(h>0){
|
||||
lcdPrint(IntToStr(h,2,flag));
|
||||
lcdPrint("h");
|
||||
flag|=F_LONG;
|
||||
};
|
||||
h=t/60%60;
|
||||
if(h>0){
|
||||
lcdPrint(IntToStr(h,2,flag));
|
||||
lcdPrint("m");
|
||||
flag|=F_LONG;
|
||||
};
|
||||
h=t%60;
|
||||
if(h>0){
|
||||
lcdPrint(IntToStr(h,2,flag));
|
||||
lcdPrint("s");
|
||||
};
|
||||
lcdNl();
|
||||
lcdRefresh();
|
||||
delayms_queue(200);
|
||||
};
|
||||
lcdPrintln("done.");
|
||||
};
|
||||
|
||||
void gotoISP(void) {
|
||||
DoString(0,0,"Enter ISP!");
|
||||
lcdDisplay();
|
||||
ISPandReset();
|
||||
}
|
||||
|
||||
void lcd_mirror(void) {
|
||||
lcdToggleFlag(LCD_MIRRORX);
|
||||
};
|
||||
|
||||
void lcd_invert(void) {
|
||||
lcdToggleFlag(LCD_INVERTED);
|
||||
};
|
||||
|
||||
void adc_check(void) {
|
||||
int dx=0;
|
||||
int dy=8;
|
||||
// Print Voltage
|
||||
dx=DoString(0,dy,"Voltage:");
|
||||
while ((getInputRaw())==BTN_NONE){
|
||||
DoInt(dx,dy,GetVoltage());
|
||||
lcdDisplay();
|
||||
};
|
||||
dy+=8;
|
||||
dx=DoString(0,dy,"Done.");
|
||||
};
|
||||
|
||||
void msc_menu(void){
|
||||
DoString(0,8,"MSC Enabled.");
|
||||
lcdDisplay();
|
||||
usbMSCInit();
|
||||
getInputWaitRelease();
|
||||
getInputWait();
|
||||
DoString(0,16,"MSC Disabled.");
|
||||
usbMSCOff();
|
||||
};
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#include <sysinit.h>
|
||||
|
||||
#include "basic/basic.h"
|
||||
|
||||
#include "lcd/lcd.h"
|
||||
#include "lcd/print.h"
|
||||
|
||||
#include "funk/nrf24l01p.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "funk/rftransfer.h"
|
||||
#include "funk/openbeacon.h"
|
||||
|
||||
#include "core/iap/iap.h"
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
void f_uuid(void) {
|
||||
IAP_return_t iap_return;
|
||||
iap_return = iapReadSerialNumber();
|
||||
lcdPrintIntHex(iap_return.Result[0]); lcdNl();
|
||||
lcdPrintIntHex(iap_return.Result[1]); lcdNl();
|
||||
lcdPrintIntHex(iap_return.Result[2]); lcdNl();
|
||||
lcdPrintIntHex(iap_return.Result[3]); lcdNl();
|
||||
}
|
|
@ -6,52 +6,201 @@
|
|||
#include "basic/basic.h"
|
||||
#include "lcd/render.h"
|
||||
#include "lcd/allfonts.h"
|
||||
#include "basic/config.h"
|
||||
#include "basic/byteorder.h"
|
||||
#include "lcd/lcd.h"
|
||||
#include "lcd/print.h"
|
||||
#include "funk/nrf24l01p.h"
|
||||
#include "usbcdc/usb.h"
|
||||
#include "usbcdc/usbcore.h"
|
||||
#include "usbcdc/usbhw.h"
|
||||
#include "usbcdc/cdcuser.h"
|
||||
#include "usbcdc/cdc_buf.h"
|
||||
#include "usbcdc/util.h"
|
||||
#include "core/ssp/ssp.h"
|
||||
|
||||
#include "ecc.c"
|
||||
void backlightInit(void);
|
||||
#if CFG_USBMSC
|
||||
#error "MSC is defined"
|
||||
#endif
|
||||
|
||||
#if !CFG_USBCDC
|
||||
#error "CDC is not defined"
|
||||
#endif
|
||||
|
||||
#define CHANNEL 81
|
||||
#define MAC "\x1\x2\x3\x2\x1"
|
||||
|
||||
#define SERIAL_NONE 0
|
||||
#define SERIAL_ESCAPE '\\'
|
||||
#define SERIAL_STOP '0'
|
||||
#define SERIAL_PACKETLEN 128
|
||||
|
||||
struct NRF_CFG config = {
|
||||
.channel= CHANNEL,
|
||||
.txmac= MAC,
|
||||
.nrmacs=1,
|
||||
.mac0= MAC,
|
||||
.maclen ="\x20",
|
||||
};
|
||||
|
||||
uint8_t serialmsg_message[SERIAL_PACKETLEN];
|
||||
uint8_t serialmsg_len = 0;
|
||||
|
||||
void serialmsg_init(void);
|
||||
uint8_t serialmsg_put(uint8_t data);
|
||||
char snd_pkt_no_crc(int size, uint8_t * pkt);
|
||||
void dump_encoded(int len, uint8_t *data);
|
||||
|
||||
#define INPUTLEN 99
|
||||
/**************************************************************************/
|
||||
|
||||
void main_schneider(void) {
|
||||
//int yctr=8;
|
||||
int dx=0;
|
||||
char key;
|
||||
int ctr = 1;
|
||||
backlightInit();
|
||||
font_direction = FONT_DIR_LTR; // LeftToRight is the default
|
||||
//yctr=18;
|
||||
bitstr_parse(poly, "800000000000000000000000000000000000000c9");
|
||||
bitstr_parse(coeff_b, "20a601907b8c953ca1481eb10512f78744a3205fd");
|
||||
bitstr_parse(base_x, "3f0eba16286a2d57ea0991168d4994637e8343e36");
|
||||
bitstr_parse(base_y, "0d51fbc6c71a0094fa2cdd545b11c5c0c797324f1");
|
||||
bitstr_parse(base_order, "40000000000000000000292fe77e70c12a4234c33");
|
||||
void main_schneider(void)
|
||||
{
|
||||
GLOBAL(daytrig)=10;
|
||||
GLOBAL(lcdbacklight)=10;
|
||||
char input[64];
|
||||
|
||||
ECIES_generate_key_pair(); // generate a public/private key pair
|
||||
while (1) {
|
||||
key= getInput();
|
||||
font=&Font_7x8;
|
||||
usbCDCInit();
|
||||
delayms(500);
|
||||
nrf_init();
|
||||
nrf_config_set(&config);
|
||||
|
||||
// Easy flashing
|
||||
if(key==BTN_LEFT){
|
||||
DoString(0,8,"Enter ISP!");
|
||||
lcdDisplay();
|
||||
ISPandReset();
|
||||
nrf_rcv_pkt_start();
|
||||
while(1){
|
||||
int l, i, status;
|
||||
CDC_OutBufAvailChar (&l);
|
||||
if(l>0){
|
||||
CDC_RdOutBuf (input, &l);
|
||||
for(i=0; i<l; i++){
|
||||
uint8_t cmd = serialmsg_put(input[i]);
|
||||
if( cmd != SERIAL_NONE ){
|
||||
switch( cmd ){
|
||||
case '1':
|
||||
// can we loose packets here?
|
||||
nrf_rcv_pkt_end();
|
||||
status=snd_pkt_no_crc(serialmsg_len, serialmsg_message);
|
||||
//status=nrf_snd_pkt_crc(serialmsg_len, serialmsg_message);
|
||||
nrf_rcv_pkt_start();
|
||||
break;
|
||||
case '3':
|
||||
memcpy(config.txmac, serialmsg_message, 5);
|
||||
nrf_config_set(&config);
|
||||
break;
|
||||
case '4':
|
||||
memcpy(config.mac0, serialmsg_message, 5);
|
||||
nrf_config_set(&config);
|
||||
break;
|
||||
case '5':
|
||||
config.channel=serialmsg_message[0];
|
||||
nrf_config_set(&config);
|
||||
break;
|
||||
case '6':
|
||||
config.maclen[0]=serialmsg_message[0];
|
||||
nrf_config_set(&config);
|
||||
break;
|
||||
};
|
||||
|
||||
// Display nickname
|
||||
//font = &Font_Ubuntu36pt;
|
||||
dx=DoString(0,0,"Test");
|
||||
dx=DoInt(dx,0,ctr++);
|
||||
lcdDisplay();
|
||||
encryption_decryption_demo("This is encrypted",
|
||||
"1c56d302cf642a8e1ba4b48cc4fbe2845ee32dce7",
|
||||
"45f46eb303edf2e62f74bd68368d979e265ee3c03",
|
||||
"0e10e787036941e6c78daf8a0e8e1dbfac68e26d2");
|
||||
puts("\\2\\0");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
int len;
|
||||
uint8_t buf[32];
|
||||
len=nrf_rcv_pkt_poll(sizeof(buf),buf);
|
||||
if( len > 0 ){
|
||||
puts("\\1");
|
||||
dump_encoded(len, buf);
|
||||
puts("\\0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dump_encoded(int len, uint8_t *data)
|
||||
{
|
||||
int i=0,j=0;
|
||||
uint8_t buf[SERIAL_PACKETLEN*2];
|
||||
for(i=0; i<len; i++){
|
||||
if( data[i] == SERIAL_ESCAPE ){
|
||||
buf[j++] = SERIAL_ESCAPE;
|
||||
}
|
||||
buf[j++] = data[i];
|
||||
}
|
||||
CDC_WrInBuf((char*)buf, &j);
|
||||
}
|
||||
|
||||
void tick_schneider(void){
|
||||
return;
|
||||
};
|
||||
|
||||
inline void xmit_spi(uint8_t dat) {
|
||||
sspSend(0, (uint8_t*) &dat, 1);
|
||||
}
|
||||
|
||||
inline void rcv_spi(uint8_t *dat) {
|
||||
sspReceive(0, dat, 1);
|
||||
}
|
||||
|
||||
#define CS_LOW() gpioSetValue(RB_SPI_NRF_CS, 0)
|
||||
#define CS_HIGH() gpioSetValue(RB_SPI_NRF_CS, 1)
|
||||
#define CE_LOW() gpioSetValue(RB_NRF_CE, 0)
|
||||
#define CE_HIGH() gpioSetValue(RB_NRF_CE, 1)
|
||||
|
||||
char snd_pkt_no_crc(int size, uint8_t * pkt)
|
||||
{
|
||||
if(size > MAX_PKT)
|
||||
size=MAX_PKT;
|
||||
|
||||
nrf_write_reg(R_CONFIG,
|
||||
R_CONFIG_PWR_UP| // Power on
|
||||
R_CONFIG_EN_CRC // CRC on, single byte
|
||||
);
|
||||
|
||||
CS_LOW();
|
||||
xmit_spi(C_W_TX_PAYLOAD);
|
||||
sspSend(0,pkt,size);
|
||||
CS_HIGH();
|
||||
|
||||
CE_HIGH();
|
||||
delayms(1); // Send it. (only needs >10ys, i think)
|
||||
CE_LOW();
|
||||
|
||||
return nrf_cmd_status(C_NOP);
|
||||
};
|
||||
|
||||
void serialmsg_init(void)
|
||||
{
|
||||
serialmsg_len = 0;
|
||||
}
|
||||
|
||||
//returns the message type or SERIAL_NONE
|
||||
uint8_t serialmsg_put(uint8_t data)
|
||||
{
|
||||
static uint8_t escaped = 0;
|
||||
static uint8_t msgtype = SERIAL_NONE;
|
||||
|
||||
if( data == SERIAL_ESCAPE && escaped == 0 ){
|
||||
//a control code will follow
|
||||
escaped = 1;
|
||||
return SERIAL_NONE;
|
||||
}else if( escaped ){
|
||||
escaped = 0;
|
||||
if( data != SERIAL_ESCAPE ){
|
||||
if( data == SERIAL_STOP ){
|
||||
uint8_t tmp = msgtype;
|
||||
msgtype = SERIAL_NONE;
|
||||
return tmp;
|
||||
}
|
||||
msgtype = data;
|
||||
serialmsg_len=0;
|
||||
return SERIAL_NONE;
|
||||
}
|
||||
}
|
||||
serialmsg_message[serialmsg_len++] = data;
|
||||
|
||||
//prevent a buffer overflow
|
||||
if( serialmsg_len == SERIAL_PACKETLEN )
|
||||
serialmsg_len--;
|
||||
|
||||
return SERIAL_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,312 @@
|
|||
#include <sysinit.h>
|
||||
|
||||
#include "basic/basic.h"
|
||||
#include "basic/byteorder.h"
|
||||
#include "lcd/lcd.h"
|
||||
#include "lcd/print.h"
|
||||
#include "funk/nrf24l01p.h"
|
||||
#include <string.h>
|
||||
#include "basic/random.h"
|
||||
#include "basic/config.h"
|
||||
#include "usetable.h"
|
||||
|
||||
|
||||
//channel and mac used to transmit game announcements
|
||||
#define ANNOUNCE_CHANNEL 81
|
||||
#define ANNOUNCE_MAC "REM0T"
|
||||
|
||||
struct NRF_CFG config;
|
||||
|
||||
struct packet{
|
||||
uint8_t len;
|
||||
uint8_t protocol;
|
||||
uint8_t command;
|
||||
uint32_t id;
|
||||
uint32_t ctr;
|
||||
|
||||
//union with 19 bytes data
|
||||
union content{
|
||||
struct button{
|
||||
uint8_t button;
|
||||
uint8_t reserved[18];
|
||||
}__attribute__((packed)) button;
|
||||
struct text{
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
uint8_t flags;
|
||||
uint8_t text[16];
|
||||
}__attribute__((packed)) text;
|
||||
struct nick{
|
||||
uint8_t flags;
|
||||
uint8_t nick[18];
|
||||
}__attribute__((packed)) nick;
|
||||
struct nickrequest{
|
||||
uint8_t reserved[19];
|
||||
}__attribute__((packed)) nickrequest;
|
||||
struct ack{
|
||||
uint8_t flags;
|
||||
uint8_t reserved[18];
|
||||
}__attribute__((packed)) ack;
|
||||
struct announce{
|
||||
uint8_t gameMac[5];
|
||||
uint8_t gameChannel;
|
||||
//uint8_t playerMac[5]; playerMac = gameMac+1;
|
||||
uint32_t gameId;
|
||||
uint8_t gameFlags;
|
||||
uint8_t gameTitle[8];
|
||||
}__attribute__((packed)) announce;
|
||||
struct join{
|
||||
uint32_t gameId;
|
||||
uint8_t reserved[15];
|
||||
}__attribute__((packed)) join;
|
||||
}c;
|
||||
uint16_t crc;
|
||||
}__attribute__((packed));
|
||||
|
||||
#define FLAGS_MASS_GAME 1
|
||||
#define FLAGS_ACK_JOINOK 1
|
||||
#define MASS_ID 1
|
||||
|
||||
/**************************************************************************/
|
||||
/* l0dable for playing games which are announced by other r0kets with the l0dabel r_game */
|
||||
/* Values of buf[3]:
|
||||
* B: packet sent by player, contain information which button is pressed
|
||||
* T: packet sent by game, contain text for display
|
||||
* N: packet sent by game, requesting nick
|
||||
* n: packet sent player, containing nick
|
||||
* A: packet sent by game, announcing game
|
||||
* J: packet sent by player, requesting to join game
|
||||
* a: ack, packet with $ctr was received
|
||||
*/
|
||||
|
||||
|
||||
uint32_t ctr;
|
||||
uint32_t id;
|
||||
uint32_t gameId;
|
||||
|
||||
void sendButton(uint8_t button);
|
||||
void sendJoin(uint32_t game);
|
||||
void processPacket(struct packet *p);
|
||||
void processAnnounce(struct announce *a);
|
||||
|
||||
uint8_t selectGame();
|
||||
void playGame();
|
||||
|
||||
struct announce games[7];
|
||||
uint8_t gamecount;
|
||||
|
||||
void ram(void)
|
||||
{
|
||||
int priv = GLOBAL(privacy);
|
||||
GLOBAL(privacy) = 3;
|
||||
config.nrmacs=1;
|
||||
config.maclen[0] = 32;
|
||||
config.channel = ANNOUNCE_CHANNEL;
|
||||
memcpy(config.mac0, ANNOUNCE_MAC, 5);
|
||||
nrf_config_set(&config);
|
||||
|
||||
id = getRandom();
|
||||
ctr = 1;
|
||||
|
||||
while( selectGame() ){
|
||||
playGame();
|
||||
}
|
||||
GLOBAL(privacy) = priv;
|
||||
};
|
||||
|
||||
void playGame(void)
|
||||
{
|
||||
int len;
|
||||
struct packet p;
|
||||
|
||||
while(1){
|
||||
uint8_t button = getInputRaw();
|
||||
sendButton(button);
|
||||
|
||||
while(1){
|
||||
len = nrf_rcv_pkt_time(32,sizeof(p),(uint8_t*)&p);
|
||||
if(len==sizeof(p)){
|
||||
processPacket(&p);
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
delayms(20);
|
||||
};
|
||||
}
|
||||
|
||||
void showGames(uint8_t selected)
|
||||
{
|
||||
int i;
|
||||
lcdClear();
|
||||
lcdPrintln("Games:");
|
||||
if( gamecount ){
|
||||
for(i=0;i<gamecount;i++){
|
||||
if( i==selected )
|
||||
lcdPrint("*");
|
||||
else
|
||||
lcdPrint(" ");
|
||||
char buf[9];
|
||||
memcpy(buf, games[i].gameTitle, 8);
|
||||
buf[8] = 0;
|
||||
lcdPrintln(buf);
|
||||
}
|
||||
}else{
|
||||
lcdPrint("*No Games");
|
||||
}
|
||||
lcdRefresh();
|
||||
}
|
||||
|
||||
uint8_t joinGame()
|
||||
{
|
||||
int i;
|
||||
struct packet p;
|
||||
p.len=sizeof(p);
|
||||
p.protocol='G';
|
||||
p.command='J';
|
||||
p.id= id;
|
||||
p.ctr= ++ctr;
|
||||
p.c.join.gameId=gameId;
|
||||
lcdClear();
|
||||
lcdPrintln("Joining game");
|
||||
lcdRefresh();
|
||||
|
||||
for(i=0; i<10; i++){
|
||||
nrf_snd_pkt_crc(sizeof(p),(uint8_t*)&p);
|
||||
|
||||
int len = nrf_rcv_pkt_time(30,sizeof(p),(uint8_t*)&p);
|
||||
if( len==sizeof(p) ){
|
||||
if( (p.len==32) && (p.protocol=='G') && p.command=='a' ){ //check sanity, protocol
|
||||
if( p.id == id && p.ctr == ctr ){
|
||||
if( p.c.ack.flags & FLAGS_ACK_JOINOK ){
|
||||
lcdPrintln("Join OK");
|
||||
lcdRefresh();
|
||||
return 1;
|
||||
}else{
|
||||
lcdPrintln("Join rejected");
|
||||
lcdRefresh();
|
||||
getInputWait();
|
||||
getInputWaitRelease();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delayms(70);
|
||||
}
|
||||
lcdPrintln("timeout :(");
|
||||
lcdRefresh();
|
||||
getInputWait();
|
||||
getInputWaitRelease();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t selectGame()
|
||||
{
|
||||
int len, i, selected;
|
||||
struct packet p;
|
||||
int a = 0;
|
||||
config.channel = ANNOUNCE_CHANNEL;
|
||||
memcpy(config.mac0, ANNOUNCE_MAC, 5);
|
||||
nrf_config_set(&config);
|
||||
|
||||
gamecount = 0;
|
||||
for(i=0;i<60;i++){
|
||||
len= nrf_rcv_pkt_time(30, sizeof(p), (uint8_t*)&p);
|
||||
if (len==sizeof(p)){
|
||||
if( a ) a = 0; else a = 1;
|
||||
gpioSetValue (RB_LED2, a);
|
||||
processPacket(&p);
|
||||
}
|
||||
}
|
||||
selected = 0;
|
||||
while(1){
|
||||
showGames(selected);
|
||||
int key=getInputWait();
|
||||
getInputWaitRelease();
|
||||
switch(key){
|
||||
case BTN_DOWN:
|
||||
if( selected < gamecount-1 ){
|
||||
selected++;
|
||||
}
|
||||
break;
|
||||
case BTN_UP:
|
||||
if( selected > 0 ){
|
||||
selected--;
|
||||
}
|
||||
break;
|
||||
case BTN_LEFT:
|
||||
return 0;
|
||||
case BTN_ENTER:
|
||||
case BTN_RIGHT:
|
||||
if( gamecount == 0 )
|
||||
return 0;
|
||||
gameId = games[selected].gameId;
|
||||
memcpy(config.txmac, games[selected].gameMac, 5);
|
||||
memcpy(config.mac0, games[selected].gameMac, 5);
|
||||
config.mac0[4]++;
|
||||
config.channel = games[selected].gameChannel;
|
||||
nrf_config_set(&config);
|
||||
if( games[selected].gameFlags & FLAGS_MASS_GAME )
|
||||
return 1;
|
||||
else
|
||||
return joinGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void processNickRequest( struct nickrequest *nq)
|
||||
{
|
||||
struct packet p;
|
||||
p.len=sizeof(p);
|
||||
p.protocol='G'; // Proto
|
||||
p.command='n';
|
||||
p.id= id;
|
||||
p.ctr= ++ctr;
|
||||
p.c.nick.flags = 0;
|
||||
uint8_t *nick = GLOBAL(nickname);
|
||||
strcpy(p.c.nick.nick, nick);
|
||||
nrf_snd_pkt_crc(sizeof(p),(uint8_t*)&p);
|
||||
}
|
||||
|
||||
void processPacket(struct packet *p)
|
||||
{
|
||||
if ((p->len==32) && (p->protocol=='G') && (p->id == id || p->id == 0) ){ //check sanity, protocol, id
|
||||
if (p->command=='T'){
|
||||
//processText(&(p->c.text));
|
||||
}
|
||||
else if (p->command=='N'){
|
||||
processNickRequest(&(p->c.nickrequest));
|
||||
}
|
||||
else if (p->command=='A'){
|
||||
processAnnounce(&(p->c.announce));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void processAnnounce(struct announce *a)
|
||||
{
|
||||
if( gamecount < sizeof(games)/sizeof(games[0]) ){
|
||||
games[gamecount] = *a;
|
||||
gamecount++;
|
||||
}
|
||||
}
|
||||
|
||||
//increment ctr and send button state, id and ctr
|
||||
void sendButton(uint8_t button)
|
||||
{
|
||||
struct packet p;
|
||||
p.len=sizeof(p);
|
||||
p.protocol='G'; // Proto
|
||||
p.command='B';
|
||||
p.id= id;
|
||||
p.ctr= ++ctr;
|
||||
p.c.button.button=button;
|
||||
|
||||
//lcdClear();
|
||||
//lcdPrint("Key:"); lcdPrintInt(buf[2]); lcdNl();
|
||||
|
||||
nrf_snd_pkt_crc(sizeof(p),(uint8_t*)&p);
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
*.elf
|
||||
*.bin
|
||||
*.h
|
||||
loadable.ld
|
|
@ -1,12 +0,0 @@
|
|||
# Make doesn't allow dependencies on parent directory, so we need to
|
||||
# run make from one level up:
|
||||
|
||||
MAKEFILE=loadable/Makefile.sub
|
||||
MAKE+=--no-print-directory
|
||||
|
||||
all:
|
||||
@cd .. && $(MAKE) -f $(MAKEFILE)
|
||||
|
||||
clean:
|
||||
@cd .. && $(MAKE) -f $(MAKEFILE) clean
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
DIR?= loadable
|
||||
|
||||
##########################################################################
|
||||
# User configuration and firmware specific object files
|
||||
##########################################################################
|
||||
SRCS = $(wildcard $(DIR)/*.c)
|
||||
OBJS = $(foreach mod,$(SRCS),$(subst .c,.o,$(mod)))
|
||||
ELFS = $(foreach mod,$(SRCS),$(subst .c,.elf,$(mod)))
|
||||
BINS = $(foreach mod,$(SRCS),$(subst .c,.bin,$(mod)))
|
||||
HDRS = $(foreach mod,$(SRCS),$(subst .c,.h,$(mod)))
|
||||
|
||||
##########################################################################
|
||||
# GNU GCC compiler flags
|
||||
##########################################################################
|
||||
ROOT_PATH?= .
|
||||
|
||||
INCLUDE_PATHS = -I$(ROOT_PATH) -I$(ROOT_PATH)/core
|
||||
|
||||
include $(ROOT_PATH)/Makefile.inc
|
||||
|
||||
##########################################################################
|
||||
# Compiler settings, parameters and flags
|
||||
##########################################################################
|
||||
FIRMWARE=$(ROOT_PATH)/$(OUTFILE).elf
|
||||
LDSRCFILE=$(DIR)/ram.ld
|
||||
LDFILE=$(DIR)/loadable.ld
|
||||
CFLAGS+=-mlong-calls -fno-toplevel-reorder
|
||||
LDFLAGS+= -R $(FIRMWARE)
|
||||
|
||||
all: $(OBJS) $(ELFS) $(BINS) $(HDRS)
|
||||
|
||||
$(LDFILE):
|
||||
-@echo "MEMORY" > $(LDFILE)
|
||||
-@echo "{" >> $(LDFILE)
|
||||
-@echo " sram(rwx): ORIGIN = 0x10002000 - $(RAMCODE), LENGTH = $(RAMCODE)" >> $(LDFILE)
|
||||
-@echo "}" >> $(LDFILE)
|
||||
-@echo "INCLUDE $(LDSRCFILE)" >> $(LDFILE)
|
||||
|
||||
%.o : %.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
%.elf: %.o $(FIRMWARE) $(LDFILE)
|
||||
$(LD) $(LDFLAGS) -T $(LDFILE) -o $@ $<
|
||||
$(SIZE) $@
|
||||
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) $(OCFLAGS) -O binary $< $@
|
||||
|
||||
%.h: %.bin $(DIR)/bin2h.pl
|
||||
$(DIR)/bin2h.pl $<
|
||||
|
||||
clean:
|
||||
cd $(DIR) && rm -f *.o *.elf *.bin
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
.PHONY: $(LDFILE)
|
|
@ -1,41 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# vim:set ts=4 sw=4:
|
||||
|
||||
use strict;
|
||||
|
||||
sub dwim{
|
||||
local $/=undef;
|
||||
my $file=shift;
|
||||
|
||||
open(IN,"<:bytes",$file) || die "Can't open $file: $!";
|
||||
my @bytes=unpack("C*",<IN>);
|
||||
close(IN);
|
||||
|
||||
$file=~s/\.[^.]+$//;
|
||||
|
||||
open(OUT,">","${file}.h") || die "Can't write ${file}.h: $!";
|
||||
|
||||
$file=~s!.*/!!;
|
||||
|
||||
print OUT "const uint16_t loadable_${file}_size = ", scalar @bytes, ";\n";
|
||||
print OUT "const uint8_t loadable_${file}[] = {\n";
|
||||
|
||||
my $ctr=0;
|
||||
for(@bytes){
|
||||
print OUT "\t" if($ctr==0);
|
||||
printf OUT "0x%02x, ",$_;
|
||||
if(++$ctr==8){
|
||||
print OUT "\n";
|
||||
$ctr=0;
|
||||
};
|
||||
};
|
||||
print OUT "\n" if($ctr!=0);
|
||||
|
||||
print OUT "};\n";
|
||||
close(OUT);
|
||||
};
|
||||
|
||||
for(@ARGV){
|
||||
dwim($_);
|
||||
};
|
|
@ -1,10 +0,0 @@
|
|||
#include <sysinit.h>
|
||||
|
||||
#include "basic/basic.h"
|
||||
|
||||
void ram(void){
|
||||
for (int x=0;x<20;x++){
|
||||
gpioSetValue (RB_LED1, x%2);
|
||||
delayms(50);
|
||||
};
|
||||
};
|
|
@ -1,190 +0,0 @@
|
|||
#include <sysinit.h>
|
||||
|
||||
#include "basic/basic.h"
|
||||
|
||||
#include "lcd/render.h"
|
||||
#include "lcd/display.h"
|
||||
#include "lcd/allfonts.h"
|
||||
|
||||
#define FIXSIZE 25
|
||||
#define mul(a,b) ((((long long)a)*(b))>>FIXSIZE)
|
||||
#define fixpt(a) ((long)(((a)*(1<<FIXSIZE))))
|
||||
#define integer(a) (((a)+(1<<(FIXSIZE-1)))>>FIXSIZE)
|
||||
|
||||
#define ZOOM_RATIO 0.90
|
||||
#define ITERATION_MAX 150
|
||||
|
||||
void mandelInit();
|
||||
void mandelMove();
|
||||
void mandelUpdate();
|
||||
|
||||
void ram(void) {
|
||||
int key;
|
||||
mandelInit();
|
||||
while (1) {
|
||||
lcdDisplay();
|
||||
mandelMove();
|
||||
mandelUpdate();
|
||||
|
||||
// Exit on enter+direction
|
||||
key=getInputRaw();
|
||||
if(key&BTN_ENTER && key>BTN_ENTER)
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
struct mb {
|
||||
long rmin, rmax, imin, imax;
|
||||
bool dirty, dup, ddown, dleft, dright, clickmark;
|
||||
int count, limitZIn, limitZOut;
|
||||
} mandel;
|
||||
|
||||
void mandelInit() {
|
||||
//mandel.rmin = -2.2*0.9;
|
||||
//mandel.rmax = 1.0*0.9;
|
||||
//mandel.imin = -2.0*0.9;
|
||||
//mandel.imax = 2.0*0.9;
|
||||
mandel.rmin = fixpt(-2);
|
||||
mandel.rmax = fixpt(1);
|
||||
mandel.imin = fixpt(-2);
|
||||
mandel.imax = fixpt(2);
|
||||
mandel.count = 0;
|
||||
mandel.limitZIn = 40;
|
||||
mandel.limitZOut = 30;
|
||||
|
||||
mandel.dirty = true;
|
||||
mandel.dup = false;
|
||||
mandel.ddown = false;
|
||||
mandel.dleft = false;
|
||||
mandel.dright = false;
|
||||
mandel.clickmark = false;
|
||||
}
|
||||
|
||||
void mandelMove() {
|
||||
//long delta_r = (mandel.rmax - mandel.rmin)/10;
|
||||
//long delta_i = (mandel.imax - mandel.imin)/10;
|
||||
|
||||
long rs =(mandel.rmax-mandel.rmin)/RESY;
|
||||
long is =(mandel.imax-mandel.imin)/RESX;
|
||||
|
||||
char key = getInputRaw();
|
||||
|
||||
if (key == BTN_LEFT) {
|
||||
mandel.imax -=is;
|
||||
mandel.imin -=is;
|
||||
mandel.dleft = true;
|
||||
} else if (key == BTN_RIGHT) {
|
||||
mandel.imax += is;
|
||||
mandel.imin += is;
|
||||
mandel.dright = true;
|
||||
} else if (key == BTN_DOWN) {
|
||||
mandel.rmax += rs;
|
||||
mandel.rmin += rs;
|
||||
mandel.ddown = true;
|
||||
} else if (key == BTN_UP) {
|
||||
mandel.rmax -= rs;
|
||||
mandel.rmin -= rs;
|
||||
mandel.dup = true;
|
||||
} else if (key == BTN_ENTER) {
|
||||
if (mandel.count < mandel.limitZIn) {
|
||||
mandel.count = mandel.count + 1;
|
||||
}
|
||||
} else if (key == BTN_NONE) {
|
||||
if(mandel.count > 0 ) {
|
||||
mandel.count = mandel.count - 1;
|
||||
mandel.clickmark = true;
|
||||
}
|
||||
if (mandel.count == 0 ) {
|
||||
mandel.clickmark = false;
|
||||
}
|
||||
}
|
||||
if (mandel.count > mandel.limitZOut && mandel.clickmark && key == BTN_ENTER) {
|
||||
mandel.imin = mandel.imin - (mandel.imax-mandel.imin)/10;
|
||||
mandel.imax = mandel.imax + (mandel.imax-mandel.imin)/10;
|
||||
mandel.rmin = mandel.rmin -(mandel.rmax-mandel.rmin)/10;
|
||||
mandel.rmax = mandel.rmax +(mandel.rmax-mandel.rmin)/10;
|
||||
mandel.dirty = true;
|
||||
}
|
||||
if (mandel.count == mandel.limitZIn && key == BTN_ENTER) {
|
||||
mandel.imin = mandel.imin + (mandel.imax-mandel.imin)/10;
|
||||
mandel.imax = mandel.imax - (mandel.imax-mandel.imin)/10;
|
||||
mandel.rmin = mandel.rmin +(mandel.rmax-mandel.rmin)/10;
|
||||
mandel.rmax = mandel.rmax -(mandel.rmax-mandel.rmin)/10;
|
||||
mandel.dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void mandelPixel(int x, int y) {
|
||||
long r0,i0,rn, p,q;
|
||||
long rs,is;
|
||||
int iteration;
|
||||
|
||||
rs=(mandel.rmax-mandel.rmin)/RESY;
|
||||
is=(mandel.imax-mandel.imin)/RESX;
|
||||
//p=fixpt(mandel.rmin+y*rs);
|
||||
//q=fixpt(mandel.imin+x*is);
|
||||
p=mandel.rmin+y*rs;
|
||||
q=mandel.imin+x*is;
|
||||
|
||||
rn=0;
|
||||
r0=0;
|
||||
i0=0;
|
||||
iteration=0;
|
||||
while ((mul(rn,rn)+mul(i0,i0))<fixpt(4) && ++iteration<ITERATION_MAX) {
|
||||
rn=mul((r0+i0),(r0-i0)) +p;
|
||||
i0=mul(fixpt(2),mul(r0,i0)) +q;
|
||||
r0=rn;
|
||||
}
|
||||
if (iteration==ITERATION_MAX) iteration=1;
|
||||
bool pixel = ( iteration>1);
|
||||
lcdSetPixel(x, y, pixel);
|
||||
}
|
||||
|
||||
void mandelUpdate() {
|
||||
int xmin,xmax,ymin,ymax;
|
||||
if (mandel.dirty) {
|
||||
xmin = 0;
|
||||
xmax = RESX;
|
||||
ymin = 0;
|
||||
ymax = RESY;
|
||||
mandel.dirty = false;
|
||||
} else if (mandel.dleft) {
|
||||
lcdShift(1,0,false);
|
||||
xmin = 0;
|
||||
xmax = 1;
|
||||
ymin = 0;
|
||||
ymax = RESY;
|
||||
mandel.dleft = false;
|
||||
} else if (mandel.dright) {
|
||||
lcdShift(-1,0,false);
|
||||
xmin = RESX-1;
|
||||
xmax = RESX;
|
||||
ymin = 0;
|
||||
ymax = RESY;
|
||||
mandel.dright = false;
|
||||
} else if (mandel.dup) {
|
||||
lcdShift(0,-1,true);
|
||||
xmin=0;
|
||||
xmax=RESX;
|
||||
ymin=0;
|
||||
ymax=1;
|
||||
mandel.dup = false;
|
||||
} else if (mandel.ddown) {
|
||||
lcdShift(0,1,true);
|
||||
xmin=0;
|
||||
xmax=RESX;
|
||||
ymin=RESY-1;
|
||||
ymax=RESY;
|
||||
mandel.ddown = false;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int x = xmin; x<xmax; x++) {
|
||||
for (int y = ymin; y<ymax; y++) {
|
||||
mandelPixel(x,y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
|
||||
sram_top = ORIGIN(sram) + LENGTH(sram);
|
||||
ENTRY(boot_entry)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
} > sram
|
||||
|
||||
/*
|
||||
* More information about Special Section Indexes is available in the
|
||||
* free "ELF for the ARM Architecture" document from ARM Limited
|
||||
* http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf
|
||||
*
|
||||
*/
|
||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > sram
|
||||
__exidx_start = .;
|
||||
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > sram
|
||||
__exidx_end = .;
|
||||
|
||||
_etext = .;
|
||||
|
||||
.data : AT (__exidx_end)
|
||||
{
|
||||
_data = .;
|
||||
*(vtable)
|
||||
*(.data*)
|
||||
_edata = .;
|
||||
} > sram
|
||||
|
||||
/* zero initialized data */
|
||||
.bss :
|
||||
{
|
||||
_bss = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
_ebss = .;
|
||||
} > sram
|
||||
|
||||
end = .;
|
||||
|
||||
/* For GDB compatibility we decrease the top with 16 bytes */
|
||||
stack_entry = sram_top - 16;
|
||||
}
|
|
@ -1,338 +0,0 @@
|
|||
#include <sysinit.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "basic/basic.h"
|
||||
#include "lcd/render.h"
|
||||
#include "lcd/allfonts.h"
|
||||
#include "basic/ecc.h"
|
||||
#include "funk/nrf24l01p.h"
|
||||
#include "filesystem/ff.h"
|
||||
#include "filesystem/diskio.h"
|
||||
#include "funk/filetransfer.h"
|
||||
#include "lcd/print.h"
|
||||
|
||||
uint8_t mac[5] = {1,2,3,2,1};
|
||||
|
||||
void ram(void)
|
||||
{
|
||||
if( sendKeys() )
|
||||
return;
|
||||
|
||||
char priv[42];
|
||||
UINT readbytes;
|
||||
FIL file;
|
||||
|
||||
if( f_open(&file, "priv.key", FA_OPEN_EXISTING|FA_READ) ){
|
||||
return;
|
||||
}
|
||||
if( f_read(&file, priv, 41, &readbytes) || readbytes != 41 ){
|
||||
return;
|
||||
}
|
||||
f_close(&file);
|
||||
priv[41] = 0;
|
||||
|
||||
uint8_t done = 0;
|
||||
uint8_t key;
|
||||
uint8_t k1[16], k2[16], rx[4*NUMWORDS], ry[4*NUMWORDS];
|
||||
|
||||
while( !done ){
|
||||
lcdClear();
|
||||
lcdPrintln("Receiving file");
|
||||
lcdPrintln("Down=Abort");
|
||||
lcdRefresh();
|
||||
key = getInput();
|
||||
delayms(20);
|
||||
if( key == BTN_DOWN ){
|
||||
return -1;
|
||||
}
|
||||
if( receiveR(rx,ry) )
|
||||
continue;
|
||||
lcdPrintln("Creating key");
|
||||
lcdRefresh();
|
||||
ECIES_decryptkeygen(rx, ry, k1, k2, priv);
|
||||
if( filetransfer_receive(mac,(uint32_t*)k1) < 0 )
|
||||
continue;
|
||||
lcdPrintln("Right=OK");
|
||||
lcdPrintln("Left=Retry");
|
||||
lcdPrintln("Down=Abort");
|
||||
lcdRefresh();
|
||||
|
||||
while(1){
|
||||
key = getInput();
|
||||
delayms(20);
|
||||
if( key == BTN_LEFT ){
|
||||
break;
|
||||
}else if( key == BTN_RIGHT ){
|
||||
done = 1;
|
||||
break;
|
||||
}else if( key == BTN_DOWN ){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sendPublicKey(void)
|
||||
{
|
||||
uint8_t exp[2 + 4*NUMWORDS + 2];
|
||||
char buf[42];
|
||||
UINT readbytes;
|
||||
FIL file;
|
||||
|
||||
if( f_open(&file, "pubx.key", FA_OPEN_EXISTING|FA_READ) ){
|
||||
return;
|
||||
}
|
||||
if( f_read(&file, buf, 41, &readbytes) || readbytes != 41 ){
|
||||
return;
|
||||
}
|
||||
f_close(&file);
|
||||
buf[41] = 0;
|
||||
|
||||
exp[0] = 'P';
|
||||
bitstr_parse_export((char*)exp+2, buf);
|
||||
exp[1] = 'X';
|
||||
nrf_snd_pkt_crc(32, exp);
|
||||
delayms(10);
|
||||
|
||||
if( f_open(&file, "puby.key", FA_OPEN_EXISTING|FA_READ) ){
|
||||
return;
|
||||
}
|
||||
if( f_read(&file, buf, 41, &readbytes) || readbytes != 41 ){
|
||||
return;
|
||||
}
|
||||
f_close(&file);
|
||||
buf[41] = 0;
|
||||
|
||||
exp[1] = 'Y';
|
||||
bitstr_parse_export((char*)exp+2, buf);
|
||||
nrf_snd_pkt_crc(32, exp);
|
||||
delayms(10);
|
||||
}
|
||||
|
||||
|
||||
int receiveKey(uint8_t type, uint8_t *x, uint8_t *y)
|
||||
{
|
||||
uint8_t buf[32];
|
||||
uint8_t n;
|
||||
|
||||
n = nrf_rcv_pkt_time(1000, 32, buf);
|
||||
if( n == 32 && buf[0] == type && buf[1] == 'X' ){
|
||||
for(int i=0; i<NUMWORDS*4; i++)
|
||||
x[i] = buf[i+2];
|
||||
n = nrf_rcv_pkt_time(100, 32, buf);
|
||||
if( n == 32 && buf[0] ==type && buf[1] == 'Y' ){
|
||||
for(int i=0; i<NUMWORDS*4; i++)
|
||||
y[i] = buf[i+2];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int receiveR(uint8_t *rx, uint8_t *ry)
|
||||
{
|
||||
return receiveKey('R',rx,ry);
|
||||
}
|
||||
|
||||
void sendMac(void)
|
||||
{
|
||||
uint8_t buf[32];
|
||||
buf[0] = 'M';
|
||||
buf[1] = 'C';
|
||||
buf[2] = mac[0];
|
||||
buf[3] = mac[1];
|
||||
buf[4] = mac[2];
|
||||
buf[5] = mac[3];
|
||||
buf[6] = mac[4];
|
||||
nrf_snd_pkt_crc(32, buf);
|
||||
delayms(10);
|
||||
}
|
||||
|
||||
int sendKeys(void)
|
||||
{
|
||||
uint8_t done = 0;
|
||||
char key;
|
||||
while( !done ){
|
||||
lcdClear();
|
||||
lcdPrintln("Sending PUBKEY");lcdRefresh();
|
||||
sendPublicKey();
|
||||
sendMac();
|
||||
lcdPrintln("Done");
|
||||
lcdPrintln("Right=OK");
|
||||
lcdPrintln("Left=Retry");
|
||||
lcdPrintln("Down=Abort");
|
||||
lcdRefresh();
|
||||
|
||||
while(1){
|
||||
key = getInput();
|
||||
delayms(20);
|
||||
if( key == BTN_LEFT ){
|
||||
break;
|
||||
}else if( key == BTN_RIGHT ){
|
||||
done = 1;
|
||||
break;
|
||||
}else if( key == BTN_DOWN ){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#include <string.h>
|
||||
#include "funk/nrf24l01p.h"
|
||||
#include "funk/filetransfer.h"
|
||||
#include "funk/rftransfer.h"
|
||||
#include "basic/basic.h"
|
||||
#include "basic/xxtea.h"
|
||||
#include "filesystem/ff.h"
|
||||
#include "lcd/print.h"
|
||||
|
||||
|
||||
int filetransfer_receive(uint8_t *mac, uint32_t const k[4])
|
||||
{
|
||||
uint8_t buf[MAXSIZE+1];
|
||||
uint16_t size;
|
||||
uint8_t n;
|
||||
|
||||
UINT written = 0;
|
||||
FIL file;
|
||||
FRESULT res;
|
||||
//uint8_t macbuf[5];
|
||||
//nrf_get_rx_max(0,5,macbuf);
|
||||
|
||||
uint8_t metadata[32];
|
||||
|
||||
//nrf_set_rx_mac(0, 32, 5, mac);
|
||||
n = nrf_rcv_pkt_time_encr(3000, 32, metadata, k);
|
||||
if( n != 32 )
|
||||
return 1; //timeout
|
||||
//nrf_set_rx_mac(0, 32, 5, macbuf);
|
||||
//lcdPrintln("got meta"); lcdRefresh();
|
||||
metadata[19] = 0; //enforce termination
|
||||
size = (metadata[20] << 8) | metadata[21];
|
||||
|
||||
if( size > MAXSIZE ) {lcdPrintln("too big"); lcdRefresh(); while(1);}
|
||||
if( size > MAXSIZE ) return 1; //file to big
|
||||
//if(fileexists(metadata)) return 1; //file already exists
|
||||
|
||||
//lcdPrint("open"); lcdPrintln((const char*)metadata); lcdRefresh();
|
||||
res = f_open(&file, (const char*)metadata, FA_OPEN_ALWAYS|FA_WRITE);
|
||||
|
||||
//lcdPrintln("file opened"); lcdRefresh();
|
||||
if( res ) {lcdPrintln("res"); lcdPrint(f_get_rc_string(res)); lcdRefresh(); while(1);}
|
||||
if( res )
|
||||
return res;
|
||||
|
||||
uint16_t wordcount = (size+3)/4;
|
||||
|
||||
//nrf_set_rx_mac(0, 32, 5, mac);
|
||||
//lcdPrintln("get file"); lcdRefresh();
|
||||
int fres = rftransfer_receive(buf, wordcount*4, 1000);
|
||||
if( fres == -1 ){
|
||||
lcdPrintln("checksum wrong");
|
||||
}else if( fres == -2 ){
|
||||
lcdPrintln("timeout");
|
||||
}else{
|
||||
//lcdPrintln("got file");
|
||||
}
|
||||
lcdRefresh();
|
||||
if( fres < 0 )
|
||||
return 1;
|
||||
//nrf_set_rx_mac(0, 32, 5, macbuf);
|
||||
|
||||
xxtea_decode_words((uint32_t *)buf, wordcount, k);
|
||||
|
||||
res = f_write(&file, buf, size, &written);
|
||||
f_close(&file);
|
||||
if( res )
|
||||
return res;
|
||||
if( written != size )
|
||||
return 1; //error while writing
|
||||
lcdClear();
|
||||
lcdPrintln("Received"); lcdPrintln((const char*)metadata); lcdRefresh();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAXPACKET 32
|
||||
int16_t rftransfer_receive(uint8_t *buffer, uint16_t maxlen, uint16_t timeout)
|
||||
{
|
||||
uint8_t buf[MAXPACKET];
|
||||
uint8_t state = 0;
|
||||
uint16_t pos = 0, seq = 0, size = 0, rand = 0, crc = 0;
|
||||
int n,i;
|
||||
unsigned int currentTick = systickGetTicks();
|
||||
unsigned int startTick = currentTick;
|
||||
|
||||
while(systickGetTicks() < (startTick+timeout) ){//this fails if either overflows
|
||||
n = nrf_rcv_pkt_time(1000, MAXPACKET, buf);
|
||||
switch(state){
|
||||
case 0:
|
||||
if( n == 32 && buf[0] == 'L' ){
|
||||
size = (buf[1] << 8) | buf[2];
|
||||
rand = (buf[3] << 8) | buf[4];
|
||||
seq = 0;
|
||||
pos = 0;
|
||||
if( size <= maxlen ){
|
||||
//lcdClear();
|
||||
//lcdPrint("got l="); lcdPrintInt(size);
|
||||
//lcdPrintln(""); lcdRefresh();
|
||||
state = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if( n == 32 && buf[0] == 'D' && ((buf[3]<<8)|buf[4])==rand ){
|
||||
//lcdPrint("got d"); lcdRefresh();
|
||||
if( seq == ((buf[1]<<8)|buf[2]) ){
|
||||
//lcdPrintln(" in seq"); lcdRefresh();
|
||||
for(i=5; i<n-2 && pos<size; i++,pos++){
|
||||
buffer[pos] = buf[i];
|
||||
}
|
||||
seq++;
|
||||
}
|
||||
}
|
||||
if( pos == size ){
|
||||
//lcdPrintln("got all"); lcdRefresh();
|
||||
crc = crc16(buffer, size);
|
||||
state = 2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if( n == 32 && buf[0] == 'C' && ((buf[3]<<8)|buf[4])==rand){
|
||||
//lcdPrint("got crc"); lcdRefresh();
|
||||
if( crc == ((buf[1]<<8)|buf[2]) ){
|
||||
//lcdPrintln(" ok"); lcdRefresh();
|
||||
return size;
|
||||
}else{
|
||||
//lcdPrintln(" nok"); lcdRefresh();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
//lcdPrintln("Timeout"); lcdRefresh();
|
||||
return -2;
|
||||
}
|
||||
|
||||
int ECIES_decryptkeygen(uint8_t *rx, uint8_t *ry,
|
||||
uint8_t k1[16], uint8_t k2[16], const char *privkey)
|
||||
{
|
||||
elem_t Rx, Ry, Zx, Zy;
|
||||
exp_t d;
|
||||
bitstr_import(Rx, (char*)rx);
|
||||
bitstr_import(Ry, (char*)ry);
|
||||
if (ECIES_embedded_public_key_validation(Rx, Ry) < 0)
|
||||
return -1;
|
||||
bitstr_parse(d, privkey);
|
||||
point_copy(Zx, Zy, Rx, Ry);
|
||||
point_mult(Zx, Zy, d);
|
||||
point_double(Zx, Zy); /* cofactor h = 2 on B163 */
|
||||
if (point_is_zero(Zx, Zy))
|
||||
return -1;
|
||||
ECIES_kdf((char*)k1,(char*) k2, Zx, Rx, Ry);
|
||||
return 0;
|
||||
}
|
|
@ -1,285 +0,0 @@
|
|||
#include <sysinit.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "basic/basic.h"
|
||||
#include "lcd/render.h"
|
||||
#include "lcd/allfonts.h"
|
||||
#include "basic/ecc.h"
|
||||
#include "funk/nrf24l01p.h"
|
||||
#include "filesystem/ff.h"
|
||||
#include "filesystem/diskio.h"
|
||||
#include "funk/filetransfer.h"
|
||||
#include "lcd/print.h"
|
||||
|
||||
|
||||
|
||||
uint8_t mac[5] = {1,2,3,2,1};
|
||||
|
||||
void ram(void)
|
||||
{
|
||||
char file[13];
|
||||
selectFile(file,"TXT");
|
||||
sendFile(file);
|
||||
}
|
||||
|
||||
void sendR(uint8_t *rx, uint8_t *ry)
|
||||
{
|
||||
uint8_t exp[2 + 4*NUMWORDS + 2];
|
||||
exp[0] = 'R';
|
||||
for(int i=0; i<4*NUMWORDS; i++)
|
||||
exp[2+i] = rx[i];
|
||||
exp[1] = 'X';
|
||||
nrf_snd_pkt_crc(32, exp);
|
||||
delayms(10);
|
||||
exp[1] = 'Y';
|
||||
for(int i=0; i<4*NUMWORDS; i++)
|
||||
exp[2+i] = ry[i];
|
||||
nrf_snd_pkt_crc(32, exp);
|
||||
delayms(10);
|
||||
}
|
||||
|
||||
int receiveKey(uint8_t type, uint8_t *x, uint8_t *y)
|
||||
{
|
||||
uint8_t buf[32];
|
||||
uint8_t n;
|
||||
|
||||
n = nrf_rcv_pkt_time(1000, 32, buf);
|
||||
if( n == 32 && buf[0] == type && buf[1] == 'X' ){
|
||||
for(int i=0; i<NUMWORDS*4; i++)
|
||||
x[i] = buf[i+2];
|
||||
n = nrf_rcv_pkt_time(100, 32, buf);
|
||||
if( n == 32 && buf[0] ==type && buf[1] == 'Y' ){
|
||||
for(int i=0; i<NUMWORDS*4; i++)
|
||||
y[i] = buf[i+2];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int receivePublicKey(uint8_t *px, uint8_t *py)
|
||||
{
|
||||
return receiveKey('P',px,py);
|
||||
}
|
||||
|
||||
void sendMac(void)
|
||||
{
|
||||
uint8_t buf[32];
|
||||
buf[0] = 'M';
|
||||
buf[1] = 'C';
|
||||
buf[2] = mac[0];
|
||||
buf[3] = mac[1];
|
||||
buf[4] = mac[2];
|
||||
buf[5] = mac[3];
|
||||
buf[6] = mac[4];
|
||||
nrf_snd_pkt_crc(32, buf);
|
||||
delayms(10);
|
||||
}
|
||||
|
||||
int receiveMac(uint8_t *mac)
|
||||
{
|
||||
uint8_t buf[32];
|
||||
uint8_t n;
|
||||
|
||||
n = nrf_rcv_pkt_time(100, 32, buf);
|
||||
if( n == 32 && buf[0] == 'M' && buf[1] == 'C' ){
|
||||
for(int i=0; i<5; i++)
|
||||
mac[i] = buf[i+2];
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int receiveKeys(uint8_t *px, uint8_t *py, uint8_t *mac)
|
||||
{
|
||||
uint8_t done = 0;
|
||||
char key;
|
||||
while( !done ){
|
||||
lcdClear();
|
||||
lcdPrintln("Recv. PUBKEY");
|
||||
lcdPrintln("Down=Abort");
|
||||
lcdRefresh();
|
||||
key = getInput();
|
||||
delayms(20);
|
||||
if( key == BTN_DOWN ){
|
||||
return -1;
|
||||
}
|
||||
if( receivePublicKey(px,py) )
|
||||
continue;
|
||||
if( receiveMac(mac) )
|
||||
continue;
|
||||
lcdClear();
|
||||
lcdPrintln("Got PUBKEY"); lcdRefresh();
|
||||
lcdPrintln("Hash:");
|
||||
lcdPrintln("Right=OK");
|
||||
lcdPrintln("Left=Retry");
|
||||
lcdPrintln("Down=Abort");
|
||||
lcdRefresh();
|
||||
while(1){
|
||||
key = getInput();
|
||||
delayms(20);
|
||||
if( key == BTN_LEFT ){
|
||||
break;
|
||||
}else if( key == BTN_RIGHT ){
|
||||
done = 1;
|
||||
break;
|
||||
}else if( key == BTN_DOWN ){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void sendFile(char *filename)
|
||||
{
|
||||
uint8_t px[4*NUMWORDS];
|
||||
uint8_t py[4*NUMWORDS];
|
||||
uint8_t mac[5];
|
||||
if( receiveKeys(px, py, mac) )
|
||||
return;
|
||||
|
||||
uint8_t done = 0;
|
||||
uint8_t key;
|
||||
|
||||
uint8_t k1[16], k2[16], rx[4*NUMWORDS], ry[4*NUMWORDS];
|
||||
|
||||
lcdClear();
|
||||
lcdPrintln("Creating key"); lcdRefresh();
|
||||
ECIES_encyptkeygen(px, py, k1, k2, rx, ry);
|
||||
|
||||
while( !done ){
|
||||
lcdPrintln("Sending file");lcdRefresh();
|
||||
sendR(rx,ry);
|
||||
delayms(3000);
|
||||
filetransfer_send((uint8_t*)filename, 0, mac, (uint32_t*)k1);
|
||||
lcdPrintln("Done");
|
||||
lcdPrintln("Right=OK");
|
||||
lcdPrintln("Left=Retry");
|
||||
lcdRefresh();
|
||||
while(1){
|
||||
key = getInput();
|
||||
delayms(20);
|
||||
if( key == BTN_LEFT ){
|
||||
break;
|
||||
}else if( key == BTN_RIGHT ){
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
lcdClear();
|
||||
}
|
||||
}
|
||||
|
||||
#include <string.h>
|
||||
#include "funk/nrf24l01p.h"
|
||||
#include "funk/filetransfer.h"
|
||||
#include "funk/rftransfer.h"
|
||||
#include "basic/basic.h"
|
||||
#include "basic/xxtea.h"
|
||||
#include "filesystem/ff.h"
|
||||
#include "lcd/print.h"
|
||||
|
||||
|
||||
//TODO: use a proper MAC to sign the message
|
||||
int filetransfer_send(uint8_t *filename, uint16_t size,
|
||||
uint8_t *mac, uint32_t const k[4])
|
||||
{
|
||||
uint8_t buf[MAXSIZE];
|
||||
FIL file;
|
||||
FRESULT res;
|
||||
UINT readbytes;
|
||||
|
||||
|
||||
if( size > MAXSIZE )
|
||||
return 1; //File to big
|
||||
|
||||
res=f_open(&file, (const char*)filename, FA_OPEN_EXISTING|FA_READ);
|
||||
if( res )
|
||||
return res;
|
||||
|
||||
//res = f_read(&file, (char *)buf, size, &readbytes);
|
||||
for(uint16_t i=0; i<MAXSIZE; i++)
|
||||
buf[i] = 0;
|
||||
|
||||
res = f_read(&file, (char *)buf, MAXSIZE, &readbytes);
|
||||
size = readbytes;
|
||||
|
||||
if( res )
|
||||
return res;
|
||||
if( size != readbytes)
|
||||
return 1; //Error while reading
|
||||
|
||||
uint16_t wordcount = (size+3)/4;
|
||||
//uint8_t macbuf[5];
|
||||
|
||||
uint8_t metadata[32];
|
||||
if( strlen((char*)filename) < 20 )
|
||||
strcpy((char*)metadata, (char*)filename);
|
||||
else
|
||||
return 1; //File name too long
|
||||
metadata[20] = size >> 8;
|
||||
metadata[21] = size & 0xFF;
|
||||
|
||||
//nrf_get_tx_max(5,macbuf);
|
||||
|
||||
//nrf_set_tx_mac(5, mac);
|
||||
nrf_snd_pkt_crc_encr(32, metadata, k);
|
||||
delayms(20);
|
||||
xxtea_encode_words((uint32_t *)buf, wordcount, k);
|
||||
rftransfer_send(wordcount*4, buf);
|
||||
//nrf_set_tx_mac(5, macbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "funk/rftransfer.h"
|
||||
#include "funk/nrf24l01p.h"
|
||||
#include <basic/basic.h>
|
||||
#include <basic/random.h>
|
||||
#include <core/systick/systick.h>
|
||||
#include <lcd/print.h>
|
||||
|
||||
#define MAXPACKET 32
|
||||
void rftransfer_send(uint16_t size, uint8_t *data)
|
||||
{
|
||||
uint8_t buf[MAXPACKET];
|
||||
buf[0] = 'L';
|
||||
buf[1] = size >> 8;
|
||||
buf[2] = size & 0xFF;
|
||||
|
||||
uint16_t rand = getRandom() & 0xFFFF;
|
||||
buf[3] = rand >> 8;
|
||||
buf[4] = rand & 0xFF;
|
||||
|
||||
nrf_snd_pkt_crc(32,buf); //setup packet
|
||||
delayms(20);
|
||||
uint16_t index = 0;
|
||||
uint8_t i;
|
||||
uint16_t crc = crc16(data,size);
|
||||
|
||||
while(size){
|
||||
buf[0] = 'D';
|
||||
buf[1] = index >> 8;
|
||||
buf[2] = index & 0xFF;
|
||||
buf[3] = rand >> 8;
|
||||
buf[4] = rand & 0xFF;
|
||||
for(i=5; i<MAXPACKET-2 && size>0; i++,size--){
|
||||
buf[i] = *data++;
|
||||
}
|
||||
index++;
|
||||
nrf_snd_pkt_crc(32,buf); //data packet
|
||||
delayms(20);
|
||||
}
|
||||
|
||||
buf[0] = 'C';
|
||||
buf[1] = crc >> 8;
|
||||
buf[2] = crc & 0xFF;
|
||||
buf[3] = rand >> 8;
|
||||
buf[4] = rand & 0xFF;
|
||||
nrf_snd_pkt_crc(32,buf); //setup packet
|
||||
delayms(20);
|
||||
}
|
||||
|
|
@ -1,462 +0,0 @@
|
|||
#include <sysinit.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "basic/basic.h"
|
||||
#include "basic/random.h"
|
||||
|
||||
#include "lcd/render.h"
|
||||
#include "lcd/display.h"
|
||||
#include "lcd/allfonts.h"
|
||||
|
||||
/**************************************************************************/
|
||||
#define POS_PLAYER_Y 60
|
||||
#define POS_PLAYER_X RESX/2-3
|
||||
#define POS_UFO_Y 0
|
||||
#define ENEMY_ROWS 3
|
||||
#define ENEMY_COLUMNS 6
|
||||
#define DISABLED 255
|
||||
|
||||
#define UFO_PROB 1024
|
||||
|
||||
#define TYPE_PLAYER 1
|
||||
#define TYPE_ENEMY_A 3
|
||||
#define TYPE_ENEMY_B 2
|
||||
#define TYPE_ENEMY_C 4
|
||||
#define TYPE_UFO 5
|
||||
|
||||
#define BUNKERS 3
|
||||
#define BUNKER_WIDTH 10
|
||||
static const uint8_t BUNKER_X[] = {15, RESX/2-BUNKER_WIDTH/2,RESX-BUNKER_WIDTH-15};
|
||||
static const uint8_t ENEMY_WIDTHS[] = {8,10,12};
|
||||
|
||||
struct gamestate {
|
||||
char player;
|
||||
char ufo;
|
||||
char shot_x, shot_y;
|
||||
char shots_x[ENEMY_COLUMNS];
|
||||
char shots_y[ENEMY_COLUMNS];
|
||||
char alive;
|
||||
int16_t move;
|
||||
char direction, lastcol;
|
||||
bool killed;
|
||||
bool step;
|
||||
uint32_t score;
|
||||
uint16_t level;
|
||||
int8_t rokets;
|
||||
char enemy_x[ENEMY_ROWS][ENEMY_COLUMNS];
|
||||
char enemy_row_y[ENEMY_ROWS];
|
||||
uint8_t bunker[BUNKERS][BUNKER_WIDTH];
|
||||
} game;
|
||||
char key;
|
||||
|
||||
void init_game();
|
||||
void init_enemy();
|
||||
void check_end();
|
||||
void move_ufo();
|
||||
void move_shot();
|
||||
void move_shots();
|
||||
void move_player();
|
||||
void move_enemy();
|
||||
void draw_score();
|
||||
void draw_bunker();
|
||||
void draw_player();
|
||||
void draw_enemy();
|
||||
void draw_shots();
|
||||
void draw_sprite(char type, char x, char y);
|
||||
void draw_ufo();
|
||||
void screen_intro();
|
||||
void screen_gameover();
|
||||
void screen_level();
|
||||
bool check_bunker(char xpos, char ypos, int8_t shift);
|
||||
|
||||
void ram(void) {
|
||||
//gpioSetValue (RB_LED1, CFG_LED_OFF);
|
||||
//backlightInit();
|
||||
while(1) {
|
||||
screen_intro();
|
||||
game.rokets = 3;
|
||||
game.level = 1;
|
||||
init_game();
|
||||
screen_level();
|
||||
while (game.rokets>=0) {
|
||||
////checkISP();
|
||||
lcdFill(0);
|
||||
check_end();
|
||||
move_ufo();
|
||||
move_shot();
|
||||
move_shots();
|
||||
move_player();
|
||||
move_enemy();
|
||||
draw_score();
|
||||
draw_ufo();
|
||||
draw_bunker();
|
||||
draw_player();
|
||||
draw_enemy();
|
||||
draw_shots();
|
||||
// draw_status();
|
||||
lcdDisplay();
|
||||
delayms(12);
|
||||
}
|
||||
screen_gameover();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void screen_intro() {
|
||||
char key=0;
|
||||
while(key==0) {
|
||||
lcdFill(0);
|
||||
font = &Font_Invaders;
|
||||
DoString(28,25,"ABC");
|
||||
font = &Font_7x8;
|
||||
DoString (28,40,"SPACE");
|
||||
DoString (18,50,"INVADERS");
|
||||
//DoString (20,RESY-24, "Highscore");
|
||||
DoString (0, 0, "12345");
|
||||
DoString (0, 9, "iggy");
|
||||
lcdDisplay();
|
||||
|
||||
delayms_queue(50);
|
||||
key=getInput();
|
||||
}
|
||||
}
|
||||
|
||||
void screen_gameover() {
|
||||
char key =0;
|
||||
while(key==0) {
|
||||
lcdFill(0);
|
||||
font = &Font_7x8;
|
||||
DoString (12,32, "GAME OVER");
|
||||
DoInt (0,0, game.score);
|
||||
DoString (0,9,"HIGHSCORE!");
|
||||
lcdDisplay();
|
||||
delayms_queue(50);
|
||||
key=getInput();
|
||||
}
|
||||
}
|
||||
|
||||
void screen_level() {
|
||||
lcdFill(0);
|
||||
draw_score();
|
||||
font = &Font_7x8;
|
||||
int dx = DoString(20,32, "Level ");
|
||||
DoInt(dx,32,game.level);
|
||||
lcdDisplay();
|
||||
delayms(500);
|
||||
}
|
||||
|
||||
void init_game(void) {
|
||||
game.player = POS_PLAYER_X;
|
||||
game.shot_x = DISABLED;
|
||||
game.shot_y = 0;
|
||||
game.alive = ENEMY_ROWS*ENEMY_COLUMNS;
|
||||
game.move = 0;
|
||||
if (getRandom()%2 == 0) {
|
||||
game.direction = -1;
|
||||
game.lastcol = ENEMY_COLUMNS-1;
|
||||
} else {
|
||||
game.direction = 1;
|
||||
game.lastcol = 0;
|
||||
}
|
||||
game.killed = 0;
|
||||
game.step = false;
|
||||
game.ufo = DISABLED;
|
||||
game.score = 0;
|
||||
init_enemy();
|
||||
|
||||
for (int col=0; col<ENEMY_COLUMNS; col++){
|
||||
game.shots_x[col] = DISABLED;
|
||||
}
|
||||
|
||||
for (int b=0; b<BUNKERS; b++){
|
||||
//for (int slice=0; slice<BUNKER_WIDTH; slice++){
|
||||
// game.bunker[b][slice] = 255<<2;
|
||||
//}
|
||||
game.bunker[b][0] = 0b00111100;
|
||||
game.bunker[b][1] = 0b01111100;
|
||||
game.bunker[b][2] = 0b11111100;
|
||||
game.bunker[b][3] = 0b11100000;
|
||||
game.bunker[b][4] = 0b11100000;
|
||||
game.bunker[b][5] = 0b11100000;
|
||||
game.bunker[b][6] = 0b11100000;
|
||||
game.bunker[b][7] = 0b11111100;
|
||||
game.bunker[b][8] = 0b01111100;
|
||||
game.bunker[b][9] = 0b00111100;
|
||||
}
|
||||
}
|
||||
|
||||
void init_enemy() {
|
||||
for (int row = 0; row<ENEMY_ROWS; row++) {
|
||||
game.enemy_row_y[row] = 10 + (40/ENEMY_ROWS)*row;
|
||||
for (int col = 0; col<ENEMY_COLUMNS; col++) {
|
||||
game.enemy_x[row][col] = 5+(86/ENEMY_COLUMNS)*col+(2-row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool check_bunker(char xpos, char ypos, int8_t shift){
|
||||
for (int b=0; b<BUNKERS; b++) {
|
||||
if (xpos>BUNKER_X[BUNKERS-1-b] &&
|
||||
xpos<BUNKER_X[BUNKERS-1-b]+BUNKER_WIDTH &&
|
||||
ypos<RESY-8 &&
|
||||
ypos>RESY-16) {
|
||||
int offset = BUNKER_WIDTH - (xpos-BUNKER_X[BUNKERS-1-b]);
|
||||
if (game.bunker[b][offset]!=0) {
|
||||
if (shift>0)
|
||||
game.bunker[b][offset]&=game.bunker[b][offset]<<shift;
|
||||
else
|
||||
game.bunker[b][offset]&=game.bunker[b][offset]>>-shift;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void move_shot() {
|
||||
//No shot, do nothing
|
||||
if(game.shot_x == DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
//moving out of top, end shot
|
||||
if (game.shot_y <= 0) {
|
||||
game.shot_x = DISABLED;
|
||||
return;
|
||||
}
|
||||
|
||||
if (check_bunker(game.shot_x,game.shot_y-5,1 ))
|
||||
game.shot_x=DISABLED;
|
||||
|
||||
//check for collision with enemy, kill enemy if
|
||||
for (int row=0; row<ENEMY_ROWS; row++) {
|
||||
if (game.enemy_row_y[row]+6 >= game.shot_y && game.enemy_row_y[row]+6 < game.shot_y+7) {
|
||||
for(int col = 0; col<ENEMY_COLUMNS; col++) {
|
||||
if(game.shot_x >= game.enemy_x[row][col] && game.shot_x < game.enemy_x[row][col]+ENEMY_WIDTHS[row]) {
|
||||
game.enemy_x[row][col]=DISABLED;
|
||||
game.shot_x = DISABLED;
|
||||
game.alive--;
|
||||
game.score+=(3-row)*10;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//check for collision with ufo
|
||||
if (game.ufo != DISABLED &&
|
||||
game.shot_x>game.ufo &&
|
||||
game.shot_x<game.ufo + 16 &&
|
||||
game.shot_y<8) {
|
||||
|
||||
game.ufo = DISABLED;
|
||||
game.score += 50;
|
||||
}
|
||||
|
||||
game.shot_y -= 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void move_shots() {
|
||||
for (int col = 0; col<ENEMY_COLUMNS; col++){
|
||||
//No shot, maybe generate
|
||||
if (game.shots_x[col] == DISABLED) {
|
||||
for (int row = 0; row<ENEMY_ROWS; row++) {
|
||||
if (game.enemy_x[row][col] != DISABLED) {
|
||||
if(getRandom()%(game.alive*20/((game.level/3)+1))==0) {
|
||||
game.shots_x[col] = game.enemy_x[row][col]+5;
|
||||
game.shots_y[col] = game.enemy_row_y[row]+0;
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
//moving out of bottm, end shot
|
||||
if (game.shots_y[col] >= RESY) {
|
||||
game.shots_x[col] = DISABLED;
|
||||
return;
|
||||
}
|
||||
//check for collision with bunker
|
||||
if (check_bunker(game.shots_x[col],game.shots_y[col],-1))
|
||||
game.shots_x[col]=DISABLED;
|
||||
|
||||
//check for collision with player
|
||||
if (game.shots_y[col] >= RESY-13 &&
|
||||
game.shots_x[col] > game.player+1 &&
|
||||
game.shots_x[col] < game.player+6) {
|
||||
|
||||
game.killed = true;
|
||||
}
|
||||
|
||||
//move shots down
|
||||
game.shots_y[col] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void move_ufo() {
|
||||
if (game.ufo == DISABLED) {
|
||||
if ((getRandom()%UFO_PROB)==0) {
|
||||
game.ufo = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (game.ufo >= RESX){
|
||||
game.ufo = DISABLED;
|
||||
return;
|
||||
}
|
||||
game.ufo++;
|
||||
}
|
||||
|
||||
void move_player() {
|
||||
if(gpioGetValue(RB_BTN0)==0 && game.player > 0 ){
|
||||
game.player-=1;
|
||||
}
|
||||
|
||||
if(gpioGetValue(RB_BTN1)==0 && game.player < RESX-8){
|
||||
game.player+=1;
|
||||
}
|
||||
|
||||
if(gpioGetValue(RB_BTN4)==0 && game.shot_x == 255){
|
||||
game.shot_x = game.player+4;
|
||||
game.shot_y = POS_PLAYER_Y;
|
||||
}
|
||||
}
|
||||
|
||||
void move_enemy() {
|
||||
if(game.move > 0){
|
||||
game.move-=game.level/5+1;
|
||||
return;
|
||||
}
|
||||
|
||||
game.step = !game.step;
|
||||
for (int col = 0; col < ENEMY_COLUMNS; col++) {
|
||||
for (int row = 0; row < ENEMY_ROWS; row++) {
|
||||
char pos = game.enemy_x[row][(game.direction==1)?(ENEMY_COLUMNS-(col+1)):col];
|
||||
if (pos != DISABLED) {
|
||||
//Check collision with player
|
||||
if((game.enemy_row_y[row]+8 >= POS_PLAYER_Y && pos+8 >= game.player && pos < game.player+8) ||
|
||||
game.enemy_row_y[row]+8 >= POS_PLAYER_Y+8) {
|
||||
for(int row=0; row<ENEMY_ROWS; row++) {
|
||||
game.enemy_row_y[row] = 10 + (40/ENEMY_ROWS)*row;
|
||||
}
|
||||
game.killed = true;
|
||||
}
|
||||
check_bunker(pos,game.enemy_row_y[row]+8,-2);
|
||||
|
||||
//Are we at the beginning or end? Direction change
|
||||
if((pos <=0 && game.direction != 1) ||
|
||||
(pos >=RESX-10 && game.direction == 1)){
|
||||
game.direction = (game.direction==1)?-1:1;
|
||||
for (int r = 0; r<ENEMY_ROWS; r++) {
|
||||
game.enemy_row_y[r]+=game.level>=23?4:2;
|
||||
}
|
||||
return;
|
||||
}
|
||||
game.enemy_x[row][(game.direction==1)?(ENEMY_COLUMNS-(col+1)):col] += game.direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
game.move = game.alive*2-1;
|
||||
}
|
||||
|
||||
void draw_player() {
|
||||
draw_sprite(TYPE_PLAYER, game.player, POS_PLAYER_Y);
|
||||
}
|
||||
|
||||
void draw_ufo() {
|
||||
if (game.ufo!=DISABLED)
|
||||
draw_sprite(TYPE_UFO, game.ufo, POS_UFO_Y);
|
||||
}
|
||||
|
||||
void draw_enemy() {
|
||||
for (int row = 0; row<ENEMY_ROWS; row++) {
|
||||
for (int col = 0; col<ENEMY_COLUMNS; col++) {
|
||||
if (game.enemy_x[row][col] != DISABLED) {
|
||||
draw_sprite(TYPE_ENEMY_C-row,game.enemy_x[row][col],game.enemy_row_y[row]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_bunker() {
|
||||
for (int b=0; b<BUNKERS; b++) {
|
||||
memcpy(lcdBuffer+(RESX*1+BUNKER_X[b]),game.bunker+b,BUNKER_WIDTH);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_shots() {
|
||||
if (game.shot_x != 255) {
|
||||
for (int length=0; length<=5; length++) {
|
||||
lcdSetPixel(game.shot_x, game.shot_y+length, true);
|
||||
}
|
||||
}
|
||||
|
||||
for (int col = 0; col < ENEMY_COLUMNS; col++) {
|
||||
if (game.shots_x[col] != DISABLED) {
|
||||
for (int length=0; length<=5; length++) {
|
||||
lcdSetPixel(game.shots_x[col], game.shots_y[col]+length,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void draw_status() {
|
||||
for (int p = 0; p<game.alive; p++){
|
||||
lcdSetPixel(p+1,1,true);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_sprite(char type, char x, char y) {
|
||||
font = &Font_Invaders;
|
||||
switch(type) {
|
||||
case TYPE_PLAYER:
|
||||
DoChar(x,y-1,'P');
|
||||
break;
|
||||
case TYPE_ENEMY_A:
|
||||
DoChar(x,y-1,game.step?'a':'A');
|
||||
break;
|
||||
case TYPE_ENEMY_B:
|
||||
DoChar(x,y-1,game.step?'b':'B');
|
||||
break;
|
||||
case TYPE_ENEMY_C:
|
||||
DoChar(x,y-1,game.step?'c':'C');
|
||||
break;
|
||||
case TYPE_UFO:
|
||||
DoChar(x,y-1,'U');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_score() {
|
||||
font = &Font_7x8;
|
||||
DoInt(0,0,game.score);
|
||||
|
||||
DoInt(RESX-8,0,game.rokets);
|
||||
font = &Font_Invaders;
|
||||
DoChar(RESX-16, 0, 'P');
|
||||
}
|
||||
|
||||
|
||||
void check_end() {
|
||||
if (game.killed) {
|
||||
game.rokets--;
|
||||
delayms(500);
|
||||
game.player = POS_PLAYER_X;
|
||||
|
||||
for(int col=0; col<ENEMY_COLUMNS; col++) {
|
||||
game.shots_x[col] = DISABLED;
|
||||
}
|
||||
game.killed = false;
|
||||
}
|
||||
if (game.alive == 0) {
|
||||
delayms(500);
|
||||
game.level++;
|
||||
init_game();
|
||||
screen_level();
|
||||
}
|
||||
}
|
|
@ -37,9 +37,11 @@ SECTIONS
|
|||
{
|
||||
KEEP(*(.irq_vectors))
|
||||
KEEP(*(table))
|
||||
*(.text.main)
|
||||
. = 0x000002FC ; /* or 1FC for LPC2000 */
|
||||
/* or 1FC for LPC2000*/
|
||||
/* *(.text.main)
|
||||
. = 0x000002FC ;
|
||||
KEEP(*(crp))
|
||||
*/
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
} > flash
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#define CRP_VALUE 0x0 // ANY non-magic value disables CRP
|
||||
#endif
|
||||
|
||||
__attribute__ ((used, section("crp"))) const uint32_t the_crp=CRP_VALUE;
|
||||
//__attribute__ ((used, section("crp"))) const uint32_t the_crp=CRP_VALUE;
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
OBJS =
|
||||
OBJS += cdcuser.o
|
||||
OBJS += cdc_buf.o
|
||||
OBJS += usbcore.o
|
||||
OBJS += usbdesc.o
|
||||
OBJS += usbhw.o
|
||||
|
|
|
@ -1,161 +0,0 @@
|
|||
/*******************************************************************
|
||||
Copyright (C) 2009 FreakLabs
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
Originally written by Christopher Wang aka Akiba.
|
||||
Please post support questions to the FreakLabs forum.
|
||||
*******************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@file cdc_buf.c
|
||||
@author Christopher Wang (Freaklabs)
|
||||
Modified by: K. Townsend (microBuilder.eu)
|
||||
@date 19 May 2010
|
||||
|
||||
Original code taken from the FreakUSB Open Source USB Device Stack
|
||||
http://freaklabs.org/index.php/FreakUSB-Open-Source-USB-Device-Stack.html
|
||||
|
||||
If it works well, you can thank Akiba at Freaklabs. If it fails
|
||||
miserably, you can blame me (since parts of it it were rather
|
||||
ungraciously modified). :-)
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include "cdc_buf.h"
|
||||
|
||||
static cdc_buffer_t cdcfifo;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Gets a pointer to the fifo buffer
|
||||
*/
|
||||
/**************************************************************************/
|
||||
cdc_buffer_t *cdcGetBuffer()
|
||||
{
|
||||
return &cdcfifo;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Initialises the RX FIFO buffer
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void cdcBufferInit()
|
||||
{
|
||||
cdcfifo.len = 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Read one byte out of the RX buffer. This function will return the byte
|
||||
located at the array index of the read pointer, and then increment the
|
||||
read pointer index. If the read pointer exceeds the maximum buffer
|
||||
size, it will roll over to zero.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t cdcBufferRead()
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
data = cdcfifo.buf[cdcfifo.rd_ptr];
|
||||
cdcfifo.rd_ptr = (cdcfifo.rd_ptr + 1) % CFG_USBCDC_BUFFERSIZE;
|
||||
cdcfifo.len--;
|
||||
return data;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Reads x bytes from cdc buffer
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint32_t cdcBufferReadLen(uint8_t* buf, uint32_t len)
|
||||
{
|
||||
uint32_t counter, actual;
|
||||
counter = actual = 0;
|
||||
|
||||
while(counter != len)
|
||||
{
|
||||
// Make sure we don't exceed buffer limits
|
||||
if (cdcfifo.len > 0)
|
||||
{
|
||||
buf[counter] = cdcBufferRead();
|
||||
actual++;
|
||||
counter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return actual;
|
||||
}
|
||||
}
|
||||
|
||||
return actual;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Write one byte into the RX buffer. This function will write one
|
||||
byte into the array index specified by the write pointer and increment
|
||||
the write index. If the write index exceeds the max buffer size, then it
|
||||
will roll over to zero.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void cdcBufferWrite(uint8_t data)
|
||||
{
|
||||
cdcfifo.buf[cdcfifo.wr_ptr] = data;
|
||||
cdcfifo.wr_ptr = (cdcfifo.wr_ptr + 1) % CFG_USBCDC_BUFFERSIZE;
|
||||
cdcfifo.len++;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Clear the fifo read and write pointers and set the length to zero.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void cdcBufferClearFIFO()
|
||||
{
|
||||
cdcfifo.rd_ptr = 0;
|
||||
cdcfifo.wr_ptr = 0;
|
||||
cdcfifo.len = 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Check whether there is any data pending on the RX buffer.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t cdcBufferDataPending()
|
||||
{
|
||||
if (cdcfifo.len != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Name: cdc_buf.h
|
||||
* Purpose: usb cdc buffer handling
|
||||
* Version: V1.00
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __CDC_BUF_H__
|
||||
#define __CDC_BUF_H__
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
// Buffer used for circular fifo
|
||||
typedef struct _cdc_buffer_t
|
||||
{
|
||||
volatile uint8_t len;
|
||||
volatile uint8_t wr_ptr;
|
||||
volatile uint8_t rd_ptr;
|
||||
uint8_t buf[CFG_USBCDC_BUFFERSIZE];
|
||||
} cdc_buffer_t;
|
||||
|
||||
cdc_buffer_t * cdcGetBuffer();
|
||||
void cdcBufferInit();
|
||||
uint8_t cdcBufferRead();
|
||||
uint32_t cdcBufferReadLen(uint8_t* buf, uint32_t len);
|
||||
void cdcBufferWrite(uint8_t data);
|
||||
void cdcBufferClearFIFO();
|
||||
uint8_t cdcBufferDataPending();
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
/*----------/BulkBufOut------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: cdcuser.c
|
||||
|
@ -17,6 +17,7 @@
|
|||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "projectconfig.h"
|
||||
#include "basic/basic.h"
|
||||
|
||||
#include "usb.h"
|
||||
#include "usbhw.h"
|
||||
|
@ -24,15 +25,16 @@
|
|||
#include "usbcore.h"
|
||||
#include "cdc.h"
|
||||
#include "cdcuser.h"
|
||||
#include "cdc_buf.h"
|
||||
#include "usbreg.h"
|
||||
|
||||
// unsigned char BulkBufIn [64]; // Buffer to store USB IN packet
|
||||
|
||||
unsigned char BulkBufIn [64]; // Buffer to store USB IN packet
|
||||
unsigned char BulkBufOut [64]; // Buffer to store USB OUT packet
|
||||
unsigned char NotificationBuf [10];
|
||||
|
||||
CDC_LINE_CODING CDC_LineCoding = {CFG_USBCDC_BAUDRATE, 0, 0, 8};
|
||||
unsigned short CDC_SerialState = 0x0000;
|
||||
unsigned short CDC_DepInEmpty = 1; // Data IN EP is empty
|
||||
volatile unsigned char CDC_DepInEmpty = 1; // Data IN EP is empty
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
We need a buffer for incoming data on USB port because USB receives
|
||||
|
@ -61,6 +63,7 @@ typedef struct __CDC_BUF_T
|
|||
} CDC_BUF_T;
|
||||
|
||||
CDC_BUF_T CDC_OutBuf; // buffer for all CDC Out data
|
||||
CDC_BUF_T CDC_InBuf; // buffer for all CDC Out data
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
read data from CDC_OutBuf
|
||||
|
@ -116,6 +119,71 @@ int CDC_OutBufAvailChar (int *availChar)
|
|||
}
|
||||
/* end Buffer handling */
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
read data from CDC_InBuf
|
||||
*---------------------------------------------------------------------------*/
|
||||
int CDC_RdInBuf (char *buffer, const int *length)
|
||||
{
|
||||
int bytesToRead, bytesRead;
|
||||
|
||||
/* Read *length bytes, block if *bytes are not avaialable */
|
||||
bytesToRead = *length;
|
||||
//bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length);
|
||||
bytesRead = bytesToRead;
|
||||
|
||||
|
||||
// ... add code to check for underrun
|
||||
|
||||
while (bytesToRead--) {
|
||||
*buffer++ = CDC_BUF_RD(CDC_InBuf);
|
||||
}
|
||||
return (bytesRead);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
write data to CDC_InBuf
|
||||
*---------------------------------------------------------------------------*/
|
||||
int CDC_WrInBuf (const char *buffer, int *length)
|
||||
{
|
||||
int bytesToWrite, bytesWritten;
|
||||
|
||||
// Write *length bytes
|
||||
bytesToWrite = *length;
|
||||
bytesWritten = bytesToWrite;
|
||||
|
||||
// Just block if we can't write all at once
|
||||
// +1 to prevent an overflow of the ring buffer
|
||||
while( CDC_BUF_SIZE - CDC_BUF_COUNT(CDC_InBuf) < bytesToWrite+1 );
|
||||
|
||||
//uint8_t flush = CDC_DepInEmpty;
|
||||
|
||||
USB_DEVINTEN = 0;
|
||||
while (bytesToWrite--) {
|
||||
CDC_BUF_WR(CDC_InBuf, *buffer++); // Copy Data to buffer
|
||||
}
|
||||
//if( flush == 1 ){
|
||||
//if( CDC_DepInEmpty && CDC_BUF_COUNT(CDC_InBuf) ){
|
||||
if( CDC_DepInEmpty ){
|
||||
CDC_DepInEmpty = 0;
|
||||
CDC_BulkIn();
|
||||
}
|
||||
USB_DEVINTEN = DEV_STAT_INT | (0xFF<<1) | (USB_SOF_EVENT ? FRAME_INT : 0);
|
||||
|
||||
return (bytesWritten);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
check if character(s) are available at CDC_OutBuf
|
||||
*---------------------------------------------------------------------------*/
|
||||
int CDC_InBufAvailChar (int *availChar)
|
||||
{
|
||||
*availChar = CDC_BUF_COUNT(CDC_InBuf);
|
||||
|
||||
return (0);
|
||||
}
|
||||
/* end Buffer handling */
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CDC Initialisation
|
||||
|
@ -129,12 +197,8 @@ void CDC_Init (void)
|
|||
CDC_SerialState = CDC_GetSerialState();
|
||||
|
||||
CDC_BUF_RESET(CDC_OutBuf);
|
||||
CDC_BUF_RESET(CDC_InBuf);
|
||||
|
||||
// Initialise the CDC buffer. This is required to buffer outgoing
|
||||
// data (MCU to PC) since data can only be sent 64 bytes per frame
|
||||
// with at least 1ms between frames. To see how the buffer is used,
|
||||
// see 'puts' in systeminit.c
|
||||
cdcBufferInit();
|
||||
}
|
||||
|
||||
|
||||
|
@ -269,7 +333,6 @@ uint32_t CDC_SendBreak (unsigned short wDurationOfBreak) {
|
|||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CDC_BulkIn call on DataIn Request
|
||||
Parameters: none
|
||||
|
@ -277,25 +340,19 @@ uint32_t CDC_SendBreak (unsigned short wDurationOfBreak) {
|
|||
*---------------------------------------------------------------------------*/
|
||||
void CDC_BulkIn(void)
|
||||
{
|
||||
// int numBytesRead, numBytesAvail;
|
||||
//
|
||||
// // ToDo: Modify BulkIn to send incoming data to USB
|
||||
//
|
||||
// ser_AvailChar (&numBytesAvail);
|
||||
//
|
||||
// // ... add code to check for overwrite
|
||||
//
|
||||
// numBytesRead = ser_Read ((char *)&BulkBufIn[0], &numBytesAvail);
|
||||
//
|
||||
// // send over USB
|
||||
// if (numBytesRead > 0) {
|
||||
// USB_WriteEP (CDC_DEP_IN, &BulkBufIn[0], numBytesRead);
|
||||
// }
|
||||
// else {
|
||||
// CDC_DepInEmpty = 1;
|
||||
// }
|
||||
//
|
||||
//
|
||||
int numBytesRead, numBytesAvail;
|
||||
CDC_InBufAvailChar(&numBytesAvail);
|
||||
numBytesRead = CDC_RdInBuf((char*)&BulkBufIn[0], &numBytesAvail);
|
||||
// send over USB
|
||||
if (numBytesRead > 0) {
|
||||
//gpioSetValue (RB_LED0, 1);
|
||||
USB_WriteEP (CDC_DEP_IN, &BulkBufIn[0], numBytesRead);
|
||||
//gpioSetValue (RB_LED0, 0);
|
||||
} else {
|
||||
//USB_WriteEP (CDC_DEP_IN, "test\r\n", 6);
|
||||
CDC_DepInEmpty = 1;
|
||||
//gpioSetValue (RB_LED2, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ extern int CDC_RdOutBuf (char *buffer, const int *length);
|
|||
extern int CDC_WrOutBuf (const char *buffer, int *length);
|
||||
extern int CDC_OutBufAvailChar (int *availChar);
|
||||
|
||||
extern int CDC_WrInBuf (const char *buffer, int *length);
|
||||
|
||||
/* CDC Data In/Out Endpoint Address */
|
||||
#define CDC_DEP_IN 0x83
|
||||
|
@ -57,7 +58,7 @@ extern void CDC_Init (void);
|
|||
extern unsigned short CDC_GetSerialState (void);
|
||||
|
||||
/* flow control */
|
||||
extern unsigned short CDC_DepInEmpty; // DataEndPoint IN empty
|
||||
extern volatile unsigned char CDC_DepInEmpty; // DataEndPoint IN empty
|
||||
|
||||
#endif /* __CDCUSER_H__ */
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "usbhw.h"
|
||||
#include "usbcore.h"
|
||||
#include "usbuser.h"
|
||||
#include "basic/basic.h"
|
||||
|
||||
#include "usb/usbmsc.h"
|
||||
|
||||
|
@ -471,6 +472,10 @@ uint32_t USB_WriteEP (uint32_t EPNum, uint8_t *pData, uint32_t cnt)
|
|||
{
|
||||
uint32_t n;
|
||||
|
||||
//this seems rather brutal...
|
||||
//disable all usb related interrupts or WrCmd might block
|
||||
USB_DEVINTEN = 0;
|
||||
|
||||
USB_CTRL = ((EPNum & 0x0F) << 2) | CTRL_WR_EN;
|
||||
/* 3 clock cycles to fetch the packet length from RAM. */
|
||||
delay( 5 );
|
||||
|
@ -486,6 +491,9 @@ uint32_t USB_WriteEP (uint32_t EPNum, uint8_t *pData, uint32_t cnt)
|
|||
|
||||
WrCmdEP(EPNum, CMD_VALID_BUF);
|
||||
|
||||
//enable interrupts again
|
||||
USB_DEVINTEN = DEV_STAT_INT | (0xFF<<1) | (USB_SOF_EVENT ? FRAME_INT : 0);
|
||||
|
||||
return (cnt);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <sysinit.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "usbcdc/usb.h"
|
||||
#include "usbcdc/usbcore.h"
|
||||
|
@ -6,54 +7,20 @@
|
|||
#include "usbcdc/usbhw.h"
|
||||
#include "usbcdc/cdcuser.h"
|
||||
|
||||
#include "basic/basic.h"
|
||||
|
||||
volatile unsigned int lastTick;
|
||||
|
||||
// There must be at least 1ms between USB frames (of up to 64 bytes)
|
||||
// This buffers all data and writes it out from the buffer one frame
|
||||
// and one millisecond at a time
|
||||
int puts(const char * str){
|
||||
if(!USB_Configuration)
|
||||
return -1;
|
||||
|
||||
while(*str)
|
||||
cdcBufferWrite(*str++);
|
||||
|
||||
//XXX: This assumes systick is 1ms, which it isn't for us.
|
||||
// this makes usbserial unnecessary slow. Ah well....
|
||||
|
||||
// Check if we can flush the buffer now or if we need to wait
|
||||
unsigned int currentTick = systickGetTicks();
|
||||
if (currentTick != lastTick){
|
||||
uint8_t frame[64];
|
||||
uint32_t bytesRead = 0;
|
||||
char repeat=0;
|
||||
while (cdcBufferDataPending()){
|
||||
// Read up to 64 bytes as long as possible
|
||||
bytesRead = cdcBufferReadLen(frame, 64);
|
||||
USB_WriteEP (CDC_DEP_IN, frame, bytesRead);
|
||||
if(repeat)
|
||||
systickDelay(1);
|
||||
else
|
||||
repeat=1;
|
||||
}
|
||||
lastTick = currentTick;
|
||||
}
|
||||
int len = strlen(str);
|
||||
CDC_WrInBuf(str, &len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int puts_plus(const char * str){
|
||||
if(!USB_Configuration)
|
||||
return -1;
|
||||
|
||||
while(*str)
|
||||
cdcBufferWrite(*str++);
|
||||
return 0;
|
||||
return puts(str);
|
||||
}
|
||||
|
||||
void usbCDCInit(){
|
||||
lastTick = systickGetTicks(); // Used to control output/printf timing
|
||||
CDC_Init(); // Initialise VCOM
|
||||
USB_Init(); // USB Initialization
|
||||
USB_Connect(TRUE); // USB Connect
|
||||
|
|
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.7 KiB |
|
@ -0,0 +1,122 @@
|
|||
import pygame, pypong
|
||||
from pypong.player import BasicAIPlayer, KeyboardPlayer, MousePlayer, Rem0tePlayer
|
||||
import r0ketrem0te.game
|
||||
import time
|
||||
|
||||
class Pong:
|
||||
def __init__(self):
|
||||
self.configuration = {
|
||||
'screen_size': (686,488),
|
||||
'paddle_image': 'assets/paddle.png',
|
||||
'paddle_left_position': 84.,
|
||||
'paddle_right_position': 594.,
|
||||
'paddle_velocity': 6.,
|
||||
'paddle_bounds': (0, 488), # This sets the upper and lower paddle boundary.The original game didn't allow the paddle to touch the edge,
|
||||
'line_image': 'assets/dividing-line.png',
|
||||
'ball_image': 'assets/ball.png',
|
||||
'ball_velocity': 4.,
|
||||
'ball_velocity_bounce_multiplier': 1.105,
|
||||
'ball_velocity_max': 32.,
|
||||
'score_left_position': (141, 30),
|
||||
'score_right_position': (473, 30),
|
||||
'digit_image': 'assets/digit_%i.png',
|
||||
'sound_missed': 'assets/missed-ball.wav',
|
||||
'sound_paddle': 'assets/bounce-paddle.wav',
|
||||
'sound_wall': 'assets/bounce-wall.wav',
|
||||
'sound': True,
|
||||
}
|
||||
pygame.mixer.pre_init(22050, -16, 2, 1024)
|
||||
pygame.init()
|
||||
|
||||
self.rem0te = r0ketrem0te.game.Game('/dev/ttyACM0', "pong", 83,
|
||||
81, [ord(x) for x in 'REM0T'], 2, True)
|
||||
self.rem0te.registerPlayerCallback(self.playercallback)
|
||||
|
||||
self.player_right = Rem0tePlayer(self.rem0te)
|
||||
self.player_left = Rem0tePlayer(self.rem0te)
|
||||
|
||||
self.stop = True
|
||||
self.start = False
|
||||
self.restart()
|
||||
|
||||
def playercallback(self, action, player):
|
||||
if action == 'added':
|
||||
if self.player_left.player == None:
|
||||
self.player_left.player = player
|
||||
elif self.player_right.player == None:
|
||||
self.player_right.player = player
|
||||
if self.player_left.player and self.player_right.player:
|
||||
self.start = True
|
||||
elif action == 'removed':
|
||||
print 'got remove for', player.nick
|
||||
if self.player_left.player == player:
|
||||
print 'removing left player'
|
||||
self.player_left.player = None
|
||||
elif self.player_right.player == player:
|
||||
print 'removing right player'
|
||||
self.player_right.player = None
|
||||
if self.player_left.player == None or self.player_right.player == None:
|
||||
print 'halting game'
|
||||
self.stop = True
|
||||
|
||||
def restart(self):
|
||||
self.display_surface = pygame.display.set_mode(self.configuration['screen_size'])
|
||||
self.output_surface = self.display_surface.copy().convert_alpha()
|
||||
self.output_surface.fill((0,0,0))
|
||||
#~ debug_surface = output_surface.copy()
|
||||
#~ debug_surface.fill((0,0,0,0))
|
||||
self.debug_surface = None
|
||||
self.clock = pygame.time.Clock()
|
||||
self.input_state = {'key': None, 'mouse': None}
|
||||
|
||||
# Prepare game
|
||||
|
||||
self.game = pypong.Game(self.player_left, self.player_right, self.configuration)
|
||||
|
||||
def run(self):
|
||||
# Main game loop
|
||||
timestamp = 1
|
||||
while self.game.running:
|
||||
if self.start:
|
||||
self.restart()
|
||||
self.start = False
|
||||
self.stop = False
|
||||
|
||||
self.clock.tick(60)
|
||||
now = pygame.time.get_ticks()
|
||||
if timestamp > 0 and timestamp < now:
|
||||
timestamp = now + 5000
|
||||
print self.clock.get_fps()
|
||||
self.input_state['key'] = pygame.key.get_pressed()
|
||||
self.input_state['mouse'] = pygame.mouse.get_pos()
|
||||
if not self.stop:
|
||||
self.game.update()
|
||||
self.game.draw(self.output_surface)
|
||||
|
||||
|
||||
#~ pygame.surfarray.pixels_alpha(output_surface)[:,::2] = 12
|
||||
self.display_surface.blit(self.output_surface, (0,0))
|
||||
|
||||
font = pygame.font.Font(None, 36)
|
||||
if self.player_left.player:
|
||||
text = font.render(self.player_left.player.nick, 1, (0, 255, 0))
|
||||
textpos = text.get_rect(centerx=self.output_surface.get_width()/4)
|
||||
self.display_surface.blit(text, textpos)
|
||||
|
||||
if self.player_right.player:
|
||||
text = font.render(self.player_right.player.nick, 1, (0, 255, 0))
|
||||
textpos = text.get_rect(centerx=self.output_surface.get_width()/4*3)
|
||||
self.display_surface.blit(text, textpos)
|
||||
|
||||
if self.debug_surface:
|
||||
self.display_surface.blit(self.debug_surface, (0,0))
|
||||
pygame.display.flip()
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
self.game.running = False
|
||||
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
|
||||
self.game.running = False
|
||||
|
||||
if __name__ == '__main__':
|
||||
pong = Pong()
|
||||
pong.run()
|
|
@ -0,0 +1,150 @@
|
|||
import pygame, math, random, entity
|
||||
|
||||
def load_image(path):
|
||||
surface = pygame.image.load(path)
|
||||
surface.convert()
|
||||
pygame.surfarray.pixels3d(surface)[:,:,0:1:] = 0
|
||||
return surface
|
||||
|
||||
def line_line_intersect(x1, y1, x2, y2, x3, y3, x4, y4):
|
||||
# Taken from http://paulbourke.net/geometry/lineline2d/
|
||||
# Denominator for ua and ub are the same, so store this calculation
|
||||
d = float((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))
|
||||
# n_a and n_b are calculated as seperate values for readability
|
||||
n_a = float((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3))
|
||||
n_b = float((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3))
|
||||
# Make sure there is not a division by zero - this also indicates that
|
||||
# the lines are parallel.
|
||||
# If n_a and n_b were both equal to zero the lines would be on top of each
|
||||
# other (coincidental). This check is not done because it is not
|
||||
# necessary for this implementation (the parallel check accounts for this).
|
||||
if d == 0:
|
||||
return False
|
||||
# Calculate the intermediate fractional point that the lines potentially intersect.
|
||||
ua = n_a / d
|
||||
ub = n_b / d
|
||||
# The fractional point will be between 0 and 1 inclusive if the lines
|
||||
# intersect. If the fractional calculation is larger than 1 or smaller
|
||||
# than 0 the lines would need to be longer to intersect.
|
||||
if ua >= 0. and ua <= 1. and ub >= 0. and ub <= 1.:
|
||||
return [x1 + (ua * (x2 - x1)), y1 + (ua * (y2 - y1))]
|
||||
return False
|
||||
|
||||
class Game(object):
|
||||
def __init__(self, player_left, player_right, configuration):
|
||||
self.player_left = player_left
|
||||
self.player_right = player_right
|
||||
self.configuration = configuration
|
||||
self.background = pygame.Surface(configuration['screen_size'])
|
||||
self.sprites = pygame.sprite.OrderedUpdates()
|
||||
line = entity.Line(load_image(configuration['line_image']), self.sprites)
|
||||
line.rect.topleft = ((configuration['screen_size'][0]-line.rect.width)/2, 0)
|
||||
paddle_image = load_image(configuration['paddle_image'])
|
||||
self.paddle_left = entity.Paddle(configuration['paddle_velocity'], paddle_image, configuration['paddle_bounds'], self.sprites)
|
||||
self.paddle_right = entity.Paddle(configuration['paddle_velocity'], paddle_image, configuration['paddle_bounds'], self.sprites)
|
||||
self.paddle_left.rect.topleft = (self.configuration['paddle_left_position'], (self.configuration['screen_size'][1]-self.paddle_left.rect.height)/2)
|
||||
self.paddle_right.rect.topleft = (self.configuration['paddle_right_position'], (self.configuration['screen_size'][1]-self.paddle_left.rect.height)/2)
|
||||
digit_images = [load_image(configuration['digit_image'] % n) for n in xrange(10)]
|
||||
self.score_left = entity.Score(digit_images, self.sprites)
|
||||
self.score_left.rect.topleft = configuration['score_left_position']
|
||||
self.score_right = entity.Score(digit_images, self.sprites)
|
||||
self.score_right.rect.topleft = configuration['score_right_position']
|
||||
ball_image = load_image(configuration['ball_image'])
|
||||
self.ball = entity.Ball(self.configuration['ball_velocity'], ball_image, self.sprites)
|
||||
self.bounds = pygame.Rect(20, 0, configuration['screen_size'][0]-ball_image.get_width()-20, configuration['screen_size'][1]-ball_image.get_height())
|
||||
self.sound_missed = pygame.mixer.Sound(configuration['sound_missed'])
|
||||
self.sound_paddle = pygame.mixer.Sound(configuration['sound_paddle'])
|
||||
self.sound_wall = pygame.mixer.Sound(configuration['sound_wall'])
|
||||
self.reset_game(random.random()<0.5)
|
||||
self.running = True
|
||||
|
||||
def play_sound(self, sound):
|
||||
if self.configuration['sound']:
|
||||
sound.play()
|
||||
|
||||
def reset_game(self, serveLeft=True):
|
||||
y = self.configuration['screen_size'][1] - self.ball.rect.height
|
||||
self.ball.position_x = (self.configuration['screen_size'][0]-self.ball.rect.width)/2.0
|
||||
self.ball.position_y = y * random.random()
|
||||
self.ball.velocity = self.configuration['ball_velocity']
|
||||
a = random.random() * math.pi / 2. - math.pi / 4.
|
||||
self.ball.velocity_vec[0] = self.ball.velocity * math.cos(a)
|
||||
self.ball.velocity_vec[1] = self.ball.velocity * math.sin(a)
|
||||
if random.random() < 0.5:
|
||||
self.ball.velocity_vec[1] = -self.ball.velocity_vec[1]
|
||||
if serveLeft:
|
||||
self.ball.velocity_vec[0] *= -1
|
||||
|
||||
def update(self):
|
||||
# Store previous ball position for line-line intersect test later
|
||||
ball_position_x = self.ball.position_x
|
||||
ball_position_y = self.ball.position_y
|
||||
# Update sprites and players
|
||||
self.sprites.update()
|
||||
self.player_left.update(self.paddle_left, self)
|
||||
self.player_right.update(self.paddle_right, self)
|
||||
# Paddle collision check. Could probably just do a line-line intersect but I think I prefer having the pixel-pefect result of a rect-rect intersect test as well.
|
||||
if self.ball.rect.x < self.bounds.centerx:
|
||||
# Left side bullet-through-paper check on ball and paddle
|
||||
if self.ball.velocity_vec[0] < 0:
|
||||
intersect_point = line_line_intersect(
|
||||
self.paddle_left.rect.right, self.paddle_left.rect.top,
|
||||
self.paddle_left.rect.right, self.paddle_left.rect.bottom,
|
||||
ball_position_x-self.ball.rect.width/2, ball_position_y+self.ball.rect.height/2,
|
||||
self.ball.position_x-self.ball.rect.width/2, self.ball.position_y+self.ball.rect.height/2
|
||||
)
|
||||
if intersect_point:
|
||||
self.ball.position_y = intersect_point[1]-self.ball.rect.height/2
|
||||
if intersect_point or (self.paddle_left.rect.colliderect(self.ball.rect) and self.ball.rect.right > self.paddle_left.rect.right):
|
||||
self.ball.position_x = self.paddle_left.rect.right
|
||||
velocity = self.paddle_left.calculate_bounce(min(1,max(0,(self.ball.rect.centery - self.paddle_left.rect.y)/float(self.paddle_left.rect.height))))
|
||||
self.ball.velocity = min(self.configuration['ball_velocity_max'], self.ball.velocity * self.configuration['ball_velocity_bounce_multiplier'])
|
||||
self.ball.velocity_vec[0] = velocity[0] * self.ball.velocity
|
||||
self.ball.velocity_vec[1] = velocity[1] * self.ball.velocity
|
||||
self.player_left.hit()
|
||||
self.play_sound(self.sound_paddle)
|
||||
else:
|
||||
# Right side bullet-through-paper check on ball and paddle.
|
||||
if self.ball.velocity_vec[0] > 0:
|
||||
intersect_point = line_line_intersect(
|
||||
self.paddle_right.rect.left, self.paddle_right.rect.top,
|
||||
self.paddle_right.rect.left, self.paddle_right.rect.bottom,
|
||||
ball_position_x-self.ball.rect.width/2, ball_position_y+self.ball.rect.height/2,
|
||||
self.ball.position_x-self.ball.rect.width/2, self.ball.position_y+self.ball.rect.height/2
|
||||
)
|
||||
if intersect_point:
|
||||
self.ball.position_y = intersect_point[1]-self.ball.rect.height/2
|
||||
if intersect_point or (self.paddle_right.rect.colliderect(self.ball.rect) and self.ball.rect.x < self.paddle_right.rect.x):
|
||||
self.ball.position_x = self.paddle_right.rect.x - self.ball.rect.width
|
||||
velocity = self.paddle_right.calculate_bounce(min(1,max(0,(self.ball.rect.centery - self.paddle_right.rect.y)/float(self.paddle_right.rect.height))))
|
||||
self.ball.velocity = min(self.configuration['ball_velocity_max'], self.ball.velocity * self.configuration['ball_velocity_bounce_multiplier'])
|
||||
self.ball.velocity_vec[0] = -velocity[0] * self.ball.velocity
|
||||
self.ball.velocity_vec[1] = velocity[1] * self.ball.velocity
|
||||
self.player_right.hit()
|
||||
self.play_sound(self.sound_paddle)
|
||||
# Bounds collision check
|
||||
if self.ball.rect.y < self.bounds.top:
|
||||
self.ball.position_y = float(self.bounds.top)
|
||||
self.ball.velocity_vec[1] = -self.ball.velocity_vec[1]
|
||||
self.play_sound(self.sound_wall)
|
||||
elif self.ball.rect.y > self.bounds.bottom:
|
||||
self.ball.position_y = float(self.bounds.bottom)
|
||||
self.ball.velocity_vec[1] = -self.ball.velocity_vec[1]
|
||||
self.play_sound(self.sound_wall)
|
||||
# Check the ball is still in play
|
||||
if self.ball.rect.x < self.bounds.x:
|
||||
self.player_left.lost()
|
||||
self.player_right.won()
|
||||
self.score_right.score += 1
|
||||
self.reset_game(False)
|
||||
self.play_sound(self.sound_missed)
|
||||
if self.ball.rect.x > self.bounds.right:
|
||||
self.player_left.won()
|
||||
self.player_right.lost()
|
||||
self.score_left.score += 1
|
||||
self.reset_game(True)
|
||||
self.play_sound(self.sound_missed)
|
||||
|
||||
def draw(self, display_surface):
|
||||
self.sprites.clear(display_surface, self.background)
|
||||
return self.sprites.draw(display_surface)
|
|
@ -0,0 +1,87 @@
|
|||
import pygame, math
|
||||
from pygame.sprite import Sprite
|
||||
|
||||
class Paddle(Sprite):
|
||||
def __init__(self, velocity, image, bounds_y, *groups):
|
||||
Sprite.__init__(self, *groups)
|
||||
self.image = image
|
||||
self.rect = self.image.get_rect()
|
||||
self.direction = 0
|
||||
self.velocity = velocity
|
||||
self.bounds_y = bounds_y
|
||||
# Like original pong, we break this up into 8 segments from the edge angle (acute_angle) to pi/2 at the center
|
||||
# Changing acute_angle lets us change the extreme edge angle of the paddle.
|
||||
acute_angle = .125
|
||||
# Build the angles from acute_angle to the first 0.5 center value then append the values going from the
|
||||
# second center 0.5 value by using the values we just calculated reversed.
|
||||
angles = [acute_angle + (0.5-acute_angle)/3.0 * n for n in xrange(4)]
|
||||
angles += map(lambda x: 1 + x * -1, reversed(angles))
|
||||
# Final table is the output vector (x,y) of each angle
|
||||
self.bounce_table = [(math.cos(n*math.pi-math.pi/2.0), math.sin(n*math.pi-math.pi/2.0)) for n in angles]
|
||||
|
||||
def update(self):
|
||||
self.rect.y = max(self.bounds_y[0], min(self.bounds_y[1]-self.rect.height, self.rect.y + self.direction * self.velocity))
|
||||
|
||||
def calculate_bounce(self, delta):
|
||||
return self.bounce_table[int(round(delta * (len(self.bounce_table)-1)))]
|
||||
|
||||
class Line(Sprite):
|
||||
def __init__(self, image, *groups):
|
||||
Sprite.__init__(self, *groups)
|
||||
self.image = image
|
||||
self.rect = self.image.get_rect()
|
||||
|
||||
class Ball(Sprite):
|
||||
def __init__(self, velocity, image, *groups):
|
||||
Sprite.__init__(self, *groups)
|
||||
self.velocity = velocity
|
||||
self.image = image
|
||||
self.rect = self.image.get_rect()
|
||||
self.position_vec = [0., 0.]
|
||||
self.velocity_vec = [0., 0.]
|
||||
|
||||
def update(self):
|
||||
self.position_vec[0] += self.velocity_vec[0]
|
||||
self.position_vec[1] += self.velocity_vec[1]
|
||||
self.rect.x = self.position_vec[0]
|
||||
self.rect.y = self.position_vec[1]
|
||||
|
||||
def set_position_x(self, value):
|
||||
self.position_vec[0] = value
|
||||
self.rect.left = value
|
||||
position_x = property(lambda self: self.position_vec[0], set_position_x)
|
||||
|
||||
def set_position_y(self, value):
|
||||
self.position_vec[1] = value
|
||||
self.rect.top = value
|
||||
position_y = property(lambda self: self.position_vec[1], set_position_y)
|
||||
|
||||
class Score(Sprite):
|
||||
def __init__(self, image_list, *groups):
|
||||
Sprite.__init__(self, *groups)
|
||||
self.image_list = image_list
|
||||
self.image = None
|
||||
self.rect = pygame.Rect(0,0,0,0)
|
||||
self.score = 0
|
||||
|
||||
def get_score(self):
|
||||
return self.score_value
|
||||
|
||||
def set_score(self, value):
|
||||
self.score_value = value
|
||||
digit_spacing = 8
|
||||
digit_width = self.image_list[0].get_width()
|
||||
digit_height = self.image_list[0].get_height()
|
||||
values = map(int, reversed(str(self.score_value)))
|
||||
surface_width = len(values) * digit_width + (len(values)-1) * digit_spacing
|
||||
if not self.image or self.image.get_width() < surface_width:
|
||||
self.image = pygame.Surface((surface_width, digit_height))
|
||||
self.image.fill((0,0,0))
|
||||
self.rect.width = self.image.get_width()
|
||||
self.rect.height = self.image.get_height()
|
||||
offset = self.image.get_width()-digit_width
|
||||
for i in values:
|
||||
self.image.blit(self.image_list[i], (offset, 0))
|
||||
offset = offset - (digit_width + digit_spacing)
|
||||
|
||||
score = property(get_score, set_score)
|
|
@ -0,0 +1,118 @@
|
|||
import pygame, random
|
||||
import r0ketrem0te.game
|
||||
import r0ketrem0te.bridge
|
||||
import r0ketrem0te.packets
|
||||
import time
|
||||
import Queue
|
||||
import threading
|
||||
|
||||
class Rem0tePlayer(object):
|
||||
def __init__(self, rem0te):
|
||||
self.rem0te = rem0te
|
||||
self.rem0te.bridge.registerCallback(self.receivedPacket)
|
||||
self.state = 0
|
||||
self.player = None
|
||||
|
||||
def receivedPacket(self, packet):
|
||||
if self.player == None:
|
||||
return
|
||||
if packet.id == self.player.id:
|
||||
if isinstance(packet, r0ketrem0te.packets.Button):
|
||||
self.state = packet.button
|
||||
|
||||
def update(self, paddle, game):
|
||||
if self.state == 1:
|
||||
paddle.direction = -1
|
||||
elif self.state == 2:
|
||||
paddle.direction = 1
|
||||
else:
|
||||
paddle.direction = 0
|
||||
|
||||
def hit(self):
|
||||
pass
|
||||
|
||||
def lost(self):
|
||||
pass
|
||||
|
||||
def won(self):
|
||||
pass
|
||||
|
||||
class BasicAIPlayer(object):
|
||||
def __init__(self):
|
||||
self.bias = random.random() - 0.5
|
||||
self.hit_count = 0
|
||||
|
||||
def update(self, paddle, game):
|
||||
# Dead simple AI, waits until the ball is on its side of the screen then moves the paddle to intercept.
|
||||
# A bias is used to decide which edge of the paddle is going to be favored.
|
||||
if (paddle.rect.x < game.bounds.centerx and game.ball.rect.x < game.bounds.centerx) or (paddle.rect.x > game.bounds.centerx and game.ball.rect.x > game.bounds.centerx):
|
||||
delta = (paddle.rect.centery + self.bias * paddle.rect.height) - game.ball.rect.centery
|
||||
if abs(delta) > paddle.velocity:
|
||||
if delta > 0:
|
||||
paddle.direction = -1
|
||||
else:
|
||||
paddle.direction = 1
|
||||
else:
|
||||
paddle.direction = 0
|
||||
else:
|
||||
paddle.direction = 0
|
||||
|
||||
def hit(self):
|
||||
self.hit_count += 1
|
||||
if self.hit_count > 6:
|
||||
self.bias = random.random() - 0.5 # Recalculate our bias, this game is going on forever
|
||||
self.hit_count = 0
|
||||
|
||||
def lost(self):
|
||||
# If we lose, randomise the bias again
|
||||
self.bias = random.random() - 0.5
|
||||
|
||||
def won(self):
|
||||
pass
|
||||
|
||||
class KeyboardPlayer(object):
|
||||
def __init__(self, input_state, up_key=None, down_key=None):
|
||||
self.input_state = input_state
|
||||
self.up_key = up_key
|
||||
self.down_key = down_key
|
||||
|
||||
def update(self, paddle, game):
|
||||
if self.input_state['key'][self.up_key]:
|
||||
paddle.direction = -1
|
||||
elif self.input_state['key'][self.down_key]:
|
||||
paddle.direction = 1
|
||||
else:
|
||||
paddle.direction = 0
|
||||
|
||||
def hit(self):
|
||||
pass
|
||||
|
||||
def lost(self):
|
||||
pass
|
||||
|
||||
def won(self):
|
||||
pass
|
||||
|
||||
class MousePlayer(object):
|
||||
def __init__(self, input_state):
|
||||
self.input_state = input_state
|
||||
pygame.mouse.set_visible(False)
|
||||
|
||||
def update(self, paddle, game):
|
||||
centery = paddle.rect.centery/int(paddle.velocity)
|
||||
mousey = self.input_state['mouse'][1]/int(paddle.velocity)
|
||||
if centery > mousey:
|
||||
paddle.direction = -1
|
||||
elif centery < mousey:
|
||||
paddle.direction = 1
|
||||
else:
|
||||
paddle.direction = 0
|
||||
|
||||
def hit(self):
|
||||
pass
|
||||
|
||||
def lost(self):
|
||||
pass
|
||||
|
||||
def won(self):
|
||||
pass
|
|
@ -0,0 +1,240 @@
|
|||
import serialinterface
|
||||
import threading
|
||||
import Queue
|
||||
import crcmod
|
||||
import packets
|
||||
import traceback
|
||||
|
||||
class QueuePacket:
|
||||
def __init__(self, channel, mac, acked, packet, callback=None):
|
||||
self.channel = channel
|
||||
self.mac = mac
|
||||
self.acked = acked
|
||||
self.packet = packet
|
||||
self.priority = packet.priority
|
||||
self.retriesleft = 5
|
||||
self.timeout = 0.1
|
||||
self.timer = None
|
||||
self.timedout = False
|
||||
self.lock = threading.RLock()
|
||||
self.isdone = False
|
||||
self.callback = callback
|
||||
|
||||
def __cmp__(self, other):
|
||||
if not isinstance(other,QueuePacket):
|
||||
return 1
|
||||
if self.priority < other.priority:
|
||||
return -1
|
||||
if self.priority > other.priority:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def valid(self):
|
||||
with self.lock:
|
||||
return self.retriesleft > 0 and not self.acked
|
||||
|
||||
def sent(self, timeoutcallback):
|
||||
with self.lock:
|
||||
self.timedout = False
|
||||
if self.retriesleft > 0:
|
||||
self.retriesleft-=1
|
||||
if self.acked:
|
||||
self.timeoutcallback = timeoutcallback
|
||||
self.timer = threading.Timer(self.timeout, self.timercallback)
|
||||
self.timer.start()
|
||||
elif self.callback:
|
||||
self.callback('done')
|
||||
|
||||
def done(self):
|
||||
with self.lock:
|
||||
if self.timer != None:
|
||||
self.timer.cancel()
|
||||
self.timer = None
|
||||
self.isdone = True
|
||||
if self.callback:
|
||||
self.callback('done')
|
||||
|
||||
def timercallback(self):
|
||||
with self.lock:
|
||||
self.timedout = True
|
||||
self.timeoutcallback(self)
|
||||
if retriesleft == 0:
|
||||
self.callback('timeout')
|
||||
|
||||
class Bridge:
|
||||
def __init__(self, path2device, channel, rxmac):
|
||||
self.ser = serialinterface.SerialInterface(path2device, 115200, 0)
|
||||
self.free = threading.Lock()
|
||||
self.queueslock = threading.Lock()
|
||||
self.packets = Queue.PriorityQueue()
|
||||
self.outpackets = Queue.Queue()
|
||||
self.crc = crcmod.predefined.mkCrcFun('crc-ccitt-false')
|
||||
self.queues = {}
|
||||
self.callbacks = []
|
||||
self.ctrs = {}
|
||||
|
||||
self.reader = threading.Thread(target = self.readerThread)
|
||||
self.reader.daemon = True
|
||||
|
||||
self.writer = threading.Thread(target = self.writerThread)
|
||||
self.writer.daemon = True
|
||||
|
||||
self.writer.start()
|
||||
self.reader.start()
|
||||
|
||||
self.packetlength = None
|
||||
self.txmac = None
|
||||
self.rxmac = None
|
||||
self.channel = None
|
||||
self.gameChannel = channel
|
||||
|
||||
self.setPacketLength(0x20)
|
||||
self.setRxMAC(rxmac)
|
||||
self.setChannel(channel)
|
||||
|
||||
self.ctr = 0
|
||||
|
||||
def registerCallback(self, callback):
|
||||
if callback not in self.callbacks:
|
||||
self.callbacks.append(callback)
|
||||
|
||||
def registerQueue(self, queue):
|
||||
if queue not in self.queues:
|
||||
self.queues[queue] = None
|
||||
|
||||
def putInQueue(self, queue, qp):
|
||||
if queue in self.queues:
|
||||
queue.put(qp);
|
||||
self.checkQueues()
|
||||
|
||||
def processAck(self, ack):
|
||||
#find the corresponding packet in the queues
|
||||
found = False
|
||||
for pq in self.queues.values():
|
||||
if pq.packet.id == ack.id and pq.packet.ctr == ack.ctr:
|
||||
#notify it
|
||||
pq.done()
|
||||
found = True
|
||||
#notify the queue system
|
||||
if found:
|
||||
self.checkQueues()
|
||||
else:
|
||||
print "got an ack for an unknown packet"
|
||||
|
||||
def packetTimeout(self, qp):
|
||||
self.checkQueues()
|
||||
|
||||
def checkQueues(self):
|
||||
with self.queueslock:
|
||||
for q in self.queues:
|
||||
#check if a packet has to be resent
|
||||
#remove it from the packet slot if it has been resent to often
|
||||
qp = self.queues[q]
|
||||
if qp != None:
|
||||
if qp.valid():
|
||||
self.queues[q] = None
|
||||
elif qp.timedout:
|
||||
print "packet timed out" + qp.packet
|
||||
self.outpackets.put(qp)
|
||||
#check if a idle queue has a new packet in line
|
||||
qp = self.queues[q]
|
||||
if qp == None and not q.empty():
|
||||
qp = q.get()
|
||||
if not isinstance(qp.packet,packets.Ack):
|
||||
self.ctr+=1
|
||||
qp.packet.ctr = self.ctr
|
||||
self.queues[q] = qp
|
||||
self.outpackets.put(qp)
|
||||
|
||||
def writerThread(self):
|
||||
while True:
|
||||
try:
|
||||
#wait until we have packets to take care of
|
||||
qp = self.outpackets.get()
|
||||
#send it and notify the queuepacket
|
||||
self.setTxMAC(qp.mac)
|
||||
self.setChannel(qp.channel)
|
||||
self.sendPacket(qp.packet)
|
||||
qp.sent(self.packetTimeout)
|
||||
self.setChannel(self.gameChannel)
|
||||
except Exception as e:
|
||||
print e
|
||||
traceback.print_stack()
|
||||
|
||||
def readerThread(self):
|
||||
while True:
|
||||
try:
|
||||
(command, data) = self.ser.readMessage()
|
||||
if command == '1':
|
||||
self.newPacket(data)
|
||||
elif command == '2':
|
||||
self.free.release()
|
||||
except Exception as e:
|
||||
print e
|
||||
traceback.print_stack()
|
||||
|
||||
def newPacket(self, data):
|
||||
print "received:", list(data)
|
||||
crc = self.crc(data[:-2])
|
||||
if data[-2:] == chr(crc>>8) + chr(crc&0xFF):
|
||||
packet = packets.fromMessage(data)
|
||||
print "received:", packet
|
||||
if packet == None:
|
||||
return
|
||||
#if packet.id in self.ctrs and self.ctrs[packet.id] == packet.ctr:
|
||||
# print 'ignoring duplicate'
|
||||
# return
|
||||
if isinstance(packet,packets.Ack):
|
||||
self.ProcessAck(packet)
|
||||
else:
|
||||
for callback in self.callbacks:
|
||||
callback(packet)
|
||||
#self.packets.put(packet)
|
||||
|
||||
# def gotPacket(self):
|
||||
# return not self.packets.empty()
|
||||
|
||||
# def getPacket(self):
|
||||
# return self.packets.get()
|
||||
|
||||
def sendPacket(self, packet):
|
||||
print 'sending', packet
|
||||
data = packet.toMessage()
|
||||
crc = self.crc(data)
|
||||
data += chr(crc>>8);
|
||||
data += chr(crc&0xFF);
|
||||
self.free.acquire()
|
||||
#print 'sending packet: len:', len(data), 'data:', list(data)
|
||||
self.ser.writeMessage('1',data);
|
||||
|
||||
def setPacketLength(self, length):
|
||||
if length == self.packetlength:
|
||||
return
|
||||
self.free.acquire()
|
||||
self.ser.writeMessage('6', '%c'%length)
|
||||
self.packetLength = length
|
||||
|
||||
def setTxMAC(self, mac):
|
||||
if mac == self.txmac:
|
||||
return
|
||||
self.free.acquire()
|
||||
print "setting tx mac", mac
|
||||
self.ser.writeMessage('3', ''.join([chr(x) for x in mac]))
|
||||
self.txmac = mac
|
||||
|
||||
def setRxMAC(self, mac):
|
||||
if mac == self.rxmac:
|
||||
return
|
||||
self.free.acquire()
|
||||
print "setting rx mac", mac
|
||||
self.ser.writeMessage('4', ''.join([chr(x) for x in mac]))
|
||||
self.rxmac = mac
|
||||
|
||||
def setChannel(self, channel):
|
||||
if channel == self.channel:
|
||||
return
|
||||
self.free.acquire()
|
||||
print "setting channel", channel
|
||||
self.ser.writeMessage('5', '%c'%channel)
|
||||
self.channel = channel
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
import bridge
|
||||
import packets
|
||||
import time
|
||||
import Queue
|
||||
import random
|
||||
import threading
|
||||
|
||||
class Player():
|
||||
def __init__(self, id):
|
||||
self.id = id
|
||||
self.nick = 'anonymous'
|
||||
self.timeout = 10
|
||||
self.active = False
|
||||
|
||||
class Game:
|
||||
def __init__(self, device, gameName, gameChannel, announcechannel, announcemac, maxplayer=0, askname=False):
|
||||
self.gameName = gameName
|
||||
self.channel = gameChannel
|
||||
self.gamemac = [int(random.random()*254) for x in range(1,6)]
|
||||
self.playermac = list(self.gamemac)
|
||||
self.playermac[4]+=1
|
||||
self.gameid = int(random.random()*(2**31))
|
||||
|
||||
self.bridge = bridge.Bridge(device, self.channel, self.gamemac)
|
||||
self.announce = packets.Announce(self.gamemac, self.channel,
|
||||
self.gameid, 0, "testgame")
|
||||
|
||||
self.announcequeue = Queue.Queue()
|
||||
self.bridge.registerQueue(self.announcequeue)
|
||||
self.announcechannel = announcechannel
|
||||
self.announcemac = announcemac
|
||||
self.askname = askname
|
||||
|
||||
self.sendAnnounce()
|
||||
|
||||
self.maxplayer = maxplayer
|
||||
self.players = {}
|
||||
self.callbacks = []
|
||||
self.queue = Queue.Queue()
|
||||
self.bridge.registerQueue(self.queue)
|
||||
self.bridge.registerCallback(self.receivedPacket)
|
||||
self.checkPlayers()
|
||||
|
||||
def checkPlayers(self):
|
||||
if self.maxplayer > 0:
|
||||
toremove = []
|
||||
for id in self.players:
|
||||
player = self.players[id]
|
||||
player.timeout-=1
|
||||
if player.timeout == 0:
|
||||
toremove.append(id)
|
||||
for id in toremove:
|
||||
player = self.players[id]
|
||||
if self.askname:
|
||||
print "removing player", player.nick
|
||||
else:
|
||||
print "removing player", id
|
||||
|
||||
del self.players[id]
|
||||
if player.active:
|
||||
player.active = False
|
||||
for callback in self.callbacks:
|
||||
callback("removed", player)
|
||||
self.timer = threading.Timer(1, self.checkPlayers)
|
||||
self.timer.start()
|
||||
|
||||
def receivedPacket(self, packet):
|
||||
if self.maxplayer == 0:
|
||||
return
|
||||
if isinstance(packet, packets.Join):
|
||||
# flags = 1: join ok
|
||||
# flags = 0: join not ok
|
||||
flags = 0
|
||||
if len(self.players) < self.maxplayer:
|
||||
flags = 1
|
||||
self.players[packet.id] = Player(packet.id)
|
||||
|
||||
ack = packets.Ack(packet.id, packet.ctr, flags)
|
||||
qp = bridge.QueuePacket(
|
||||
self.channel, self.playermac, False, ack)
|
||||
self.bridge.putInQueue(self.queue, qp)
|
||||
elif packet.id in self.players:
|
||||
print "player known:", packet.id
|
||||
player = self.players[packet.id]
|
||||
player.timeout = 10
|
||||
if not player.active and isinstance(packet, packets.Button):
|
||||
if self.askname:
|
||||
nickrequest = packets.Nickrequest(packet.id)
|
||||
qp = bridge.QueuePacket(self.channel,
|
||||
self.playermac, False, nickrequest)
|
||||
self.bridge.putInQueue(self.queue, qp)
|
||||
else:
|
||||
player.active = True
|
||||
for callback in self.callbacks:
|
||||
callback("added", player)
|
||||
elif not player.active and isinstance(packet, packets.Nick):
|
||||
if self.askname:
|
||||
player.nick = packet.nick
|
||||
player.active = True
|
||||
for callback in self.callbacks:
|
||||
callback("added", player)
|
||||
else:
|
||||
print "player unknown"
|
||||
|
||||
def sendAnnounce(self):
|
||||
aq = bridge.QueuePacket(self.announcechannel,
|
||||
self.announcemac, False, self.announce)
|
||||
self.bridge.putInQueue(self.announcequeue, aq)
|
||||
self.announcetimer = threading.Timer(1, self.sendAnnounce)
|
||||
self.announcetimer.start()
|
||||
|
||||
def registerPlayerCallback(self, callback):
|
||||
if not callback in self.callbacks:
|
||||
self.callbacks.append(callback)
|
|
@ -0,0 +1,207 @@
|
|||
def inttouint32(v):
|
||||
return chr(v&0xff)+chr((v>>8)&0xff)+chr((v>>16)&0xff)+chr((v>>24)&0xff)
|
||||
|
||||
def uint32toint(v):
|
||||
return (ord(v[3])<< 24) + (ord(v[2])<<16) + (ord(v[1])<<8) + (ord(v[0]))
|
||||
|
||||
class Packet:
|
||||
def __init__(self, command, id=None):
|
||||
self.ctr = 0
|
||||
if id == None:
|
||||
message = command
|
||||
command = message[2]
|
||||
id = uint32toint(message[3:7])
|
||||
self.ctr = uint32toint(message[7:11])
|
||||
self.length = 32
|
||||
self.protocol = 'G'
|
||||
self.command = command
|
||||
self.id = id
|
||||
self.priority = 5
|
||||
|
||||
def toMessage(self):
|
||||
message = chr(self.length)
|
||||
message += self.protocol
|
||||
message += self.command
|
||||
message += inttouint32(self.id)
|
||||
message += inttouint32(self.ctr)
|
||||
return message
|
||||
|
||||
def headerString(self):
|
||||
return "id=%d, ctr=%d"%(self.id, self.ctr)
|
||||
|
||||
def __str__(self):
|
||||
s = "Packet with protocol=" + self.protocol
|
||||
s += ", command=" + self.command
|
||||
s += ", "+ self.headerString()
|
||||
return s
|
||||
|
||||
class Button(Packet):
|
||||
def __init__(self, id, button=None):
|
||||
if button!= None:
|
||||
Packet.__init__(self, 'B', id)
|
||||
else:
|
||||
message = id
|
||||
Packet.__init__(self, message)
|
||||
button = ord(message[11])
|
||||
self.button = button
|
||||
|
||||
def toMessage(self):
|
||||
base = Packet.toMessage(self)
|
||||
return base + chr(self.button) + '\x00'*18
|
||||
|
||||
def __str__(self):
|
||||
s = "Button packet with " + self.headerString()
|
||||
s += ", button=%d"%self.button
|
||||
return s
|
||||
|
||||
class Announce(Packet):
|
||||
def __init__(self, gameMac, gameChannel, gameId, gameFlags, gameTitle):
|
||||
#always a broadcast
|
||||
Packet.__init__(self, 'A', 0)
|
||||
self.gameMac = gameMac
|
||||
self.gameChannel = gameChannel
|
||||
self.gameId = gameId
|
||||
self.gameFlags = gameFlags
|
||||
self.gameTitle = gameTitle[0:8]
|
||||
self.priority = 3
|
||||
|
||||
def toMessage(self):
|
||||
message = Packet.toMessage(self)
|
||||
message += ''.join([chr(x) for x in self.gameMac])
|
||||
message += chr(self.gameChannel)
|
||||
message += inttouint32(self.gameId)
|
||||
message += chr(self.gameFlags)
|
||||
message += self.gameTitle
|
||||
if len(self.gameTitle) < 8:
|
||||
message += '\x00'*(8-len(self.gameTitle))
|
||||
return message
|
||||
|
||||
def __str__(self):
|
||||
s = "Announce packet with " + self.headerString()
|
||||
s += ", gameMac="+str(self.gameMac)
|
||||
s += ", gameChannel=%d"%self.gameChannel
|
||||
s += ", gameId=%d"%self.gameId
|
||||
s += ", gameFlags=%d"%self.gameFlags
|
||||
s += ", gameTitle="+self.gameTitle
|
||||
return s
|
||||
|
||||
class Join(Packet):
|
||||
def __init__(self, id, gameId=None):
|
||||
if gameId != None:
|
||||
Packet.__init__(self, 'J', id)
|
||||
else:
|
||||
message = id
|
||||
Packet.__init__(self, message)
|
||||
gameId = uint32toint(message[11:15])
|
||||
self.gameId = gameId
|
||||
|
||||
def toMessage(self):
|
||||
message = Packet.toMessage(self)
|
||||
message += inttouint32(self.gameId)
|
||||
message += '\x00'*15
|
||||
return message
|
||||
|
||||
def __str__(self):
|
||||
s = "Join packet with " + self.headerString()
|
||||
s += ", gameId=%d"%self.gameId
|
||||
return s
|
||||
|
||||
class Ack(Packet):
|
||||
def __init__(self, id, ctr, flags=None):
|
||||
if ctr != None and flags != None:
|
||||
Packet.__init__(self, 'a', id)
|
||||
self.ctr = ctr
|
||||
else:
|
||||
message = id
|
||||
Packet.__init__(self, message)
|
||||
flags = ord(message[11])
|
||||
self.flags = flags
|
||||
self.priority = 3
|
||||
|
||||
def toMessage(self):
|
||||
message = Packet.toMessage(self)
|
||||
message += chr(self.flags)
|
||||
message += '\x00'*18
|
||||
return message
|
||||
|
||||
def __str__(self):
|
||||
s = "Ack packet with " + self.headerString()
|
||||
s += ", flags=%d"%self.flags
|
||||
return s
|
||||
|
||||
class Nickrequest(Packet):
|
||||
def __init__(self, id):
|
||||
Packet.__init__(self, 'N', id)
|
||||
|
||||
def __str__(self):
|
||||
s = "Nickrequest packet with " + self.headerString()
|
||||
return s
|
||||
|
||||
def toMessage(self):
|
||||
message = Packet.toMessage(self)
|
||||
message += '\x00'*19
|
||||
return message
|
||||
|
||||
class Nick(Packet):
|
||||
def __init__(self, id, flags=None, nick=None):
|
||||
if flags != None and nick != None:
|
||||
Packet.__init__(self, 'n', id)
|
||||
else:
|
||||
message = id
|
||||
Packet.__init__(self, message)
|
||||
flags = ord(message[11])
|
||||
nick = message[12:30].rstrip(' \t\r\n\0')
|
||||
self.flags = flags
|
||||
self.nick = nick
|
||||
|
||||
def toMessage(self):
|
||||
message = Packet.toMessage(self)
|
||||
message += chr(self.flags)
|
||||
message += self.nick
|
||||
if len(self.nick) < 18:
|
||||
message += '\x00'*(18-len(self.nick))
|
||||
return message
|
||||
|
||||
def __str__(self):
|
||||
s = "Nick packet with " + self.headerString()
|
||||
s += ", flags=%d"%self.flags
|
||||
s += ", nick="+self.nick
|
||||
return s
|
||||
|
||||
class Text(Packet):
|
||||
def __init__(self, id, x, y, flags, text):
|
||||
Packet.__init__(self, 'T', id)
|
||||
self.x = x
|
||||
self.y = y
|
||||
self. flags = flags
|
||||
self.text = text[0:16]
|
||||
|
||||
def toMessage(self):
|
||||
message = Packet.toMessage(self)
|
||||
message += chr(self.x)
|
||||
message += chr(self.y)
|
||||
message += chr(self.flags)
|
||||
message += self.text
|
||||
if len(self.text) < 16:
|
||||
message += '\x00'*(16-len(self.text))
|
||||
return message
|
||||
|
||||
def __str__(self):
|
||||
s = "Text packet with " + self.headerString()
|
||||
s += ", x=%d"%self.x
|
||||
s += ", y=%d"%self.y
|
||||
s += ", flags=%d"%self.flags
|
||||
s += ", text="+self.text
|
||||
return s
|
||||
|
||||
def fromMessage(message):
|
||||
if len(message) >= 30 and ord(message[0]) == 32 and message[1] == 'G':
|
||||
if message[2] == 'B':
|
||||
return Button(message)
|
||||
if message[2] == 'n':
|
||||
return Nick(message)
|
||||
if message[2] == 'J':
|
||||
return Join(message)
|
||||
if message[2] == 'a':
|
||||
return Ack(message)
|
||||
return None
|
|
@ -0,0 +1,92 @@
|
|||
import serial
|
||||
import string
|
||||
import sys
|
||||
import time
|
||||
|
||||
class SerialInterface:
|
||||
def __init__ ( self, path2device, baudrate, timeout=0):
|
||||
self.portopen = False
|
||||
while not self.portopen:
|
||||
try:
|
||||
self.ser = serial.Serial(path2device, baudrate)
|
||||
self.path2device = path2device
|
||||
self.baudrate = baudrate
|
||||
self.timeout = timeout+1
|
||||
self.ser.flushInput()
|
||||
self.ser.flushOutput()
|
||||
if timeout:
|
||||
self.ser.setTimeout(timeout+1)
|
||||
self.portopen = True
|
||||
except serial.SerialException:
|
||||
print "exception while opening"
|
||||
pass
|
||||
time.sleep(1)
|
||||
#print "done"
|
||||
def close(self):
|
||||
try:
|
||||
self.portopen = False
|
||||
self.ser.close()
|
||||
except serial.SerialException:
|
||||
pass
|
||||
def reinit(self):
|
||||
self.close()
|
||||
print "reopening"
|
||||
while not self.portopen:
|
||||
self.__init__(self.path2device, self.baudrate, self.timeout)
|
||||
time.sleep(1)
|
||||
print "done"
|
||||
|
||||
def writeMessage(self,command,message):
|
||||
enc = "\\"+ command + message.replace('\\','\\\\') + "\\0";
|
||||
#print 'writing %s' % list(enc)
|
||||
try:
|
||||
self.ser.write(enc)
|
||||
except :
|
||||
pass
|
||||
#self.reinit()
|
||||
|
||||
def readMessage(self):
|
||||
data = ""
|
||||
escaped = False
|
||||
stop = False
|
||||
start = False
|
||||
inframe = False
|
||||
command = ''
|
||||
while True:
|
||||
starttime = time.time()
|
||||
c = self.ser.read(1)
|
||||
endtime = time.time()
|
||||
if len(c) == 0: #A timout occured
|
||||
if endtime-starttime < self.timeout - 1:
|
||||
print "port broken"
|
||||
self.reinit()
|
||||
raise Exception()
|
||||
else:
|
||||
#print 'TIMEOUT'
|
||||
return (False, '')
|
||||
if escaped:
|
||||
if c == '\\':
|
||||
d = '\\'
|
||||
elif c == '0':
|
||||
stop = True
|
||||
inframe = False
|
||||
else:
|
||||
start = True
|
||||
inframe = True
|
||||
command = c
|
||||
data = ""
|
||||
escaped = False
|
||||
elif c == '\\':
|
||||
escaped = 1
|
||||
else:
|
||||
d = c
|
||||
|
||||
if start and inframe:
|
||||
start = False
|
||||
elif stop:
|
||||
#print 'received message: len=%d data=%s'%(len(data),data)
|
||||
#print 'received message. command=',command, "data=" ,list(data)
|
||||
return (command, data)
|
||||
elif escaped == False and inframe:
|
||||
data += str(d)
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
from distutils.core import setup
|
||||
setup(name='r0ketrem0te',
|
||||
version='1.0',
|
||||
packages=['r0ketrem0te'],
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
import r0ketrem0te.game
|
||||
import r0ketrem0te.bridge
|
||||
import r0ketrem0te.packets
|
||||
import time
|
||||
import Queue
|
||||
|
||||
def receivedPacket(packet):
|
||||
pass
|
||||
game = r0ketrem0te.game.Game('/dev/ttyACM0', "testgame", 83,
|
||||
81, [ord(x) for x in 'REM0T'], 2, True)
|
||||
queue = Queue.Queue()
|
||||
game.bridge.registerQueue(queue)
|
||||
game.bridge.registerCallback(receivedPacket)
|
||||
|
||||
while True:
|
||||
time.sleep(1)
|