Skip to content

Commit

Permalink
Implemented firmware-accelerated channel scann
Browse files Browse the repository at this point in the history
  • Loading branch information
Arnaud Taffanel committed Jan 5, 2013
1 parent 0c6e72c commit d782fdb
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 0 deletions.
1 change: 1 addition & 0 deletions firmware/inc/radio.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ unsigned char radioSendPacket(__xdata char *payload, char len,
void radioSendPacketNoAck(__xdata char *payload, char len);
void radioSetChannel(char channel);
void radioSetDataRate(unsigned char dr);
char radioGetDataRate();
void radioSetAddress(__xdata char* address);
void radioSetPower(char power);
void radioSetArd(char ard);
Expand Down
1 change: 1 addition & 0 deletions firmware/inc/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ typedef struct {
#define SET_RADIO_ARC 0x06
#define ACK_ENABLE 0x10
#define SET_CONT_CARRIER 0x20
#define CHANNEL_SCANN 0x21
#define LAUNCH_BOOTLOADER 0xFF

//SET_DATA_RATE parameter
Expand Down
63 changes: 63 additions & 0 deletions firmware/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ __xdata char tbuffer[33];
//Receive buffer (from the ack)
__xdata char rbuffer[33];

//Limits the scann result to 63B to avoid having to send two result USB packet
//See usb_20.pdf #8.5.3.2
#define MAX_SCANN_LENGTH 63
static char scannLength;

static bool contCarrier=false;
static bool needAck = true;

Expand Down Expand Up @@ -243,6 +248,64 @@ void handleUsbVendorSetup()
usbAckSetup();
return;
}
else if(setup->request == CHANNEL_SCANN && setup->requestType == 0x40)
{
int i;
char rlen;
char status;
char inc = 1;
unsigned char start, stop;
scannLength = 0;

if(setup->length < 1)
{
usbDismissSetup();
return;
}

//Start and stop channels
start = setup->value;
stop = (setup->index>125)?125:setup->index;

if (radioGetDataRate() == DATA_RATE_2M)
inc = 2; //2M channel are 2MHz wide

//Arm and wait for the out transaction
OUT0BC = BCDUMMY;
while (EP0CS & OUTBSY);

memcpy(tbuffer, OUT0BUF, setup->length);
for (i=start; i<stop+1 && scannLength<MAX_SCANN_LENGTH; i+=inc)
{
radioSetChannel(i);
status = radioSendPacket(tbuffer, setup->length, rbuffer, &rlen);

if (status)
IN0BUF[scannLength++] = i;

ledTimeout = 2;
ledSet(LED_GREEN | LED_RED, false);
if(status)
ledSet(LED_GREEN, true);
else
ledSet(LED_RED, true);
}

//Ack the setup phase
usbAckSetup();
return;
}
else if(setup->request == CHANNEL_SCANN && setup->requestType == 0xC0)
{
//IN0BUF already contains the right data
//(if a scann has been launched before ...)
IN0BC = (setup->length>scannLength)?scannLength:setup->length;
while (EP0CS & INBSY);

//Ack the setup phase
usbAckSetup();
return;
}
}

//Stall in error if nothing executed!
Expand Down
5 changes: 5 additions & 0 deletions firmware/src/radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,11 @@ void radioSetDataRate(unsigned char dr)
radioUpdateRetr();
}

char radioGetDataRate()
{
return radioConf.dataRate;
}

void radioSetPower(char power)
{
radioConf.power = power&0x03;
Expand Down
26 changes: 26 additions & 0 deletions lib/crazyradio.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
SET_RADIO_ARC = 0x06
ACK_ENABLE = 0x10
SET_CONT_CARRIER = 0x20
SCANN_CHANNELS = 0x21
LAUNCH_BOOTLOADER = 0xFF

try:
Expand Down Expand Up @@ -188,6 +189,23 @@ def setContCarrier(self, active):
else:
sendVendorSetup(self.handle, SET_CONT_CARRIER, 0, 0, ())

def hasFwScann(self):
return self.version>=0.5

def scannChannels(self, start, stop, packet):

if self.hasFwScann():# Fast firmware-driven scann
sendVendorSetup(self.handle, SCANN_CHANNELS, start, stop, packet)
return tuple(getVendorSetup(self.handle, SCANN_CHANNELS, 0, 0, 64))
else: # Slow PC-driven scann
result = tuple()
for i in range(start, stop+1):
self.setChannel(i)
status = self.sendPacket(packet)
if status and status.ack:
result = result + (i,)
return result

### Data transferts ###
def sendPacket(self, dataOut):
""" Send a packet and receive the ack from the radio dongle
Expand Down Expand Up @@ -224,3 +242,11 @@ def sendVendorSetup(handle, request, value, index, data):
handle.ctrl_transfer(usb.TYPE_VENDOR, request, wValue=value, wIndex=index, timeout=1000, data_or_wLength = data)
else:
handle.controlMsg(usb.TYPE_VENDOR, request, data, value=value, index=index, timeout=1000)

def getVendorSetup(handle, request, value, index, length):
if pyusb1:
return handle.ctrl_transfer(usb.TYPE_VENDOR | 0x80, request, wValue=value,
wIndex=index, timeout=1000, data_or_wLength = length)
else:
return handle.controlMsg(usb.TYPE_VENDOR | 0x80, request, length, value=value,
index=index, timeout=1000)

0 comments on commit d782fdb

Please sign in to comment.