Merge CDC-ECM, RNG, DFU bootloader, watchdog, settings manager, energy scan routines of Robert Quattlebaum
This commit is contained in:
parent
7b529cac03
commit
110bc0242e
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile.avr,v 1.24 2010/06/22 17:11:38 dak664 Exp $
|
||||
# $Id: Makefile.avr,v 1.25 2010/09/17 21:59:09 dak664 Exp $
|
||||
|
||||
### Check if we are running under Windows
|
||||
|
||||
|
@ -23,7 +23,7 @@ CONTIKI_CPU=$(CONTIKI)/cpu/avr
|
|||
### These directories will be searched for the specified source files
|
||||
### TARGETLIBS are platform-specific routines in the contiki library path
|
||||
CONTIKI_CPU_DIRS = . dev
|
||||
AVR = clock.c mtarch.c eeprom.c flash.c rs232.c leds-arch.c watchdog.c rtimer-arch.c
|
||||
AVR = clock.c mtarch.c eeprom.c flash.c rs232.c leds-arch.c watchdog.c rtimer-arch.c bootloader.c settings.c
|
||||
ELFLOADER = elfloader.c elfloader-avr.c symtab-avr.c
|
||||
TARGETLIBS = random.c leds.c
|
||||
|
||||
|
|
59
cpu/avr/bootloader.c
Normal file
59
cpu/avr/bootloader.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
#include "bootloader.h"
|
||||
#include "dev/watchdog.h"
|
||||
#include <util/delay.h>
|
||||
#include <avr/wdt.h>
|
||||
#include "dev/usb/usb_drv.h"
|
||||
|
||||
volatile uint32_t Boot_Key ATTR_NO_INIT;
|
||||
|
||||
bool
|
||||
bootloader_is_present(void) {
|
||||
return pgm_read_word_far(BOOTLOADER_START_ADDRESS)!=0xFFFF;
|
||||
}
|
||||
|
||||
void
|
||||
Jump_To_Bootloader(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
#ifdef UDCON
|
||||
// If USB is used, detach from the bus
|
||||
Usb_detach();
|
||||
#endif
|
||||
|
||||
// Disable all interrupts
|
||||
cli();
|
||||
|
||||
// Set the bootloader key to the magic value and force a reset
|
||||
Boot_Key = MAGIC_BOOT_KEY;
|
||||
|
||||
// Wait two seconds for the USB detachment to register on the host
|
||||
for (i = 0; i < 128; i++)
|
||||
_delay_ms(16);
|
||||
|
||||
// Set the bootloader key to the magic value and force a reset
|
||||
Boot_Key = MAGIC_BOOT_KEY;
|
||||
|
||||
watchdog_reboot();
|
||||
}
|
||||
|
||||
extern void Bootloader_Jump_Check(void) ATTR_INIT_SECTION(3);
|
||||
|
||||
void
|
||||
Bootloader_Jump_Check(void)
|
||||
{
|
||||
// If the reset source was the bootloader and the key is correct, clear it and jump to the bootloader
|
||||
if(MCUSR & (1<<WDRF)) {
|
||||
MCUSR = 0;
|
||||
if(Boot_Key == MAGIC_BOOT_KEY) {
|
||||
Boot_Key = 0;
|
||||
wdt_disable();
|
||||
|
||||
((void (*)(void))BOOTLOADER_START_ADDRESS)();
|
||||
} else {
|
||||
Boot_Key++;
|
||||
}
|
||||
} else {
|
||||
Boot_Key = MAGIC_BOOT_KEY-4;
|
||||
}
|
||||
}
|
24
cpu/avr/bootloader.h
Normal file
24
cpu/avr/bootloader.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef __AVR_BOOTLOADER_H__
|
||||
#define __AVR_BOOTLOADER_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <avr/io.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define ATTR_INIT_SECTION(SectionIndex) __attribute__ ((naked, section (".init" #SectionIndex )))
|
||||
#define ATTR_NO_INIT __attribute__ ((section (".noinit")))
|
||||
|
||||
#ifndef BOOTLOADER_SEC_SIZE_BYTES
|
||||
#define BOOTLOADER_SEC_SIZE_BYTES (0x1000)
|
||||
#endif
|
||||
|
||||
#ifndef BOOTLOADER_START_ADDRESS
|
||||
#define BOOTLOADER_START_ADDRESS (FLASHEND-BOOTLOADER_SEC_SIZE_BYTES+1)
|
||||
#endif
|
||||
|
||||
#define MAGIC_BOOT_KEY 0xDC42ACCA
|
||||
|
||||
extern void Jump_To_Bootloader(void);
|
||||
extern bool bootloader_is_present(void);
|
||||
|
||||
#endif
|
|
@ -94,6 +94,14 @@
|
|||
|
||||
/** USB RNDIS / Virtual com port setup **/
|
||||
|
||||
#ifndef CDC_ECM_USES_INTERRUPT_ENDPOINT
|
||||
#define CDC_ECM_USES_INTERRUPT_ENDPOINT 0
|
||||
#endif
|
||||
|
||||
#ifndef USB_ETH_EMULATE_WIFI
|
||||
#define USB_ETH_EMULATE_WIFI 0
|
||||
#endif
|
||||
|
||||
#define NB_ENDPOINTS 7 //! number of endpoints in the application including control endpoint
|
||||
#define VCP_RX_EP 0x06
|
||||
#define VCP_TX_EP 0x05
|
||||
|
|
327
cpu/avr/dev/usb/rndis/cdc_ecm.c
Normal file
327
cpu/avr/dev/usb/rndis/cdc_ecm.c
Normal file
|
@ -0,0 +1,327 @@
|
|||
#include <stdbool.h>
|
||||
#include "cdc_ecm.h"
|
||||
#include "contiki.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "rndis/rndis_task.h"
|
||||
#include "rndis/rndis_protocol.h"
|
||||
#include "uip.h"
|
||||
#include "sicslow_ethernet.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
#define PRINTF printf
|
||||
#define PRINTF_P printf_P
|
||||
|
||||
extern uint8_t usb_eth_data_buffer[64];
|
||||
static U16 usb_ecm_packet_filter = 0;
|
||||
|
||||
#define PACKET_TYPE_PROMISCUOUS (1<<0)
|
||||
#define PACKET_TYPE_ALL_MULTICAST (1<<1)
|
||||
#define PACKET_TYPE_DIRECTED (1<<2)
|
||||
#define PACKET_TYPE_BROADCAST (1<<3)
|
||||
#define PACKET_TYPE_MULTICAST (1<<4)
|
||||
|
||||
#define Usb_write_word(x) Usb_write_byte((x)&0xFF),Usb_write_byte((x>>8)&0xFF)
|
||||
#define Usb_write_long(x) Usb_write_word((x)&0xFFFF),Usb_write_word((x>>16)&0xFFFF)
|
||||
|
||||
#define Usb_read_word() ((U16)Usb_read_byte()+((U16)Usb_read_byte()<<8))
|
||||
|
||||
void
|
||||
cdc_ecm_set_ethernet_packet_filter(void) {
|
||||
usb_ecm_packet_filter = Usb_read_word();
|
||||
|
||||
Usb_ack_receive_setup();
|
||||
Usb_send_control_in();
|
||||
usb_endpoint_wait_for_read_control_enabled();
|
||||
|
||||
PRINTF_P(PSTR("cdc_ecm: Received SET_ETHERNET_PACKET_FILTER: (0x%04X) "),usb_ecm_packet_filter);
|
||||
if(usb_ecm_packet_filter & PACKET_TYPE_PROMISCUOUS) {
|
||||
PRINTF_P(PSTR("PROMISCUOUS "));
|
||||
USB_ETH_HOOK_SET_PROMISCIOUS_MODE(true);
|
||||
} else {
|
||||
USB_ETH_HOOK_SET_PROMISCIOUS_MODE(false);
|
||||
}
|
||||
|
||||
if(usb_ecm_packet_filter & PACKET_TYPE_ALL_MULTICAST)
|
||||
PRINTF_P(PSTR("ALL_MULTICAST "));
|
||||
if(usb_ecm_packet_filter & PACKET_TYPE_DIRECTED)
|
||||
PRINTF_P(PSTR("DIRECTED "));
|
||||
if(usb_ecm_packet_filter & PACKET_TYPE_BROADCAST)
|
||||
PRINTF_P(PSTR("BROADCAST "));
|
||||
if(usb_ecm_packet_filter & PACKET_TYPE_MULTICAST)
|
||||
PRINTF_P(PSTR("MULTICAST "));
|
||||
|
||||
PRINTF_P(PSTR("\n"));
|
||||
}
|
||||
|
||||
|
||||
#define CDC_NOTIFY_NETWORK_CONNECTION (0x00)
|
||||
#define CDC_NOTIFY_CONNECTION_SPEED_CHANGE (0x2A)
|
||||
|
||||
void
|
||||
cdc_ecm_notify_network_connection(uint8_t value) {
|
||||
#if CDC_ECM_USES_INTERRUPT_ENDPOINT
|
||||
Usb_select_endpoint(INT_EP);
|
||||
|
||||
if(!Is_usb_endpoint_enabled()) {
|
||||
//PRINTF_P(PSTR("cdc_ecm: cdc_ecm_notify_network_connection: endpoint not enabled\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if(usb_endpoint_wait_for_IN_ready()!=0) {
|
||||
//PRINTF_P(PSTR("cdc_ecm: cdc_ecm_notify_network_connection: Timeout waiting for interrupt endpoint to be available\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
Usb_send_control_in();
|
||||
|
||||
Usb_write_byte(0x51); // 10100001b
|
||||
Usb_write_byte(CDC_NOTIFY_NETWORK_CONNECTION);
|
||||
Usb_write_byte(value);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_word(ECM_INTERFACE0_NB);
|
||||
Usb_write_word(0x0000);
|
||||
|
||||
Usb_send_in();
|
||||
PRINTF_P(PSTR("cdc_ecm: CDC_NOTIFY_NETWORK_CONNECTION %d\n"),value);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define CDC_ECM_DATA_ENDPOINT_SIZE 64
|
||||
|
||||
void cdc_ecm_configure_endpoints() {
|
||||
#if CDC_ECM_USES_INTERRUPT_ENDPOINT
|
||||
usb_configure_endpoint(INT_EP, \
|
||||
TYPE_INTERRUPT, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_8, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
#endif
|
||||
|
||||
usb_configure_endpoint(TX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_64, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
|
||||
usb_configure_endpoint(RX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_OUT, \
|
||||
SIZE_64, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
#if CDC_ECM_USES_INTERRUPT_ENDPOINT
|
||||
Usb_reset_endpoint(INT_EP);
|
||||
#endif
|
||||
Usb_reset_endpoint(TX_EP);
|
||||
Usb_reset_endpoint(RX_EP);
|
||||
usb_eth_is_active = 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cdc_ecm_notify_connection_speed_change(uint32_t upstream,uint32_t downstream) {
|
||||
#if CDC_ECM_USES_INTERRUPT_ENDPOINT
|
||||
Usb_select_endpoint(INT_EP);
|
||||
|
||||
if(!Is_usb_endpoint_enabled())
|
||||
return;
|
||||
|
||||
if(usb_endpoint_wait_for_IN_ready()!=0)
|
||||
return;
|
||||
|
||||
Usb_send_control_in();
|
||||
|
||||
Usb_write_byte(0x51); // 10100001b
|
||||
Usb_write_byte(CDC_NOTIFY_CONNECTION_SPEED_CHANGE);
|
||||
Usb_write_word(0x0000);
|
||||
Usb_write_word(ECM_INTERFACE0_NB);
|
||||
Usb_write_word(0x0008);
|
||||
|
||||
Usb_send_in();
|
||||
|
||||
if(usb_endpoint_wait_for_write_enabled()!=0)
|
||||
return;
|
||||
|
||||
Usb_write_long(upstream);
|
||||
Usb_write_long(downstream);
|
||||
Usb_send_in();
|
||||
|
||||
PRINTF_P(PSTR("cdc_ecm: CDC_NOTIFY_CONNECTION_SPEED_CHANGE UP:%d DOWN:%d\n"),upstream,downstream);
|
||||
#endif
|
||||
}
|
||||
|
||||
void cdc_ecm_set_active(uint8_t value) {
|
||||
if(value!=usb_eth_is_active) {
|
||||
Led3_on();
|
||||
|
||||
usb_eth_is_active = value;
|
||||
cdc_ecm_notify_network_connection(value);
|
||||
if(value) {
|
||||
cdc_ecm_notify_connection_speed_change(250000,250000);
|
||||
} else {
|
||||
cdc_ecm_notify_connection_speed_change(0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
cdc_ecm_process(void) {
|
||||
static uint8_t doInit = 1;
|
||||
|
||||
Usb_select_endpoint(RX_EP);
|
||||
|
||||
if(!Is_usb_endpoint_enabled()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (doInit) {
|
||||
#ifdef USB_ETH_HOOK_INIT
|
||||
USB_ETH_HOOK_INIT();
|
||||
#endif
|
||||
cdc_ecm_notify_network_connection(1);
|
||||
cdc_ecm_notify_connection_speed_change(250000,250000);
|
||||
doInit = 0;
|
||||
if(usb_ecm_packet_filter & PACKET_TYPE_PROMISCUOUS) {
|
||||
#if RF230BB
|
||||
rf230_set_promiscuous_mode(true);
|
||||
#else
|
||||
radio_set_trx_state(RX_ON);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Select again, just to make sure.
|
||||
Usb_select_endpoint(RX_EP);
|
||||
}
|
||||
|
||||
if(!usb_eth_is_active) {
|
||||
// If we aren't active, just eat the packets.
|
||||
if(Is_usb_read_enabled()) {
|
||||
Usb_ack_receive_out();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Connected!
|
||||
Led0_on();
|
||||
|
||||
if(Is_usb_read_enabled()) {
|
||||
uint16_t bytecounter;
|
||||
uint16_t bytes_received = 0;
|
||||
U8 * buffer = uip_buf;
|
||||
|
||||
if(!usb_eth_ready_for_next_packet()) {
|
||||
// Since we aren't ready for a packet yet,
|
||||
// just return.
|
||||
goto bail;
|
||||
}
|
||||
|
||||
#ifdef USB_ETH_HOOK_RX_START
|
||||
USB_ETH_HOOK_RX_START();
|
||||
#endif
|
||||
|
||||
while((bytecounter=Usb_byte_counter_8())==CDC_ECM_DATA_ENDPOINT_SIZE) {
|
||||
while((bytes_received<USB_ETH_MTU) && (bytecounter--)) {
|
||||
*buffer++ = Usb_read_byte();
|
||||
bytes_received++;
|
||||
}
|
||||
bytes_received+=bytecounter+1;
|
||||
|
||||
//ACK previous data
|
||||
Usb_ack_receive_out();
|
||||
|
||||
//Wait for new data
|
||||
if(usb_endpoint_wait_for_read_enabled()!=0) {
|
||||
USB_ETH_HOOK_RX_ERROR("Timeout: read enabled");
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
while((bytes_received<USB_ETH_MTU) && (bytecounter--)) {
|
||||
*buffer++ = Usb_read_byte();
|
||||
bytes_received++;
|
||||
}
|
||||
bytes_received+=bytecounter+1;
|
||||
|
||||
//Ack final data packet
|
||||
Usb_ack_receive_out();
|
||||
|
||||
//PRINTF_P(PSTR("cdc_ecm: Got packet %d bytes long\n"),bytes_received);
|
||||
|
||||
#ifdef USB_ETH_HOOK_RX_END
|
||||
USB_ETH_HOOK_RX_END();
|
||||
#endif
|
||||
|
||||
//Send data over RF or to local stack
|
||||
if(bytes_received<=USB_ETH_MTU) {
|
||||
|
||||
USB_ETH_HOOK_HANDLE_INBOUND_PACKET(uip_buf,bytes_received);
|
||||
} else {
|
||||
USB_ETH_HOOK_RX_ERROR("Oversized packet");
|
||||
}
|
||||
}
|
||||
bail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
ecm_send(uint8_t * senddata, uint16_t sendlen, uint8_t led) {
|
||||
U8 byte_in_packet = 0;
|
||||
|
||||
//Send Data
|
||||
Usb_select_endpoint(TX_EP);
|
||||
|
||||
if(usb_endpoint_wait_for_write_enabled()!=0) {
|
||||
USB_ETH_HOOK_TX_ERROR("Timeout: write enabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USB_ETH_HOOK_TX_START
|
||||
USB_ETH_HOOK_TX_START();
|
||||
#endif
|
||||
|
||||
//Send packet
|
||||
while(sendlen) {
|
||||
Usb_write_byte(*senddata);
|
||||
senddata++;
|
||||
sendlen--;
|
||||
byte_in_packet++;
|
||||
|
||||
//If endpoint is full, send data in
|
||||
//And then wait for data to transfer
|
||||
if (!Is_usb_write_enabled()) {
|
||||
Usb_ack_in_ready();
|
||||
|
||||
if(usb_endpoint_wait_for_write_enabled()!=0) {
|
||||
USB_ETH_HOOK_TX_ERROR("Timeout: write enabled");
|
||||
return 0;
|
||||
}
|
||||
byte_in_packet=0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Send last data in - also handles sending a ZLP if needed
|
||||
Usb_ack_in_ready();
|
||||
|
||||
#ifdef USB_ETH_HOOK_TX_END
|
||||
USB_ETH_HOOK_TX_END();
|
||||
#endif
|
||||
|
||||
//Wait for ready
|
||||
if(usb_endpoint_wait_for_IN_ready()!=0) {
|
||||
USB_ETH_HOOK_TX_ERROR("Timeout: IN ready");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
18
cpu/avr/dev/usb/rndis/cdc_ecm.h
Normal file
18
cpu/avr/dev/usb/rndis/cdc_ecm.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
#ifndef __CDC_ECM_H__
|
||||
#define __CDC_ECM_H__
|
||||
|
||||
#include "contiki.h"
|
||||
#include <stdint.h>
|
||||
#include "conf_usb.h"
|
||||
|
||||
#define SET_ETHERNET_PACKET_FILTER (0x43)
|
||||
|
||||
|
||||
extern uint8_t cdc_ecm_process(void);
|
||||
extern uint8_t ecm_send(uint8_t * senddata, uint16_t sendlen, uint8_t led);
|
||||
extern void cdc_ecm_set_ethernet_packet_filter(void);
|
||||
extern void cdc_ecm_configure_endpoints();
|
||||
extern void cdc_ecm_set_active(uint8_t value);
|
||||
|
||||
#endif // __CDC_ECM_H__
|
296
cpu/avr/dev/usb/rndis/cdc_eem.c
Normal file
296
cpu/avr/dev/usb/rndis/cdc_eem.c
Normal file
|
@ -0,0 +1,296 @@
|
|||
#include "cdc_eem.h"
|
||||
#include "contiki.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "rndis/rndis_task.h"
|
||||
#include "rndis/rndis_protocol.h"
|
||||
#include "uip.h"
|
||||
#include "sicslow_ethernet.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
#define PRINTF printf
|
||||
#define PRINTF_P printf_P
|
||||
|
||||
extern uint8_t usb_eth_data_buffer[64];
|
||||
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
#define EEMCMD_ECHO 0x00 ///bmEEMCmd Echo
|
||||
#define EEMCMD_ECHO_RESPONSE 0x01 ///bmEEMCmd Echo Response
|
||||
#define EEMCMD_SUSPEND_HINT 0x02 ///bmEEMCmd Suspend Hint
|
||||
#define EEMCMD_RESPONSE_HINT 0x03 ///bmEEMCmd Response Hint
|
||||
#define EEMCMD_RESPONSE_COMPLETE_HINT 0x04 ///bmEEMCmd Response Complete Hint
|
||||
#define EEMCMD_TICKLE 0x05 ///bmEEMCmd Tickle
|
||||
|
||||
|
||||
void cdc_eem_configure_endpoints() {
|
||||
usb_configure_endpoint(TX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_64, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
|
||||
usb_configure_endpoint(RX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_OUT, \
|
||||
SIZE_64, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
Usb_reset_endpoint(TX_EP);
|
||||
Usb_reset_endpoint(RX_EP);
|
||||
}
|
||||
|
||||
void cdc_eem_process(void) {
|
||||
uint16_t datalength;
|
||||
uint8_t bytecounter, headercounter;
|
||||
uint16_t i;
|
||||
|
||||
#ifdef USB_ETH_HOOK_INIT
|
||||
static uint8_t doInit = 1;
|
||||
if (doInit) {
|
||||
USB_ETH_HOOK_INIT();
|
||||
doInit = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
//Connected!
|
||||
Led0_on();
|
||||
|
||||
Usb_select_endpoint(RX_EP);
|
||||
|
||||
//If we have data and a free buffer
|
||||
if(Is_usb_receive_out() && (uip_len == 0)) {
|
||||
|
||||
//Read how much (endpoint only stores up to 64 bytes anyway)
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
|
||||
//EEM uses 2 bytes as a header
|
||||
headercounter = 2;
|
||||
|
||||
uint8_t fail = 0;
|
||||
|
||||
//Hmm.. what's going on here?
|
||||
if (bytecounter < headercounter) {
|
||||
Usb_ack_receive_out();
|
||||
//TODO CO done = 1;
|
||||
}
|
||||
|
||||
//Read EEM Header
|
||||
i = 0;
|
||||
while (headercounter) {
|
||||
usb_eth_data_buffer[i] = Usb_read_byte();
|
||||
bytecounter--;
|
||||
headercounter--;
|
||||
i++;
|
||||
}
|
||||
|
||||
//Order is LSB/MSB, so MSN is in usb_eth_data_buffer[1]
|
||||
//Bit 15 indicates command packet when set
|
||||
if (usb_eth_data_buffer[1] & 0x80) {
|
||||
//not a data payload
|
||||
datalength = 0;
|
||||
} else {
|
||||
//'0' indicates data packet
|
||||
//Length is lower 14 bits
|
||||
datalength = usb_eth_data_buffer[0] | ((usb_eth_data_buffer[1] & 0x3F) << 8);
|
||||
}
|
||||
|
||||
/* EEM Command Packet */
|
||||
if ((datalength == 0) && (fail == 0))
|
||||
{
|
||||
uint8_t command;
|
||||
uint16_t echoLength;
|
||||
|
||||
//Strip command off
|
||||
command = usb_eth_data_buffer[1] & 0x38;
|
||||
command = command >> 3;
|
||||
|
||||
//Decode command type
|
||||
switch (command)
|
||||
{
|
||||
/* Echo Request */
|
||||
case EEMCMD_ECHO:
|
||||
|
||||
//Get echo length
|
||||
echoLength = (usb_eth_data_buffer[1] & 0x07) << 8; //MSB
|
||||
echoLength |= usb_eth_data_buffer[0]; //LSB
|
||||
|
||||
//TODO: everything. oops.
|
||||
|
||||
break;
|
||||
|
||||
/* Everything else: Whatever. */
|
||||
case EEMCMD_ECHO_RESPONSE:
|
||||
case EEMCMD_SUSPEND_HINT:
|
||||
case EEMCMD_RESPONSE_HINT:
|
||||
case EEMCMD_RESPONSE_COMPLETE_HINT:
|
||||
case EEMCMD_TICKLE:
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
/* EEM Data Packet */
|
||||
else if (datalength && (fail == 0))
|
||||
{
|
||||
//Looks like we've got a live one
|
||||
#ifdef USB_ETH_HOOK_RX_START
|
||||
USB_ETH_HOOK_RX_START();
|
||||
#endif
|
||||
|
||||
uint16_t bytes_received = 0;
|
||||
uint16_t dataleft = datalength;
|
||||
U8 * buffer = uip_buf;
|
||||
|
||||
while(dataleft)
|
||||
{
|
||||
*buffer++ = Usb_read_byte();
|
||||
|
||||
dataleft--;
|
||||
bytecounter--;
|
||||
bytes_received++;
|
||||
|
||||
//Check if endpoint is done but we are expecting more data
|
||||
if ((bytecounter == 0) && (dataleft))
|
||||
{
|
||||
//ACK previous data
|
||||
Usb_ack_receive_out();
|
||||
|
||||
//Wait for new data
|
||||
while (!Is_usb_receive_out());
|
||||
|
||||
//Get new data
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
|
||||
//ZLP?
|
||||
if (bytecounter == 0)
|
||||
{
|
||||
//Incomplete!!
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Ack final data packet
|
||||
Usb_ack_receive_out();
|
||||
|
||||
#ifdef USB_ETH_HOOK_RX_END
|
||||
USB_ETH_HOOK_RX_END();
|
||||
#endif
|
||||
|
||||
//Packet has CRC, nobody wants that garbage
|
||||
datalength -= 4;
|
||||
|
||||
//Send data over RF or to local stack
|
||||
if(datalength <= USB_ETH_MTU) {
|
||||
USB_ETH_HOOK_HANDLE_INBOUND_PACKET(uip_buf,datalength);
|
||||
} else {
|
||||
USB_ETH_HOOK_RX_ERROR("Oversized packet");
|
||||
}
|
||||
} //if (datalength)
|
||||
} //if(Is_usb_receive_out() && (uip_len == 0))
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Send a single ethernet frame using EEM
|
||||
*/
|
||||
uint8_t eem_send(uint8_t * senddata, uint16_t sendlen, uint8_t led)
|
||||
{
|
||||
//Make a header
|
||||
uint8_t header[2];
|
||||
|
||||
//Fake CRC! Add 4 to length for CRC
|
||||
sendlen += 4;
|
||||
header[0] = (sendlen >> 8) & 0x3f;
|
||||
header[1] = sendlen & 0xff;
|
||||
|
||||
//We send CRC seperatly..
|
||||
sendlen -= 4;
|
||||
|
||||
//Send Data
|
||||
Usb_select_endpoint(TX_EP);
|
||||
//Usb_send_in();
|
||||
|
||||
//Wait for ready
|
||||
if(usb_endpoint_wait_for_write_enabled()!=0) {
|
||||
USB_ETH_HOOK_TX_ERROR("Timeout: write enabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USB_ETH_HOOK_TX_START
|
||||
USB_ETH_HOOK_TX_START();
|
||||
#endif
|
||||
|
||||
//Send header (LSB then MSB)
|
||||
Usb_write_byte(header[1]);
|
||||
Usb_write_byte(header[0]);
|
||||
|
||||
//Send packet
|
||||
while(sendlen) {
|
||||
Usb_write_byte(*senddata);
|
||||
senddata++;
|
||||
sendlen--;
|
||||
|
||||
//If endpoint is full, send data in
|
||||
//And then wait for data to transfer
|
||||
if (!Is_usb_write_enabled()) {
|
||||
Usb_send_in();
|
||||
|
||||
if(usb_endpoint_wait_for_write_enabled()!=0) {
|
||||
USB_ETH_HOOK_TX_ERROR("Timeout: write enabled");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//CRC = 0xdeadbeef
|
||||
//Linux kernel 2.6.31 needs 0xdeadbeef in wrong order,
|
||||
//like this: uint8_t crc[4] = {0xef, 0xbe, 0xad, 0xde};
|
||||
//This is fixed in 2.6.32 to the correct order (0xde, 0xad, 0xbe, 0xef)
|
||||
uint8_t crc[4] = {0xde, 0xad, 0xbe, 0xef};
|
||||
|
||||
sendlen = 4;
|
||||
uint8_t i = 0;
|
||||
|
||||
//Send fake CRC
|
||||
while(sendlen) {
|
||||
Usb_write_byte(crc[i]);
|
||||
i++;
|
||||
sendlen--;
|
||||
|
||||
//If endpoint is full, send data in
|
||||
//And then wait for data to transfer
|
||||
if (!Is_usb_write_enabled()) {
|
||||
Usb_send_in();
|
||||
if(usb_endpoint_wait_for_write_enabled()!=0) {
|
||||
USB_ETH_HOOK_TX_ERROR("Timeout: write enabled");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Send last data in - also handles sending a ZLP if needed
|
||||
Usb_send_in();
|
||||
|
||||
#ifdef USB_ETH_HOOK_TX_END
|
||||
USB_ETH_HOOK_TX_END();
|
||||
#endif
|
||||
|
||||
//Wait for ready
|
||||
if(usb_endpoint_wait_for_IN_ready()!=0) {
|
||||
USB_ETH_HOOK_TX_ERROR("Timeout: IN ready");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
12
cpu/avr/dev/usb/rndis/cdc_eem.h
Normal file
12
cpu/avr/dev/usb/rndis/cdc_eem.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
#ifndef __CDC_EEM_H__
|
||||
#define __CDC_EEM_H__
|
||||
|
||||
#include "contiki.h"
|
||||
#include <stdint.h>
|
||||
|
||||
extern void cdc_eem_process(void);
|
||||
extern uint8_t eem_send(uint8_t * senddata, uint16_t sendlen, uint8_t led);
|
||||
extern void cdc_eem_configure_endpoints();
|
||||
|
||||
#endif // __CDC_EEM_H__
|
|
@ -58,6 +58,7 @@ RNDIS Status Information:
|
|||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "radio.h"
|
||||
#include "contiki.h"
|
||||
#include "config.h"
|
||||
|
@ -65,12 +66,18 @@ RNDIS Status Information:
|
|||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "rndis/rndis_protocol.h"
|
||||
#include "rndis/rndis_task.h"
|
||||
#include "uip.h"
|
||||
#include "serial/uart_usb_lib.h"
|
||||
#include "sicslow_ethernet.h"
|
||||
#include <avr/pgmspace.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
//_____ D E F I N I T I O N ________________________________________________
|
||||
|
@ -80,14 +87,10 @@ RNDIS Status Information:
|
|||
extern PGM_VOID_P pbuffer;
|
||||
extern U8 data_to_transfer;
|
||||
|
||||
//NB: If you change the OID list be sure to update this!!!
|
||||
//#define OID_LIST_LENGTH 50
|
||||
#define OID_LIST_LENGTH 35
|
||||
|
||||
/**
|
||||
* \brief List of supported RNDIS OID's
|
||||
*/
|
||||
prog_uint32_t OIDSupportedList[OID_LIST_LENGTH] = {
|
||||
prog_uint32_t OIDSupportedList[] = {
|
||||
/* Required General */
|
||||
OID_GEN_SUPPORTED_LIST ,
|
||||
OID_GEN_HARDWARE_STATUS ,
|
||||
|
@ -128,7 +131,7 @@ prog_uint32_t OIDSupportedList[OID_LIST_LENGTH] = {
|
|||
|
||||
/*802.11 OID's not fully implemented yet. Hence do not say we
|
||||
support them */
|
||||
#ifdef DONOTEVERDEFINETHISORBADSTUFFHAPPENS
|
||||
#if USB_ETH_EMULATE_WIFI
|
||||
/* 802.11 OIDs */
|
||||
OID_802_11_BSSID ,
|
||||
OID_802_11_SSID ,
|
||||
|
@ -156,18 +159,17 @@ prog_uint32_t OIDSupportedList[OID_LIST_LENGTH] = {
|
|||
OID_PNP_ENABLE_WAKE_UP ,
|
||||
OID_PNP_ADD_WAKE_UP_PATTERN ,
|
||||
OID_PNP_REMOVE_WAKE_UP_PATTERN
|
||||
};
|
||||
|
||||
};
|
||||
#define OID_LIST_LENGTH sizeof(OIDSupportedList)/sizeof(*OIDSupportedList)
|
||||
|
||||
|
||||
rndis_state_t rndis_state;
|
||||
|
||||
rndis_stat_t rndis_stat;
|
||||
usb_eth_stat_t usb_eth_stat;
|
||||
|
||||
uint8_t schedule_interrupt = 0;
|
||||
|
||||
uint64_t rndis_ethernet_addr = 0x203478928323ULL;
|
||||
|
||||
//_____ D E C L A R A T I O N ______________________________________________
|
||||
|
||||
|
||||
|
@ -188,7 +190,7 @@ U8 data_to_send = 0x00;
|
|||
*
|
||||
* \return True on success, false on failure.
|
||||
*/
|
||||
uint8_t send_encapsulated_command(uint16_t wLength)
|
||||
uint8_t rndis_send_encapsulated_command(uint16_t wLength)
|
||||
{
|
||||
U8 i = 0;
|
||||
|
||||
|
@ -200,12 +202,6 @@ uint8_t send_encapsulated_command(uint16_t wLength)
|
|||
if (wLength > ENC_BUF_SIZE)
|
||||
wLength = ENC_BUF_SIZE;
|
||||
|
||||
//For debugging: this shouldn't happen, just checked it didn't
|
||||
//if (data_to_send) {
|
||||
// while(1);
|
||||
//}
|
||||
|
||||
|
||||
//Read in all the bytes...
|
||||
|
||||
uint8_t nb_counter;
|
||||
|
@ -256,9 +252,13 @@ uint8_t send_encapsulated_command(uint16_t wLength)
|
|||
m->MinorVersion = RNDIS_MAJOR_VERSION;
|
||||
m->Status = RNDIS_STATUS_SUCCESS;
|
||||
m->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
|
||||
#if USB_ETH_EMULATE_WIFI
|
||||
m->Medium = NDIS_MEDIUM_WIRELESS_LAN;
|
||||
#else
|
||||
m->Medium = RNDIS_MEDIUM_802_3;
|
||||
#endif // USB_ETH_EMULATE_WIFI
|
||||
m->MaxPacketsPerTransfer = 1;
|
||||
m->MaxTransferSize = 1338; /* Space for 1280 IP buffer, Ethernet Header,
|
||||
m->MaxTransferSize = USB_ETH_MTU + 58; /* Space for 1280 IP buffer, Ethernet Header,
|
||||
RNDIS messages */
|
||||
m->PacketAlignmentFactor = 3;
|
||||
m->AfListOffset = 0;
|
||||
|
@ -353,7 +353,9 @@ void rndis_send_interrupt(void)
|
|||
|
||||
uint32_t oid_packet_filter = 0x0000000;
|
||||
|
||||
#if USB_ETH_EMULATE_WIFI
|
||||
uint16_t panid = 0xbaad;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Function to handle a RNDIS "QUERY" command in the encapsulated_buffer
|
||||
|
@ -392,15 +394,20 @@ void rndis_query_process(void)
|
|||
|
||||
case OID_GEN_MEDIA_SUPPORTED:
|
||||
case OID_GEN_MEDIA_IN_USE:
|
||||
*INFBUF = NDIS_MEDIUM_802_3; /* NDIS_MEDIUM_WIRELESS_LAN instead? */
|
||||
case OID_GEN_PHYSICAL_MEDIUM:
|
||||
#if USB_ETH_EMULATE_WIFI
|
||||
*INFBUF = NDIS_MEDIUM_WIRELESS_LAN;
|
||||
#else
|
||||
*INFBUF = NDIS_MEDIUM_802_3;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
||||
*INFBUF = (uint32_t) 1280; //1280 //102; /* Assume 25 octet header on 15.4 */
|
||||
*INFBUF = (uint32_t) USB_ETH_MTU-14; //1280 //102; /* Assume 25 octet header on 15.4 */
|
||||
break;
|
||||
|
||||
case OID_GEN_LINK_SPEED:
|
||||
*INFBUF = (uint32_t) 100; /* in 100 bytes/sec units.. this is kinda a lie */
|
||||
*INFBUF = (uint32_t) 250000/100; /* in 100 bytes/sec units.. this is kinda a lie */
|
||||
break;
|
||||
|
||||
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
||||
|
@ -422,57 +429,35 @@ void rndis_query_process(void)
|
|||
break;
|
||||
|
||||
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
||||
*INFBUF = (uint32_t) 1300; //127;
|
||||
*INFBUF = (uint32_t) USB_ETH_MTU; //127;
|
||||
break;
|
||||
|
||||
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||||
*INFBUF = NDIS_MEDIA_STATE_CONNECTED;
|
||||
*INFBUF = usb_eth_is_active?NDIS_MEDIA_STATE_CONNECTED:NDIS_MEDIA_STATE_DISCONNECTED;
|
||||
break;
|
||||
|
||||
case OID_GEN_VENDOR_DRIVER_VERSION:
|
||||
*INFBUF = 0x00001000;
|
||||
break;
|
||||
|
||||
case OID_GEN_PHYSICAL_MEDIUM:
|
||||
*INFBUF = NDIS_MEDIUM_802_3; /*NDIS_MEDIUM_WIRELESS_LAN;*/
|
||||
break;
|
||||
|
||||
case OID_GEN_CURRENT_LOOKAHEAD:
|
||||
*INFBUF = (uint32_t) 1280; //102;
|
||||
*INFBUF = (uint32_t) USB_ETH_MTU-14; //102;
|
||||
|
||||
// case OID_GEN_RNDIS_CONFIG_PARAMETER:
|
||||
// break;
|
||||
|
||||
/******* 802.3 (Ethernet) *******/
|
||||
|
||||
/*The address of the NIC encoded in the hardware.*/
|
||||
case OID_802_3_PERMANENT_ADDRESS:
|
||||
|
||||
//Clear unused bytes
|
||||
*(INFBUF + 1) = 0;
|
||||
|
||||
//Set address
|
||||
*((uint8_t *)INFBUF + 0) = *(((uint8_t * ) &rndis_ethernet_addr) + 5);
|
||||
*((uint8_t *)INFBUF + 1) = *(((uint8_t * ) &rndis_ethernet_addr) + 4);
|
||||
*((uint8_t *)INFBUF + 2) = *(((uint8_t * ) &rndis_ethernet_addr) + 3);
|
||||
*((uint8_t *)INFBUF + 3) = *(((uint8_t * ) &rndis_ethernet_addr) + 2);
|
||||
*((uint8_t *)INFBUF + 4) = *(((uint8_t * ) &rndis_ethernet_addr) + 1);
|
||||
*((uint8_t *)INFBUF + 5) = *(((uint8_t * ) &rndis_ethernet_addr) + 0);
|
||||
|
||||
|
||||
/*4+2 = 6 Bytes of eth address */
|
||||
c->InformationBufferLength += 2;
|
||||
break;
|
||||
|
||||
/*The address the NIC is currently using.*/
|
||||
case OID_802_3_CURRENT_ADDRESS:
|
||||
|
||||
//Clear unused bytes
|
||||
*(INFBUF + 1) = 0;
|
||||
|
||||
//Set address
|
||||
*((uint8_t *)INFBUF + 0) = *(((uint8_t * ) &rndis_ethernet_addr) + 5);
|
||||
*((uint8_t *)INFBUF + 1) = *(((uint8_t * ) &rndis_ethernet_addr) + 4);
|
||||
*((uint8_t *)INFBUF + 2) = *(((uint8_t * ) &rndis_ethernet_addr) + 3);
|
||||
*((uint8_t *)INFBUF + 3) = *(((uint8_t * ) &rndis_ethernet_addr) + 2);
|
||||
*((uint8_t *)INFBUF + 4) = *(((uint8_t * ) &rndis_ethernet_addr) + 1);
|
||||
*((uint8_t *)INFBUF + 5) = *(((uint8_t * ) &rndis_ethernet_addr) + 0);
|
||||
//get address
|
||||
usb_eth_get_mac_address((uint8_t*)INFBUF);
|
||||
|
||||
/*4+2 = 6 Bytes of eth address */
|
||||
c->InformationBufferLength += 2;
|
||||
|
@ -495,20 +480,14 @@ void rndis_query_process(void)
|
|||
|
||||
/* Frames received with alignment error */
|
||||
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
||||
*INFBUF = 0;
|
||||
break;
|
||||
|
||||
/* Frames transmitted with one collision */
|
||||
case OID_802_3_XMIT_ONE_COLLISION:
|
||||
*INFBUF = 0;
|
||||
break;
|
||||
|
||||
/* Frames transmitted with more than one collision */
|
||||
case OID_802_3_XMIT_MORE_COLLISIONS:
|
||||
*INFBUF = 0;
|
||||
break;
|
||||
|
||||
|
||||
#if USB_ETH_EMULATE_WIFI
|
||||
/*** 802.11 OIDs ***/
|
||||
case OID_802_11_BSSID:
|
||||
*INFBUF = (uint32_t)panid;
|
||||
|
@ -543,27 +522,28 @@ void rndis_query_process(void)
|
|||
case OID_802_11_WEP_STATUS:
|
||||
case OID_802_11_AUTHENTICATION_MODE:
|
||||
break;
|
||||
#endif //USB_ETH_EMULATE_WIFI
|
||||
|
||||
/*** Statistical ***/
|
||||
|
||||
/* Frames transmitted without errors */
|
||||
case OID_GEN_XMIT_OK:
|
||||
*INFBUF = rndis_stat.txok;
|
||||
*INFBUF = usb_eth_stat.txok;
|
||||
break;
|
||||
|
||||
/* Frames received without errors */
|
||||
case OID_GEN_RCV_OK:
|
||||
*INFBUF = rndis_stat.rxok;
|
||||
*INFBUF = usb_eth_stat.rxok;
|
||||
break;
|
||||
|
||||
/* Frames received with errors */
|
||||
case OID_GEN_RCV_ERROR:
|
||||
*INFBUF = rndis_stat.rxbad;
|
||||
*INFBUF = usb_eth_stat.rxbad;
|
||||
break;
|
||||
|
||||
/* Frames transmitted with errors */
|
||||
case OID_GEN_XMIT_ERROR:
|
||||
*INFBUF = rndis_stat.txbad;
|
||||
*INFBUF = usb_eth_stat.txbad;
|
||||
break;
|
||||
|
||||
/* Frames dropped due to lack of buffer space */
|
||||
|
@ -617,9 +597,21 @@ void rndis_query_process(void)
|
|||
#define CFGBUF ((rndis_config_parameter_t *) INFBUF)
|
||||
#define PARMNAME ((uint8_t *)CFGBUF + CFGBUF->ParameterNameOffset)
|
||||
#define PARMVALUE ((uint8_t *)CFGBUF + CFGBUF->ParameterValueOffset)
|
||||
|
||||
#define PARMVALUELENGTH CFGBUF->ParameterValueLength
|
||||
#define PARM_NAME_LENGTH 25 /* Maximum parameter name length */
|
||||
|
||||
bool
|
||||
rndis_handle_config_parm(const char* parmname,const uint8_t* parmvalue,size_t parmlength) {
|
||||
if (strncmp_P(parmname, PSTR("rawmode"), 7) == 0) {
|
||||
if (parmvalue[0] == '0') {
|
||||
usbstick_mode.raw = 0;
|
||||
} else {
|
||||
usbstick_mode.raw = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Function to deal with a RNDIS "SET" command present in the
|
||||
* encapsulated_buffer
|
||||
|
@ -664,13 +656,7 @@ void rndis_set_process(void)
|
|||
Parameter type: single octet
|
||||
Parameter values: '0' = disabled, '1' = enabled
|
||||
*/
|
||||
if (strncmp_P(parmname, PSTR("rawmode"), 7) == 0) {
|
||||
if (*PARMVALUE == '0') {
|
||||
usbstick_mode.raw = 0;
|
||||
} else {
|
||||
usbstick_mode.raw = 1;
|
||||
}
|
||||
}
|
||||
rndis_handle_config_parm(parmname,PARMVALUE,PARMVALUELENGTH);
|
||||
|
||||
|
||||
break;
|
||||
|
@ -700,6 +686,7 @@ void rndis_set_process(void)
|
|||
case OID_802_3_MULTICAST_LIST:
|
||||
break;
|
||||
|
||||
#if USB_ETH_EMULATE_WIFI
|
||||
/* Mandatory 802.11 OIDs */
|
||||
case OID_802_11_BSSID:
|
||||
panid = *INFBUF;
|
||||
|
@ -708,6 +695,7 @@ void rndis_set_process(void)
|
|||
case OID_802_11_SSID:
|
||||
break;
|
||||
//TODO: rest of 802.11
|
||||
#endif // USB_ETH_EMULATE_WIFI
|
||||
|
||||
/* Power Managment: fails for now */
|
||||
case OID_PNP_ADD_WAKE_UP_PATTERN:
|
||||
|
@ -743,7 +731,7 @@ void rndis_set_process(void)
|
|||
* the "SEND ENCAPSULATED COMMAND" message, which will trigger
|
||||
* and interrupt on the host so it knows data is ready.
|
||||
*/
|
||||
uint8_t get_encapsulated_command(void)
|
||||
uint8_t rndis_get_encapsulated_command(void)
|
||||
{
|
||||
U8 nb_byte, zlp, i;
|
||||
|
||||
|
@ -828,6 +816,261 @@ uint8_t rndis_send_status(rndis_Status_t stat)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void rndis_configure_endpoints() {
|
||||
usb_configure_endpoint(INT_EP, \
|
||||
TYPE_INTERRUPT, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_8, \
|
||||
ONE_BANK, \
|
||||
NYET_ENABLED);
|
||||
usb_configure_endpoint(TX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_64, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
|
||||
usb_configure_endpoint(RX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_OUT, \
|
||||
SIZE_64, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
Usb_reset_endpoint(INT_EP);
|
||||
Usb_reset_endpoint(TX_EP);
|
||||
Usb_reset_endpoint(RX_EP);
|
||||
}
|
||||
|
||||
|
||||
extern char usb_busy;
|
||||
extern uint8_t usb_eth_data_buffer[64];
|
||||
#define PBUF ((rndis_data_packet_t *) usb_eth_data_buffer)
|
||||
|
||||
|
||||
uint8_t rndis_process(void)
|
||||
{
|
||||
uint8_t bytecounter, headercounter;
|
||||
uint16_t i, dataoffset;
|
||||
|
||||
if(rndis_state != rndis_data_initialized) { //Enumeration processs OK ?
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USB_ETH_HOOK_INIT
|
||||
static uint8_t doInit = 1;
|
||||
if (doInit) {
|
||||
USB_ETH_HOOK_INIT();
|
||||
doInit = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
//Connected!
|
||||
Led0_on();
|
||||
|
||||
Usb_select_endpoint(RX_EP);
|
||||
|
||||
//If we have data and a free buffer
|
||||
if(Is_usb_receive_out() && (uip_len == 0)) {
|
||||
|
||||
//Read how much (endpoint only stores up to 64 bytes anyway)
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
|
||||
//Try and read the header in
|
||||
headercounter = sizeof(rndis_data_packet_t);
|
||||
|
||||
uint8_t fail = 0;
|
||||
|
||||
//Hmm.. what's going on here
|
||||
if (bytecounter < headercounter) {
|
||||
Usb_ack_receive_out();
|
||||
fail = 1;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (headercounter) {
|
||||
usb_eth_data_buffer[i] = Usb_read_byte();
|
||||
bytecounter--;
|
||||
headercounter--;
|
||||
i++;
|
||||
}
|
||||
|
||||
//This is no good. Probably lost syncronization... just drop it for now
|
||||
if(PBUF->MessageType != REMOTE_NDIS_PACKET_MSG) {
|
||||
Usb_ack_receive_out();
|
||||
fail = 1;
|
||||
}
|
||||
|
||||
//802.3 does not have OOB data, and we don't care about per-packet data
|
||||
//so that just leave regular packet data...
|
||||
if (PBUF->DataLength && (fail == 0)) {
|
||||
|
||||
//Looks like we've got a live one
|
||||
#ifdef USB_ETH_HOOK_RX_START
|
||||
USB_ETH_HOOK_RX_START();
|
||||
#endif
|
||||
|
||||
//Get offset
|
||||
dataoffset = PBUF->DataOffset;
|
||||
|
||||
//Make it offset from start of message, not DataOffset field
|
||||
dataoffset += (sizeof(rndis_MessageType_t) + sizeof(rndis_MessageLength_t));
|
||||
|
||||
//Subtract what we already took
|
||||
dataoffset -= sizeof(rndis_data_packet_t);
|
||||
|
||||
//Clear this flag
|
||||
Usb_ack_nak_out();
|
||||
|
||||
//Read to the start of data
|
||||
while(dataoffset) {
|
||||
Usb_read_byte();
|
||||
dataoffset--;
|
||||
bytecounter--;
|
||||
|
||||
//If endpoint is done
|
||||
if (bytecounter == 0) {
|
||||
|
||||
Usb_ack_receive_out();
|
||||
|
||||
|
||||
//Wait for new data
|
||||
while (!Is_usb_receive_out() && (!Is_usb_receive_nak_out()));
|
||||
|
||||
//Check for NAK
|
||||
// TODO: darco: What in the world is this for?
|
||||
if (Is_usb_receive_nak_out()) {
|
||||
Usb_ack_nak_out();
|
||||
break;
|
||||
}
|
||||
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
|
||||
//ZLP?
|
||||
if (bytecounter == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Read the data itself in
|
||||
uint8_t * uipdata = uip_buf;
|
||||
uint16_t datalen = PBUF->DataLength;
|
||||
|
||||
while(datalen) {
|
||||
*uipdata++ = Usb_read_byte();
|
||||
datalen--;
|
||||
bytecounter--;
|
||||
|
||||
//If endpoint is done
|
||||
if (bytecounter == 0) {
|
||||
//Might be everything we need!
|
||||
if (datalen) {
|
||||
Usb_ack_receive_out();
|
||||
//Wait for new data
|
||||
if(usb_endpoint_wait_for_receive_out()!=0) {
|
||||
USB_ETH_HOOK_RX_ERROR("Timeout: receive out");
|
||||
goto bail;
|
||||
}
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Ack final data packet
|
||||
Usb_ack_receive_out();
|
||||
|
||||
#ifdef USB_ETH_HOOK_RX_END
|
||||
USB_ETH_HOOK_RX_END();
|
||||
#endif
|
||||
|
||||
//Send data over RF or to local stack
|
||||
if(PBUF->DataLength <= USB_ETH_MTU) {
|
||||
USB_ETH_HOOK_HANDLE_INBOUND_PACKET(uip_buf,PBUF->DataLength);
|
||||
} else {
|
||||
USB_ETH_HOOK_RX_ERROR("Oversized packet");
|
||||
}
|
||||
} //if (PBUF->DataLength)
|
||||
}
|
||||
bail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Send data over RNDIS interface, data is in uipbuf and length is uiplen
|
||||
*/
|
||||
uint8_t rndis_send(uint8_t * senddata, uint16_t sendlen, uint8_t led)
|
||||
{
|
||||
|
||||
|
||||
uint16_t i;
|
||||
|
||||
//Setup Header
|
||||
PBUF->MessageType = REMOTE_NDIS_PACKET_MSG;
|
||||
PBUF->DataOffset = sizeof(rndis_data_packet_t) - sizeof(rndis_MessageType_t) - sizeof(rndis_MessageLength_t);
|
||||
PBUF->DataLength = sendlen;
|
||||
PBUF->OOBDataLength = 0;
|
||||
PBUF->OOBDataOffset = 0;
|
||||
PBUF->NumOOBDataElements = 0;
|
||||
PBUF->PerPacketInfoOffset = 0;
|
||||
PBUF->PerPacketInfoLength = 0;
|
||||
PBUF->DeviceVcHandle = 0;
|
||||
PBUF->Reserved = 0;
|
||||
PBUF->MessageLength = sizeof(rndis_data_packet_t) + PBUF->DataLength;
|
||||
|
||||
//Send Data
|
||||
Usb_select_endpoint(TX_EP);
|
||||
Usb_send_in();
|
||||
|
||||
//Wait for ready
|
||||
if(usb_endpoint_wait_for_write_enabled()!=0) {
|
||||
USB_ETH_HOOK_TX_ERROR("Timeout: write enabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USB_ETH_HOOK_TX_START
|
||||
USB_ETH_HOOK_TX_START();
|
||||
#endif
|
||||
|
||||
//Setup first part of transfer...
|
||||
for(i = 0; i < sizeof(rndis_data_packet_t); i++) {
|
||||
Usb_write_byte(usb_eth_data_buffer[i]);
|
||||
}
|
||||
|
||||
//Send packet
|
||||
while(sendlen) {
|
||||
Usb_write_byte(*senddata);
|
||||
senddata++;
|
||||
sendlen--;
|
||||
|
||||
//If endpoint is full, send data in
|
||||
//And then wait for data to transfer
|
||||
if (!Is_usb_write_enabled()) {
|
||||
Usb_send_in();
|
||||
|
||||
if(usb_endpoint_wait_for_write_enabled()!=0) {
|
||||
USB_ETH_HOOK_TX_ERROR("Timeout: write enabled");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Usb_send_in();
|
||||
|
||||
#ifdef USB_ETH_HOOK_TX_END
|
||||
USB_ETH_HOOK_TX_END();
|
||||
#endif
|
||||
|
||||
//Wait for ready
|
||||
if(usb_endpoint_wait_for_IN_ready()!=0) {
|
||||
USB_ETH_HOOK_TX_ERROR("Timeout: IN ready");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/****************** Radio Interface ****************/
|
||||
|
||||
|
@ -837,15 +1080,11 @@ uint8_t rndis_send_status(rndis_Status_t stat)
|
|||
*/
|
||||
void rndis_packetFilter(uint32_t newfilter)
|
||||
{
|
||||
#if !RF230BB
|
||||
if (newfilter & NDIS_PACKET_TYPE_PROMISCUOUS) {
|
||||
rxMode = RX_ON;
|
||||
radio_set_trx_state(RX_ON);
|
||||
USB_ETH_HOOK_SET_PROMISCIOUS_MODE(true);
|
||||
} else {
|
||||
rxMode = RX_AACK_ON;
|
||||
radio_set_trx_state(RX_AACK_ON);
|
||||
USB_ETH_HOOK_SET_PROMISCIOUS_MODE(false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -303,22 +303,23 @@ typedef struct{
|
|||
uint32_t rxok;
|
||||
uint32_t txbad;
|
||||
uint32_t rxbad;
|
||||
} rndis_stat_t;
|
||||
} usb_eth_stat_t;
|
||||
|
||||
extern rndis_stat_t rndis_stat;
|
||||
extern usb_eth_stat_t usb_eth_stat;
|
||||
|
||||
extern rndis_state_t rndis_state;
|
||||
|
||||
extern uint8_t schedule_interrupt;
|
||||
|
||||
extern uint64_t rndis_ethernet_addr;
|
||||
|
||||
uint8_t send_encapsulated_command(uint16_t wLength);
|
||||
uint8_t get_encapsulated_command(void);
|
||||
uint8_t rndis_send_encapsulated_command(uint16_t wLength);
|
||||
uint8_t rndis_get_encapsulated_command(void);
|
||||
void rndis_send_interrupt(void);
|
||||
void rndis_query_process(void);
|
||||
void rndis_set_process(void);
|
||||
uint8_t rndis_send_status(rndis_Status_t stat);
|
||||
uint8_t rndis_process(void);
|
||||
uint8_t rndis_send(uint8_t * senddata, uint16_t sendlen, uint8_t led);
|
||||
extern void rndis_configure_endpoints();
|
||||
|
||||
#endif //_RNDIS_H
|
||||
|
||||
|
|
|
@ -59,6 +59,9 @@
|
|||
#include <avr/pgmspace.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#include "rndis/cdc_ecm.h"
|
||||
#include "rndis/cdc_eem.h"
|
||||
|
||||
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
#define PRINTF printf
|
||||
#define PRINTF_P printf_P
|
||||
|
@ -66,12 +69,6 @@
|
|||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
#define EEMCMD_ECHO 0x00 ///bmEEMCmd Echo
|
||||
#define EEMCMD_ECHO_RESPONSE 0x01 ///bmEEMCmd Echo Response
|
||||
#define EEMCMD_SUSPEND_HINT 0x02 ///bmEEMCmd Suspend Hint
|
||||
#define EEMCMD_RESPONSE_HINT 0x03 ///bmEEMCmd Response Hint
|
||||
#define EEMCMD_RESPONSE_COMPLETE_HINT 0x04 ///bmEEMCmd Response Complete Hint
|
||||
#define EEMCMD_TICKLE 0x05 ///bmEEMCmd Tickle
|
||||
|
||||
|
||||
|
||||
|
@ -84,436 +81,210 @@
|
|||
#define RNDIS_TIMEOUT_DETACH 900
|
||||
#define RNDIS_TIMEOUT_ATTACH 1000
|
||||
|
||||
#define PBUF ((rndis_data_packet_t *) data_buffer)
|
||||
#define PBUF ((rndis_data_packet_t *) usb_eth_data_buffer)
|
||||
|
||||
//! Temp data buffer when adding RNDIS headers
|
||||
uint8_t usb_eth_data_buffer[64];
|
||||
|
||||
uint64_t usb_ethernet_addr = 0x010000000002ULL;
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
uint8_t eem_send(uint8_t * senddata, uint16_t sendlen, uint8_t led);
|
||||
uint8_t rndis_send(uint8_t * senddata, uint16_t sendlen, uint8_t led);
|
||||
|
||||
//! Timers for LEDs
|
||||
uint8_t led1_timer, led2_timer;
|
||||
|
||||
//! Temp data buffer when adding RNDIS headers
|
||||
uint8_t data_buffer[64];
|
||||
|
||||
//! Usb is busy with RNDIS
|
||||
char usb_busy = 0;
|
||||
uint8_t usb_eth_is_active = 1;
|
||||
|
||||
|
||||
static struct etimer et;
|
||||
static struct timer flood_timer;
|
||||
uint8_t usb_eth_packet_is_available() {
|
||||
Usb_select_endpoint(RX_EP);
|
||||
return Is_usb_read_enabled();
|
||||
}
|
||||
|
||||
static uint8_t doInit = 1;
|
||||
|
||||
extern uint8_t fingerPresent;
|
||||
uint8_t usb_eth_ready_for_next_packet() {
|
||||
#ifdef USB_ETH_HOOK_IS_READY_FOR_INBOUND_PACKET
|
||||
return USB_ETH_HOOK_IS_READY_FOR_INBOUND_PACKET();
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
PROCESS(rndis_process, "RNDIS process");
|
||||
return 1;
|
||||
}
|
||||
|
||||
void rxtx_led_update(void)
|
||||
{
|
||||
// turn off LED's if necessary
|
||||
if (led1_timer) {
|
||||
led1_timer--;
|
||||
if(led1_timer&(1<<2))
|
||||
Led1_on();
|
||||
else
|
||||
Led1_off();
|
||||
}
|
||||
else
|
||||
Led1_off();
|
||||
|
||||
if (led2_timer) {
|
||||
led2_timer--;
|
||||
if(led2_timer&(1<<2))
|
||||
Led2_on();
|
||||
else
|
||||
Led2_off();
|
||||
}
|
||||
else
|
||||
Led2_off();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief This will enable the RX_START LED for a period
|
||||
*/
|
||||
void rx_start_led(void)
|
||||
{
|
||||
led1_timer|=(1<<3);
|
||||
if(((led1_timer-1)&(1<<2)))
|
||||
Led1_on();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief This will enable the TRX_END LED for a period
|
||||
*/
|
||||
void tx_end_led(void)
|
||||
{
|
||||
led2_timer|=(1<<3);
|
||||
if(((led2_timer-1)&(1<<2)))
|
||||
Led1_on();
|
||||
}
|
||||
|
||||
#if USB_ETH_CONF_MASS_STORAGE_FALLBACK
|
||||
static void
|
||||
usb_eth_setup_timeout_fallback_check() {
|
||||
extern uint8_t fingerPresent;
|
||||
/* Device is Enumerated but RNDIS not loading. We might
|
||||
have a system that does not support IAD (winXP). If so
|
||||
count the timeout then switch to just network interface. */
|
||||
static uint16_t iad_fail_timeout, rndis_fail_timeout;
|
||||
if (usb_mode == rndis_debug) {
|
||||
//If we have timed out, detach
|
||||
if (iad_fail_timeout == IAD_TIMEOUT_DETACH) {
|
||||
|
||||
//Failed - BUT we are using "reverse logic", hence we force device
|
||||
//into this mode. This is used to allow Windows Vista have time to
|
||||
//install the drivers
|
||||
if (fingerPresent && (rndis_state != rndis_data_initialized) && Is_device_enumerated() ) {
|
||||
iad_fail_timeout = 0;
|
||||
} else {
|
||||
stdout = NULL;
|
||||
Usb_detach();
|
||||
doInit = 1; //Also mark system as needing intilizing
|
||||
}
|
||||
|
||||
//Then wait a few before re-attaching
|
||||
} else if (iad_fail_timeout == IAD_TIMEOUT_ATTACH) {
|
||||
|
||||
if (fingerPresent) {
|
||||
usb_mode = mass_storage;
|
||||
} else {
|
||||
usb_mode = rndis_only;
|
||||
}
|
||||
Usb_attach();
|
||||
}
|
||||
|
||||
//Increment timeout when device is not initializing, OR we have already detached,
|
||||
//OR the user had their finger on the device, indicating a reverse of logic
|
||||
if ( ( (rndis_state != rndis_data_initialized) && Is_device_enumerated() ) ||
|
||||
(iad_fail_timeout > IAD_TIMEOUT_DETACH) ||
|
||||
(fingerPresent) ) {
|
||||
iad_fail_timeout++;
|
||||
} else {
|
||||
iad_fail_timeout = 0;
|
||||
}
|
||||
} //usb_mode == rndis_debug
|
||||
|
||||
|
||||
/* Device is Enumerated but RNDIS STIL not loading. We just
|
||||
have RNDIS interface, so obviously no drivers on target.
|
||||
Just go ahead and mount ourselves as mass storage... */
|
||||
if (usb_mode == rndis_only) {
|
||||
//If we have timed out, detach
|
||||
if (rndis_fail_timeout == RNDIS_TIMEOUT_DETACH) {
|
||||
Usb_detach();
|
||||
//Then wait a few before re-attaching
|
||||
} else if (rndis_fail_timeout == RNDIS_TIMEOUT_ATTACH) {
|
||||
usb_mode = mass_storage;
|
||||
Usb_attach();
|
||||
}
|
||||
|
||||
//Increment timeout when device is not initializing, OR we are already
|
||||
//counting to detach
|
||||
if ( ( (rndis_state != rndis_data_initialized)) ||
|
||||
(rndis_fail_timeout > RNDIS_TIMEOUT_DETACH) ) {
|
||||
rndis_fail_timeout++;
|
||||
} else {
|
||||
rndis_fail_timeout = 0;
|
||||
}
|
||||
}//usb_mode == rnids_only
|
||||
}
|
||||
#endif
|
||||
|
||||
PROCESS(usb_eth_process, "USB Ethernet process");
|
||||
|
||||
/**
|
||||
* \brief RNDIS Process
|
||||
*
|
||||
* This is the link between USB and the "good stuff". In this routine data
|
||||
* is received and processed by RNDIS
|
||||
* is received and processed by RNDIS, CDC-ECM, or CDC-EEM
|
||||
*/
|
||||
PROCESS_THREAD(rndis_process, ev, data_proc)
|
||||
PROCESS_THREAD(usb_eth_process, ev, data_proc)
|
||||
{
|
||||
static struct etimer et;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
uint8_t bytecounter, headercounter;
|
||||
uint16_t i, dataoffset;
|
||||
clock_time_t timediff;
|
||||
clock_time_t thetime;
|
||||
|
||||
while(1) {
|
||||
rxtx_led_update();
|
||||
|
||||
// turn off LED's if necessary
|
||||
if (led1_timer) led1_timer--;
|
||||
else Led1_off();
|
||||
if (led2_timer) led2_timer--;
|
||||
else Led2_off();
|
||||
|
||||
/* Device is Enumerated but RNDIS not loading. We might
|
||||
have a system that does not support IAD (winXP). If so
|
||||
count the timeout then switch to just network interface. */
|
||||
#if 0
|
||||
static uint16_t iad_fail_timeout, rndis_fail_timeout;
|
||||
if (usb_mode == rndis_debug) {
|
||||
//If we have timed out, detach
|
||||
if (iad_fail_timeout == IAD_TIMEOUT_DETACH) {
|
||||
|
||||
//Failed - BUT we are using "reverse logic", hence we force device
|
||||
//into this mode. This is used to allow Windows Vista have time to
|
||||
//install the drivers
|
||||
if (fingerPresent && (rndis_state != rndis_data_initialized) && Is_device_enumerated() ) {
|
||||
iad_fail_timeout = 0;
|
||||
} else {
|
||||
stdout = NULL;
|
||||
Usb_detach();
|
||||
doInit = 1; //Also mark system as needing intilizing
|
||||
}
|
||||
|
||||
//Then wait a few before re-attaching
|
||||
} else if (iad_fail_timeout == IAD_TIMEOUT_ATTACH) {
|
||||
|
||||
if (fingerPresent) {
|
||||
usb_mode = mass_storage;
|
||||
} else {
|
||||
usb_mode = rndis_only;
|
||||
}
|
||||
Usb_attach();
|
||||
}
|
||||
|
||||
//Increment timeout when device is not initializing, OR we have already detached,
|
||||
//OR the user had their finger on the device, indicating a reverse of logic
|
||||
if ( ( (rndis_state != rndis_data_initialized) && Is_device_enumerated() ) ||
|
||||
(iad_fail_timeout > IAD_TIMEOUT_DETACH) ||
|
||||
(fingerPresent) ) {
|
||||
iad_fail_timeout++;
|
||||
} else {
|
||||
iad_fail_timeout = 0;
|
||||
}
|
||||
} //usb_mode == rndis_debug
|
||||
|
||||
|
||||
/* Device is Enumerated but RNDIS STIL not loading. We just
|
||||
have RNDIS interface, so obviously no drivers on target.
|
||||
Just go ahead and mount ourselves as mass storage... */
|
||||
if (usb_mode == rndis_only) {
|
||||
//If we have timed out, detach
|
||||
if (rndis_fail_timeout == RNDIS_TIMEOUT_DETACH) {
|
||||
Usb_detach();
|
||||
//Then wait a few before re-attaching
|
||||
} else if (rndis_fail_timeout == RNDIS_TIMEOUT_ATTACH) {
|
||||
usb_mode = mass_storage;
|
||||
Usb_attach();
|
||||
}
|
||||
|
||||
//Increment timeout when device is not initializing, OR we are already
|
||||
//counting to detach
|
||||
if ( ( (rndis_state != rndis_data_initialized)) ||
|
||||
(rndis_fail_timeout > RNDIS_TIMEOUT_DETACH) ) {
|
||||
rndis_fail_timeout++;
|
||||
} else {
|
||||
rndis_fail_timeout = 0;
|
||||
}
|
||||
}//usb_mode == rnids_only
|
||||
#if USB_ETH_CONF_MASS_STORAGE_FALLBACK
|
||||
usb_eth_setup_timeout_fallback_check();
|
||||
#endif
|
||||
|
||||
|
||||
if(rndis_state == rndis_data_initialized) //Enumeration processs OK ?
|
||||
{
|
||||
if (doInit) {
|
||||
//start flood timer
|
||||
timer_set(&flood_timer, CLOCK_SECOND / 5);
|
||||
|
||||
mac_ethernetSetup();
|
||||
doInit = 0;
|
||||
}
|
||||
|
||||
//Connected!
|
||||
Led0_on();
|
||||
|
||||
Usb_select_endpoint(RX_EP);
|
||||
|
||||
//If we have data and a free buffer
|
||||
if(Is_usb_receive_out() && (uip_len == 0)) {
|
||||
|
||||
//TODO: Fix this some better way
|
||||
//If you need a delay in RNDIS to slow down super-fast sending, insert it here
|
||||
//Also mark the USB as "in use"
|
||||
|
||||
//This is done as "flood control" by only allowing one IP packet per time limit
|
||||
thetime = clock_time();
|
||||
|
||||
timediff = thetime - flood_timer.start;
|
||||
|
||||
//Oops, timer wrapped! Just ignore it for now
|
||||
if (thetime < flood_timer.start) {
|
||||
timediff = flood_timer.interval;
|
||||
}
|
||||
|
||||
|
||||
//If timer not yet expired
|
||||
//if (timediff < flood_timer.interval) {
|
||||
if (!timer_expired(&flood_timer)) {
|
||||
//Wait until timer expiers
|
||||
usb_busy = 1;
|
||||
etimer_set(&et, flood_timer.interval - timediff);
|
||||
//Try commenting out the next line if Jackdaw stops RF transmission in Windows after a 5 minute idle period - dak
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
|
||||
|
||||
//Reselect endpoint in case we lost it
|
||||
Usb_select_endpoint(RX_EP);
|
||||
usb_busy = 0;
|
||||
}
|
||||
|
||||
|
||||
//Restart flood timer
|
||||
timer_restart(&flood_timer);
|
||||
|
||||
//Read how much (endpoint only stores up to 64 bytes anyway)
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
|
||||
//Try and read the header in
|
||||
headercounter = sizeof(rndis_data_packet_t);
|
||||
|
||||
uint8_t fail = 0;
|
||||
|
||||
//Hmm.. what's going on here
|
||||
if (bytecounter < headercounter) {
|
||||
Usb_ack_receive_out();
|
||||
fail = 1;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (headercounter) {
|
||||
data_buffer[i] = Usb_read_byte();
|
||||
bytecounter--;
|
||||
headercounter--;
|
||||
i++;
|
||||
}
|
||||
|
||||
//This is no good. Probably lost syncronization... just drop it for now
|
||||
if(PBUF->MessageType != REMOTE_NDIS_PACKET_MSG) {
|
||||
Usb_ack_receive_out();
|
||||
fail = 1;
|
||||
}
|
||||
|
||||
//802.3 does not have OOB data, and we don't care about per-packet data
|
||||
//so that just leave regular packet data...
|
||||
if (PBUF->DataLength && (fail == 0)) {
|
||||
|
||||
//Looks like we've got a live one
|
||||
rx_start_led();
|
||||
|
||||
|
||||
//Get offset
|
||||
dataoffset = PBUF->DataOffset;
|
||||
|
||||
//Make it offset from start of message, not DataOffset field
|
||||
dataoffset += (sizeof(rndis_MessageType_t) + sizeof(rndis_MessageLength_t));
|
||||
|
||||
//Subtract what we already took
|
||||
dataoffset -= sizeof(rndis_data_packet_t);
|
||||
|
||||
//Clear this flag
|
||||
Usb_ack_nak_out();
|
||||
|
||||
//Read to the start of data
|
||||
while(dataoffset) {
|
||||
Usb_read_byte();
|
||||
dataoffset--;
|
||||
bytecounter--;
|
||||
|
||||
//If endpoint is done
|
||||
if (bytecounter == 0) {
|
||||
|
||||
Usb_ack_receive_out();
|
||||
|
||||
|
||||
//Wait for new data
|
||||
while (!Is_usb_receive_out() && (!Is_usb_receive_nak_out()));
|
||||
|
||||
//Check for NAK
|
||||
if (Is_usb_receive_nak_out()) {
|
||||
Usb_ack_nak_out();
|
||||
break;
|
||||
}
|
||||
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
|
||||
//ZLP?
|
||||
if (bytecounter == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Read the data itself in
|
||||
uint8_t * uipdata = uip_buf;
|
||||
uint16_t datalen = PBUF->DataLength;
|
||||
|
||||
while(datalen) {
|
||||
*uipdata++ = Usb_read_byte();
|
||||
datalen--;
|
||||
bytecounter--;
|
||||
|
||||
//If endpoint is done
|
||||
if (bytecounter == 0) {
|
||||
//Might be everything we need!
|
||||
if (datalen) {
|
||||
Usb_ack_receive_out();
|
||||
//Wait for new data
|
||||
while (!Is_usb_receive_out());
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Ack final data packet
|
||||
Usb_ack_receive_out();
|
||||
|
||||
//Send data over RF or to local stack
|
||||
uip_len = PBUF->DataLength; //uip_len includes LLH_LEN
|
||||
mac_ethernetToLowpan(uip_buf);
|
||||
|
||||
|
||||
|
||||
} //if (PBUF->DataLength)
|
||||
|
||||
|
||||
} //if(Is_usb_receive_out() && (uip_len == 0))
|
||||
|
||||
} // if (rndis_data_intialized)
|
||||
else if(Is_device_enumerated() && //Enumeration processs OK &&
|
||||
(usb_mode == eem) ) //USB Stick is using EEM
|
||||
{
|
||||
uint16_t datalength;
|
||||
|
||||
if (doInit) {
|
||||
mac_ethernetSetup();
|
||||
doInit = 0;
|
||||
}
|
||||
|
||||
//Connected!
|
||||
Led0_on();
|
||||
|
||||
Usb_select_endpoint(RX_EP);
|
||||
|
||||
//If we have data and a free buffer
|
||||
if(Is_usb_receive_out() && (uip_len == 0)) {
|
||||
|
||||
//Read how much (endpoint only stores up to 64 bytes anyway)
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
|
||||
//EEM uses 2 bytes as a header
|
||||
headercounter = 2;
|
||||
|
||||
uint8_t fail = 0;
|
||||
|
||||
//Hmm.. what's going on here?
|
||||
if (bytecounter < headercounter) {
|
||||
Usb_ack_receive_out();
|
||||
//TODO CO done = 1;
|
||||
}
|
||||
|
||||
//Read EEM Header
|
||||
i = 0;
|
||||
while (headercounter) {
|
||||
data_buffer[i] = Usb_read_byte();
|
||||
bytecounter--;
|
||||
headercounter--;
|
||||
i++;
|
||||
}
|
||||
|
||||
//Order is LSB/MSB, so MSN is in data_buffer[1]
|
||||
//Bit 15 indicates command packet when set
|
||||
if (data_buffer[1] & 0x80) {
|
||||
//not a data payload
|
||||
datalength = 0;
|
||||
} else {
|
||||
//'0' indicates data packet
|
||||
//Length is lower 14 bits
|
||||
datalength = data_buffer[0] | ((data_buffer[1] & 0x3F) << 8);
|
||||
}
|
||||
|
||||
/* EEM Command Packet */
|
||||
if ((datalength == 0) && (fail == 0))
|
||||
{
|
||||
uint8_t command;
|
||||
uint16_t echoLength;
|
||||
|
||||
//Strip command off
|
||||
command = data_buffer[1] & 0x38;
|
||||
command = command >> 3;
|
||||
|
||||
//Decode command type
|
||||
switch (command)
|
||||
{
|
||||
/* Echo Request */
|
||||
case EEMCMD_ECHO:
|
||||
|
||||
//Get echo length
|
||||
echoLength = (data_buffer[1] & 0x07) << 8; //MSB
|
||||
echoLength |= data_buffer[0]; //LSB
|
||||
|
||||
//TODO: everything. oops.
|
||||
|
||||
break;
|
||||
|
||||
/* Everything else: Whatever. */
|
||||
case EEMCMD_ECHO_RESPONSE:
|
||||
case EEMCMD_SUSPEND_HINT:
|
||||
case EEMCMD_RESPONSE_HINT:
|
||||
case EEMCMD_RESPONSE_COMPLETE_HINT:
|
||||
case EEMCMD_TICKLE:
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
/* EEM Data Packet */
|
||||
else if (datalength && (fail == 0))
|
||||
{
|
||||
//Looks like we've got a live one
|
||||
rx_start_led();
|
||||
|
||||
uint16_t bytes_received = 0;
|
||||
uint16_t dataleft = datalength;
|
||||
U8 * buffer = uip_buf;
|
||||
|
||||
while(dataleft)
|
||||
{
|
||||
*buffer++ = Usb_read_byte();
|
||||
|
||||
dataleft--;
|
||||
bytecounter--;
|
||||
bytes_received++;
|
||||
|
||||
//Check if endpoint is done but we are expecting more data
|
||||
if ((bytecounter == 0) && (dataleft))
|
||||
{
|
||||
//ACK previous data
|
||||
Usb_ack_receive_out();
|
||||
|
||||
//Wait for new data
|
||||
while (!Is_usb_receive_out());
|
||||
|
||||
//Get new data
|
||||
bytecounter = Usb_byte_counter_8();
|
||||
|
||||
//ZLP?
|
||||
if (bytecounter == 0)
|
||||
{
|
||||
//Incomplete!!
|
||||
break;
|
||||
}
|
||||
|
||||
switch(usb_configuration_nb) {
|
||||
case USB_CONFIG_RNDIS_DEBUG:
|
||||
case USB_CONFIG_RNDIS:
|
||||
if(Is_device_enumerated()) {
|
||||
if(rndis_process()) {
|
||||
etimer_set(&et, CLOCK_SECOND/80);
|
||||
} else {
|
||||
Led0_toggle();
|
||||
etimer_set(&et, CLOCK_SECOND/8);
|
||||
}
|
||||
}
|
||||
|
||||
//Ack final data packet
|
||||
Usb_ack_receive_out();
|
||||
|
||||
//Packet has CRC, nobody wants that garbage
|
||||
datalength -= 4;
|
||||
|
||||
//Send data over RF or to local stack
|
||||
uip_len = datalength; //uip_len includes LLH_LEN
|
||||
mac_ethernetToLowpan(uip_buf);
|
||||
|
||||
} //if (datalength)
|
||||
} //if(Is_usb_receive_out() && (uip_len == 0))
|
||||
} // if (Is_device_enumerated())
|
||||
|
||||
if ((usb_mode == rndis_only) || (usb_mode == rndis_debug) || (usb_mode == eem)) {
|
||||
etimer_set(&et, CLOCK_SECOND/80);
|
||||
} else {
|
||||
etimer_set(&et, CLOCK_SECOND);
|
||||
break;
|
||||
case USB_CONFIG_EEM:
|
||||
if(Is_device_enumerated())
|
||||
cdc_eem_process();
|
||||
etimer_set(&et, CLOCK_SECOND/80);
|
||||
break;
|
||||
case USB_CONFIG_ECM:
|
||||
case USB_CONFIG_ECM_DEBUG:
|
||||
if(Is_device_enumerated()) {
|
||||
if(cdc_ecm_process()) {
|
||||
etimer_set(&et, CLOCK_SECOND/80);
|
||||
} else {
|
||||
Led0_toggle();
|
||||
etimer_set(&et, CLOCK_SECOND/8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Led0_toggle();
|
||||
etimer_set(&et, CLOCK_SECOND/4);
|
||||
break;
|
||||
}
|
||||
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
|
||||
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)||(usb_eth_packet_is_available()&&usb_eth_ready_for_next_packet()));
|
||||
} // while(1)
|
||||
|
||||
PROCESS_END();
|
||||
|
@ -527,172 +298,70 @@ static uint16_t iad_fail_timeout, rndis_fail_timeout;
|
|||
*/
|
||||
uint8_t usb_eth_send(uint8_t * senddata, uint16_t sendlen, uint8_t led)
|
||||
{
|
||||
if (usb_mode == eem)
|
||||
return eem_send(senddata, sendlen, led);
|
||||
uint8_t ret = 0;
|
||||
|
||||
if(!usb_eth_is_active) {
|
||||
USB_ETH_HOOK_TX_ERROR("Inactive");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if ((usb_mode == rndis_only) || (usb_mode == rndis_debug))
|
||||
return rndis_send(senddata, sendlen, led);
|
||||
//Check device is set up
|
||||
if (Is_device_enumerated() == 0) {
|
||||
USB_ETH_HOOK_TX_ERROR("Device not enumerated");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
switch(usb_configuration_nb) {
|
||||
case USB_CONFIG_RNDIS_DEBUG:
|
||||
case USB_CONFIG_RNDIS:
|
||||
ret = rndis_send(senddata, sendlen, led);
|
||||
break;
|
||||
case USB_CONFIG_EEM:
|
||||
ret = eem_send(senddata, sendlen, led);
|
||||
break;
|
||||
case USB_CONFIG_ECM:
|
||||
case USB_CONFIG_ECM_DEBUG:
|
||||
ret = ecm_send(senddata, sendlen, led);
|
||||
break;
|
||||
}
|
||||
|
||||
bail:
|
||||
|
||||
if(!ret) // Hit the watchdog if we have a successful send.
|
||||
watchdog_periodic();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
usb_eth_set_active(uint8_t active) {
|
||||
if(usb_eth_is_active!=active) {
|
||||
switch(usb_configuration_nb) {
|
||||
case USB_CONFIG_RNDIS_DEBUG:
|
||||
case USB_CONFIG_RNDIS:
|
||||
usb_eth_is_active = active;
|
||||
rndis_send_interrupt();
|
||||
break;
|
||||
case USB_CONFIG_EEM:
|
||||
break;
|
||||
case USB_CONFIG_ECM:
|
||||
case USB_CONFIG_ECM_DEBUG:
|
||||
cdc_ecm_set_active(active);
|
||||
usb_eth_is_active = active;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Send a single ethernet frame using EEM
|
||||
*/
|
||||
uint8_t eem_send(uint8_t * senddata, uint16_t sendlen, uint8_t led)
|
||||
{
|
||||
//Check device is set up
|
||||
if (Is_device_enumerated() == 0)
|
||||
return 0;
|
||||
|
||||
//Make a header
|
||||
uint8_t header[2];
|
||||
|
||||
//Fake CRC! Add 4 to length for CRC
|
||||
sendlen += 4;
|
||||
header[0] = (sendlen >> 8) & 0x3f;
|
||||
header[1] = sendlen & 0xff;
|
||||
|
||||
//We send CRC seperatly..
|
||||
sendlen -= 4;
|
||||
|
||||
//Send Data
|
||||
Usb_select_endpoint(TX_EP);
|
||||
//Usb_send_in();
|
||||
|
||||
//Wait for ready
|
||||
while(!Is_usb_write_enabled());
|
||||
|
||||
//Send header (LSB then MSB)
|
||||
Usb_write_byte(header[1]);
|
||||
Usb_write_byte(header[0]);
|
||||
|
||||
//Send packet
|
||||
while(sendlen) {
|
||||
Usb_write_byte(*senddata);
|
||||
senddata++;
|
||||
sendlen--;
|
||||
|
||||
//If endpoint is full, send data in
|
||||
//And then wait for data to transfer
|
||||
if (!Is_usb_write_enabled()) {
|
||||
Usb_send_in();
|
||||
|
||||
while(!Is_usb_write_enabled());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//CRC = 0xdeadbeef
|
||||
//Linux kernel 2.6.31 needs 0xdeadbeef in wrong order,
|
||||
//like this: uint8_t crc[4] = {0xef, 0xbe, 0xad, 0xde};
|
||||
//This is fixed in 2.6.32 to the correct order (0xde, 0xad, 0xbe, 0xef)
|
||||
uint8_t crc[4] = {0xde, 0xad, 0xbe, 0xef};
|
||||
|
||||
sendlen = 4;
|
||||
uint8_t i = 0;
|
||||
|
||||
//Send fake CRC
|
||||
while(sendlen) {
|
||||
Usb_write_byte(crc[i]);
|
||||
i++;
|
||||
sendlen--;
|
||||
|
||||
//If endpoint is full, send data in
|
||||
//And then wait for data to transfer
|
||||
if (!Is_usb_write_enabled()) {
|
||||
Usb_send_in();
|
||||
|
||||
while(!Is_usb_write_enabled());
|
||||
}
|
||||
|
||||
if (led) {
|
||||
tx_end_led();
|
||||
}
|
||||
}
|
||||
|
||||
//Send last data in - also handles sending a ZLP if needed
|
||||
Usb_send_in();
|
||||
|
||||
//Wait for ready
|
||||
while(!Is_usb_write_enabled());
|
||||
|
||||
return 1;
|
||||
void
|
||||
usb_eth_get_mac_address(uint8_t dest[6]) {
|
||||
memcpy(dest,&usb_ethernet_addr,6);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Send data over RNDIS interface, data is in uipbuf and length is uiplen
|
||||
*/
|
||||
uint8_t rndis_send(uint8_t * senddata, uint16_t sendlen, uint8_t led)
|
||||
{
|
||||
|
||||
|
||||
uint16_t i;
|
||||
|
||||
//Setup Header
|
||||
PBUF->MessageType = REMOTE_NDIS_PACKET_MSG;
|
||||
PBUF->DataOffset = sizeof(rndis_data_packet_t) - sizeof(rndis_MessageType_t) - sizeof(rndis_MessageLength_t);
|
||||
PBUF->DataLength = sendlen;
|
||||
PBUF->OOBDataLength = 0;
|
||||
PBUF->OOBDataOffset = 0;
|
||||
PBUF->NumOOBDataElements = 0;
|
||||
PBUF->PerPacketInfoOffset = 0;
|
||||
PBUF->PerPacketInfoLength = 0;
|
||||
PBUF->DeviceVcHandle = 0;
|
||||
PBUF->Reserved = 0;
|
||||
PBUF->MessageLength = sizeof(rndis_data_packet_t) + PBUF->DataLength;
|
||||
|
||||
//Send Data
|
||||
Usb_select_endpoint(TX_EP);
|
||||
Usb_send_in();
|
||||
|
||||
//Wait for ready
|
||||
while(!Is_usb_write_enabled());
|
||||
|
||||
//Setup first part of transfer...
|
||||
for(i = 0; i < sizeof(rndis_data_packet_t); i++) {
|
||||
Usb_write_byte(data_buffer[i]);
|
||||
}
|
||||
|
||||
//Send packet
|
||||
while(sendlen) {
|
||||
Usb_write_byte(*senddata);
|
||||
senddata++;
|
||||
sendlen--;
|
||||
|
||||
//If endpoint is full, send data in
|
||||
//And then wait for data to transfer
|
||||
if (!Is_usb_write_enabled()) {
|
||||
Usb_send_in();
|
||||
|
||||
while(!Is_usb_write_enabled());
|
||||
}
|
||||
|
||||
if (led) {
|
||||
tx_end_led();
|
||||
}
|
||||
}
|
||||
|
||||
Usb_send_in();
|
||||
|
||||
return 1;
|
||||
void
|
||||
usb_eth_set_mac_address(const uint8_t src[6]) {
|
||||
memcpy(&usb_ethernet_addr,src,6);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief This will enable the RX_START LED for a period
|
||||
*/
|
||||
void rx_start_led(void)
|
||||
{
|
||||
Led1_on();
|
||||
led1_timer = 10;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief This will enable the TRX_END LED for a period
|
||||
*/
|
||||
void tx_end_led(void)
|
||||
{
|
||||
Led2_on();
|
||||
led2_timer = 10;
|
||||
}
|
||||
/** @} */
|
||||
|
|
|
@ -52,22 +52,72 @@
|
|||
|
||||
|
||||
#include "config.h"
|
||||
#include "../conf_usb.h"
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
#define USB_ETH_MTU UIP_BUFSIZE+4
|
||||
|
||||
|
||||
/*! Hook Documentation
|
||||
** USB_ETH_HOOK_RX_START()
|
||||
** USB_ETH_HOOK_RX_END()
|
||||
** USB_ETH_HOOK_RX_ERROR(string_reason)
|
||||
**
|
||||
** USB_ETH_HOOK_TX_START()
|
||||
** USB_ETH_HOOK_TX_END()
|
||||
** USB_ETH_HOOK_TX_ERROR(string_reason)
|
||||
**
|
||||
** USB_ETH_HOOK_INITIALIZED()
|
||||
** USB_ETH_HOOK_UNINITIALIZED()
|
||||
**
|
||||
** USB_ETH_HOOK_INIT()
|
||||
**
|
||||
** USB_ETH_HOOK_SET_PROMISCIOUS_MODE(bool)
|
||||
**
|
||||
** USB_ETH_HOOK_HANDLE_INBOUND_PACKET(buffer,len)
|
||||
** USB_ETH_HOOK_IS_READY_FOR_INBOUND_PACKET()
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef USB_ETH_HOOK_RX_START
|
||||
void rx_start_led(void);
|
||||
#define USB_ETH_HOOK_RX_START() rx_start_led()
|
||||
#endif
|
||||
|
||||
#ifndef USB_ETH_HOOK_TX_END
|
||||
void tx_end_led(void);
|
||||
#define USB_ETH_HOOK_TX_END() tx_end_led()
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef USB_ETH_HOOK_TX_ERROR
|
||||
#define USB_ETH_HOOK_TX_ERROR(string) do { } while(0)
|
||||
#endif
|
||||
|
||||
#ifndef USB_ETH_HOOK_RX_ERROR
|
||||
#define USB_ETH_HOOK_RX_ERROR(string) do { } while(0)
|
||||
#endif
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
uint8_t usb_eth_send(uint8_t * senddata, uint16_t sendlen, uint8_t led);
|
||||
uint8_t usb_eth_set_active(uint8_t active);
|
||||
uint8_t usb_eth_ready_for_next_packet();
|
||||
|
||||
void sof_action(void);
|
||||
void rx_start_led(void);
|
||||
void tx_end_led(void);
|
||||
|
||||
extern char usb_busy;
|
||||
extern uint8_t usb_eth_is_active;
|
||||
|
||||
PROCESS_NAME(rndis_process);
|
||||
// TIP: Avoid using usb_ethernet_addr directly and use the get/set mac_address functions below.
|
||||
extern uint64_t usb_ethernet_addr;
|
||||
void usb_eth_get_mac_address(uint8_t dest[6]);
|
||||
void usb_eth_set_mac_address(const uint8_t src[6]);
|
||||
|
||||
PROCESS_NAME(usb_eth_process);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
|
|
@ -1,383 +0,0 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file cdc_task.c **********************************************************
|
||||
*
|
||||
* \brief
|
||||
* Manages the CDC-ACM Virtual Serial Port Dataclass for the USB Device
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY 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 COPYRIGHT OWNER 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.
|
||||
*/
|
||||
/**
|
||||
\ingroup usbstick
|
||||
\defgroup cdctask CDC Task
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ___________________________________________________
|
||||
|
||||
|
||||
#include "contiki.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "serial/cdc_task.h"
|
||||
#include "serial/uart_usb_lib.h"
|
||||
#include "rndis/rndis_protocol.h"
|
||||
#include "sicslow_ethernet.h"
|
||||
#if RF230BB
|
||||
extern void rf230_set_channel(int channel);
|
||||
extern int rf230_get_channel(void);
|
||||
#else
|
||||
#include "radio.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
#define PRINTF printf
|
||||
#define PRINTF_P printf_P
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
|
||||
#define IAD_TIMEOUT_DETACH 300
|
||||
#define IAD_TIMEOUT_ATTACH 600
|
||||
#define PBUF ((rndis_data_packet_t *) data_buffer)
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
void menu_print(void);
|
||||
void menu_process(char c);
|
||||
|
||||
extern char usb_busy;
|
||||
|
||||
//! Counter for USB Serial port
|
||||
extern U8 tx_counter;
|
||||
|
||||
//! Timers for LEDs
|
||||
uint8_t led3_timer;
|
||||
|
||||
|
||||
//! Was USB device *just* enumerated?
|
||||
uint8_t justenumerated = 1;
|
||||
|
||||
|
||||
static uint8_t timer = 0;
|
||||
static struct etimer et;
|
||||
|
||||
|
||||
PROCESS(cdc_process, "CDC process");
|
||||
|
||||
/**
|
||||
* \brief Communication Data Class (CDC) Process
|
||||
*
|
||||
* This is the link between USB and the "good stuff". In this routine data
|
||||
* is received and processed by CDC-ACM Class
|
||||
*/
|
||||
PROCESS_THREAD(cdc_process, ev, data_proc)
|
||||
{
|
||||
|
||||
PROCESS_BEGIN();
|
||||
uart_usb_init();
|
||||
|
||||
while(1) {
|
||||
|
||||
|
||||
// turn off LED's if necessary
|
||||
if (led3_timer) led3_timer--;
|
||||
else Led3_off();
|
||||
|
||||
if(Is_device_enumerated() && (usb_mode == rndis_debug) && rndis_state && (!usb_busy)) {
|
||||
|
||||
if (justenumerated) {
|
||||
|
||||
//If we have serial port, set it as output
|
||||
if (usb_mode == rndis_debug) {
|
||||
uart_usb_set_stdout();
|
||||
menu_print();
|
||||
}
|
||||
justenumerated = 0;
|
||||
}
|
||||
|
||||
//Flush buffer if timeout
|
||||
if(timer >= 4 && tx_counter!=0 ){
|
||||
timer = 0;
|
||||
uart_usb_flush();
|
||||
} else {
|
||||
timer++;
|
||||
}
|
||||
|
||||
while (uart_usb_test_hit()){
|
||||
menu_process(uart_usb_getchar()); // See what they want
|
||||
}
|
||||
|
||||
|
||||
}//if (Is_device_enumerated())
|
||||
|
||||
|
||||
if (usb_mode == rndis_debug) {
|
||||
etimer_set(&et, CLOCK_SECOND/80);
|
||||
} else {
|
||||
etimer_set(&et, CLOCK_SECOND);
|
||||
}
|
||||
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
|
||||
|
||||
} // while(1)
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Print debug menu
|
||||
*/
|
||||
void menu_print(void)
|
||||
{
|
||||
PRINTF_P(PSTR("\n\n\r********** Jackdaw Menu ******************\n\r"));
|
||||
PRINTF_P(PSTR("* *\n\r"));
|
||||
PRINTF_P(PSTR("* Main Menu: *\n\r"));
|
||||
PRINTF_P(PSTR("* h,? Print this menu *\n\r"));
|
||||
PRINTF_P(PSTR("* m Print current mode *\n\r"));
|
||||
PRINTF_P(PSTR("* s Set to sniffer mode *\n\r"));
|
||||
PRINTF_P(PSTR("* n Set to network mode *\n\r"));
|
||||
PRINTF_P(PSTR("* c Set RF channel *\n\r"));
|
||||
PRINTF_P(PSTR("* 6 Toggle 6lowpan *\n\r"));
|
||||
PRINTF_P(PSTR("* r Toggle raw mode *\n\r"));
|
||||
PRINTF_P(PSTR("* u Switch to mass-storage*\n\r"));
|
||||
PRINTF_P(PSTR("* *\n\r"));
|
||||
PRINTF_P(PSTR("* Make selection at any time by pressing *\n\r"));
|
||||
PRINTF_P(PSTR("* your choice on keyboard. *\n\r"));
|
||||
PRINTF_P(PSTR("******************************************\n\r"));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Process incomming char on debug port
|
||||
*/
|
||||
void menu_process(char c)
|
||||
{
|
||||
|
||||
static enum menustate_enum /* Defines an enumeration type */
|
||||
{
|
||||
normal,
|
||||
channel
|
||||
} menustate = normal;
|
||||
|
||||
static char channel_string[3];
|
||||
static uint8_t channel_string_i = 0;
|
||||
|
||||
int tempchannel;
|
||||
|
||||
|
||||
if (menustate == channel) {
|
||||
|
||||
switch(c) {
|
||||
case '\r':
|
||||
case '\n':
|
||||
channel_string[channel_string_i] = 0;
|
||||
|
||||
//Will return zero in event of error...
|
||||
tempchannel = atoi(channel_string);
|
||||
|
||||
//Bounds check only if user had real input
|
||||
if ( ((channel_string_i) && (tempchannel < 11)) || (tempchannel > 26)) {
|
||||
PRINTF_P(PSTR("\n\rInvalid input\n\r"));
|
||||
}
|
||||
|
||||
//If valid input, change it
|
||||
if (tempchannel) {
|
||||
#if RF230BB
|
||||
rf230_set_channel(tempchannel);
|
||||
#else
|
||||
radio_set_operating_channel(tempchannel);
|
||||
#endif
|
||||
// eeprom_write_byte((uint8_t *) 9, tempchannel); //Write channel
|
||||
// eeprom_write_byte((uint8_t *)10, ~tempchannel); //Bit inverse as check
|
||||
}
|
||||
|
||||
menustate = normal;
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
|
||||
if (channel_string_i)
|
||||
channel_string_i--;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
if (channel_string_i > 1) {
|
||||
menustate = normal;
|
||||
PRINTF_P(PSTR("\n\rInput too long!\n\r"));
|
||||
break;
|
||||
}
|
||||
|
||||
channel_string[channel_string_i] = c;
|
||||
channel_string_i++;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
uint8_t i;
|
||||
switch(c) {
|
||||
case '\r':
|
||||
case '\n':
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
menu_print();
|
||||
break;
|
||||
|
||||
case 's':
|
||||
PRINTF_P(PSTR("Jackdaw now in sniffer mode\n\r"));
|
||||
usbstick_mode.sendToRf = 0;
|
||||
usbstick_mode.translate = 0;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
PRINTF_P(PSTR("Jackdaw now in network mode\n\r"));
|
||||
usbstick_mode.sendToRf = 1;
|
||||
usbstick_mode.translate = 1;
|
||||
break;
|
||||
|
||||
case '6':
|
||||
if (usbstick_mode.sicslowpan) {
|
||||
PRINTF_P(PSTR("Jackdaw does not perform 6lowpan translation\n\r"));
|
||||
usbstick_mode.sicslowpan = 0;
|
||||
} else {
|
||||
PRINTF_P(PSTR("Jackdaw now performs 6lowpan translations\n\r"));
|
||||
usbstick_mode.sicslowpan = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if (usbstick_mode.raw) {
|
||||
PRINTF_P(PSTR("Jackdaw does not capture raw frames\n\r"));
|
||||
usbstick_mode.raw = 0;
|
||||
} else {
|
||||
PRINTF_P(PSTR("Jackdaw now captures raw frames\n\r"));
|
||||
usbstick_mode.raw = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
#if RF230BB
|
||||
PRINTF_P(PSTR("Select 802.15.4 Channel in range 11-26 [%d]: "), rf230_get_channel());
|
||||
#else
|
||||
PRINTF_P(PSTR("Select 802.15.4 Channel in range 11-26 [%d]: "), radio_get_operating_channel());
|
||||
#endif
|
||||
menustate = channel;
|
||||
channel_string_i = 0;
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case 'm':
|
||||
PRINTF_P(PSTR("Currently Jackdaw:\n\r * Will "));
|
||||
if (usbstick_mode.sendToRf == 0) { PRINTF_P(PSTR("not "));}
|
||||
PRINTF_P(PSTR("send data over RF\n\r * Will "));
|
||||
if (usbstick_mode.translate == 0) { PRINTF_P(PSTR("not "));}
|
||||
PRINTF_P(PSTR("change link-local addresses inside IP messages\n\r * Will "));
|
||||
if (usbstick_mode.sicslowpan == 0) { PRINTF_P(PSTR("not "));}
|
||||
PRINTF_P(PSTR("decompress 6lowpan headers\n\r * Will "));
|
||||
if (usbstick_mode.raw == 0) { PRINTF_P(PSTR("not "));}
|
||||
PRINTF_P(PSTR("Output raw 802.15.4 frames\n\r "));
|
||||
#if RF230BB
|
||||
PRINTF_P(PSTR(" * Operates on channel %d\n\r "), rf230_get_channel());
|
||||
#else
|
||||
PRINTF_P(PSTR(" * Operates on channel %d\n\r "), radio_get_operating_channel());
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
|
||||
//Mass storage mode
|
||||
usb_mode = mass_storage;
|
||||
|
||||
//No more serial port
|
||||
stdout = NULL;
|
||||
|
||||
//RNDIS is over
|
||||
rndis_state = rndis_uninitialized;
|
||||
Leds_off();
|
||||
|
||||
//Deatch USB
|
||||
Usb_detach();
|
||||
|
||||
//Wait a few seconds
|
||||
for(i = 0; i < 50; i++)
|
||||
_delay_ms(100);
|
||||
|
||||
//Attach USB
|
||||
Usb_attach();
|
||||
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINTF_P(PSTR("%c is not a valid option! h for menu\n\r"), c);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief This will enable the VCP_TRX_END LED for a period
|
||||
*/
|
||||
void vcptx_end_led(void)
|
||||
{
|
||||
Led3_on();
|
||||
led3_timer = 10;
|
||||
}
|
||||
/** @} */
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file cdc_task.h ************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file manages the CDC task for the virtual COM port.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
Copyright (c) 2008 Colin O'Flynn
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY 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 COPYRIGHT OWNER 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.
|
||||
*/
|
||||
|
||||
#ifndef _CDC_TASK_H_
|
||||
#define _CDC_TASK_H_
|
||||
|
||||
/**
|
||||
\addtogroup cdctask
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
void sof_action(void);
|
||||
void vcptx_end_led(void);
|
||||
|
||||
void rawmode_enable(void);
|
||||
void rawmode_disable(void);
|
||||
|
||||
PROCESS_NAME(cdc_process);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _CDC_TASK_H_ */
|
||||
|
|
@ -45,7 +45,6 @@
|
|||
#include "config.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "serial/cdc_task.h"
|
||||
#include "serial/uart_usb_lib.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -56,6 +55,26 @@
|
|||
|
||||
/*_____ M A C R O S ________________________________________________________*/
|
||||
|
||||
#ifndef USB_CDC_ACM_HOOK_TX_START
|
||||
#define USB_CDC_ACM_HOOK_TX_START(char)
|
||||
#endif
|
||||
|
||||
#ifndef USB_CDC_ACM_HOOK_TX_END
|
||||
#define USB_CDC_ACM_HOOK_TX_END(char)
|
||||
#endif
|
||||
|
||||
#ifndef USB_CDC_ACM_HOOK_CLS_CHANGED
|
||||
#define USB_CDC_ACM_HOOK_CLS_CHANGED(state)
|
||||
#endif
|
||||
|
||||
#ifndef USB_CDC_ACM_HOOK_CONFIGURED
|
||||
#define USB_CDC_ACM_HOOK_CONFIGURED()
|
||||
#endif
|
||||
|
||||
#ifndef USB_CDC_ACM_CONF_LOCAL_ECHO
|
||||
#define USB_CDC_ACM_CONF_LOCAL_ECHO 0
|
||||
#endif
|
||||
|
||||
/*_____ D E F I N I T I O N ________________________________________________*/
|
||||
|
||||
Uchar tx_counter;
|
||||
|
@ -64,22 +83,65 @@ S_line_coding line_coding;
|
|||
|
||||
/*_____ D E C L A R A T I O N ______________________________________________*/
|
||||
|
||||
void uart_usb_configure_endpoints() {
|
||||
usb_configure_endpoint(
|
||||
VCP_INT_EP,
|
||||
TYPE_INTERRUPT,
|
||||
DIRECTION_IN,
|
||||
SIZE_32,
|
||||
ONE_BANK,
|
||||
NYET_ENABLED
|
||||
);
|
||||
|
||||
usb_configure_endpoint(
|
||||
VCP_TX_EP,
|
||||
TYPE_BULK,
|
||||
DIRECTION_IN,
|
||||
SIZE_32,
|
||||
TWO_BANKS,
|
||||
NYET_ENABLED
|
||||
);
|
||||
|
||||
usb_configure_endpoint(
|
||||
VCP_RX_EP,
|
||||
TYPE_BULK,
|
||||
DIRECTION_OUT,
|
||||
SIZE_32,
|
||||
TWO_BANKS,
|
||||
NYET_ENABLED
|
||||
);
|
||||
|
||||
Usb_reset_endpoint(VCP_INT_EP);
|
||||
Usb_reset_endpoint(VCP_TX_EP);
|
||||
Usb_reset_endpoint(VCP_RX_EP);
|
||||
|
||||
USB_CDC_ACM_HOOK_CONFIGURED();
|
||||
}
|
||||
|
||||
|
||||
int usb_stdout_putchar(char c, FILE *stream)
|
||||
{
|
||||
// send to USB port
|
||||
// don't send anything if USB can't accept chars
|
||||
Usb_select_endpoint(TX_EP);
|
||||
if (!uart_usb_tx_ready())
|
||||
return 0;
|
||||
|
||||
// turn on LED
|
||||
vcptx_end_led();
|
||||
{
|
||||
// Preserve the currently selected endpoint
|
||||
uint8_t uenum = UENUM;
|
||||
|
||||
// send to USB port
|
||||
// don't send anything if USB can't accept chars
|
||||
Usb_select_endpoint(VCP_TX_EP);
|
||||
|
||||
if(usb_endpoint_wait_for_write_enabled()!=0)
|
||||
return 0;
|
||||
|
||||
if(c=='\n')
|
||||
uart_usb_putchar('\r');
|
||||
|
||||
if(c!='\r')
|
||||
uart_usb_putchar(c);
|
||||
|
||||
// Restore previously selected endpoint
|
||||
UENUM = uenum;
|
||||
|
||||
uart_usb_putchar(c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static FILE usb_stdout = FDEV_SETUP_STREAM(usb_stdout_putchar,
|
||||
NULL,
|
||||
|
@ -100,6 +162,20 @@ void uart_usb_set_stdout(void)
|
|||
}
|
||||
|
||||
|
||||
static uint8_t uart_usb_control_line_state = 0;
|
||||
|
||||
uint8_t uart_usb_get_control_line_state(void) {
|
||||
return uart_usb_control_line_state;
|
||||
}
|
||||
|
||||
|
||||
void uart_usb_set_control_line_state(uint8_t control_line_state)
|
||||
{
|
||||
uart_usb_control_line_state = control_line_state;
|
||||
USB_CDC_ACM_HOOK_CLS_CHANGED(control_line_state);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function checks if the USB emission buffer is ready to accept at
|
||||
* at least 1 byte
|
||||
|
@ -109,6 +185,7 @@ void uart_usb_set_stdout(void)
|
|||
*/
|
||||
bit uart_usb_tx_ready(void)
|
||||
{
|
||||
Usb_select_endpoint(VCP_TX_EP);
|
||||
if (!Is_usb_write_enabled())
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -127,16 +204,31 @@ bit uart_usb_tx_ready(void)
|
|||
*/
|
||||
int uart_usb_putchar(int data_to_send)
|
||||
{
|
||||
Usb_select_endpoint(VCP_TX_EP);
|
||||
|
||||
if(!uart_usb_tx_ready()) return -1;
|
||||
|
||||
// Preserve the currently selected endpoint
|
||||
uint8_t uenum = UENUM;
|
||||
|
||||
USB_CDC_ACM_HOOK_TX_START(data_to_send);
|
||||
|
||||
Usb_select_endpoint(VCP_TX_EP);
|
||||
|
||||
if(!uart_usb_tx_ready()) {
|
||||
data_to_send=-1;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
Usb_write_byte(data_to_send);
|
||||
tx_counter++;
|
||||
if(!Is_usb_write_enabled()) //If Endpoint full -> flush
|
||||
{
|
||||
uart_usb_flush();
|
||||
}
|
||||
|
||||
//If Endpoint full -> flush
|
||||
if(!Is_usb_write_enabled())
|
||||
uart_usb_flush();
|
||||
|
||||
USB_CDC_ACM_HOOK_TX_END(data_to_send);
|
||||
|
||||
bail:
|
||||
// Restore previously selected endpoint
|
||||
UENUM = uenum;
|
||||
|
||||
return data_to_send;
|
||||
}
|
||||
|
||||
|
@ -149,6 +241,8 @@ bit uart_usb_test_hit(void)
|
|||
{
|
||||
if (!rx_counter)
|
||||
{
|
||||
// Preserve the currently selected endpoint
|
||||
uint8_t uenum = UENUM;
|
||||
Usb_select_endpoint(VCP_RX_EP);
|
||||
if (Is_usb_receive_out())
|
||||
{
|
||||
|
@ -158,6 +252,8 @@ bit uart_usb_test_hit(void)
|
|||
Usb_ack_receive_out();
|
||||
}
|
||||
}
|
||||
// Restore previously selected endpoint
|
||||
UENUM = uenum;
|
||||
}
|
||||
return (rx_counter!=0);
|
||||
}
|
||||
|
@ -174,15 +270,23 @@ char uart_usb_getchar(void)
|
|||
{
|
||||
register Uchar data_rx;
|
||||
|
||||
// Preserve the currently selected endpoint
|
||||
uint8_t uenum = UENUM;
|
||||
|
||||
Usb_select_endpoint(VCP_RX_EP);
|
||||
if (!rx_counter) while (!uart_usb_test_hit());
|
||||
data_rx=Usb_read_byte();
|
||||
rx_counter--;
|
||||
if (!rx_counter) Usb_ack_receive_out();
|
||||
|
||||
#if USB_CDC_ACM_CONF_LOCAL_ECHO
|
||||
//Local echo
|
||||
uart_usb_putchar(data_rx);
|
||||
#endif
|
||||
|
||||
// Restore previously selected endpoint
|
||||
UENUM = uenum;
|
||||
|
||||
return data_rx;
|
||||
}
|
||||
|
||||
|
@ -193,9 +297,16 @@ char uart_usb_getchar(void)
|
|||
*/
|
||||
void uart_usb_flush (void)
|
||||
{
|
||||
Usb_select_endpoint(VCP_TX_EP);
|
||||
Usb_send_in();
|
||||
// Preserve the currently selected endpoint
|
||||
uint8_t uenum = UENUM;
|
||||
|
||||
Usb_select_endpoint(VCP_TX_EP);
|
||||
Usb_send_in();
|
||||
tx_counter = 0;
|
||||
usb_endpoint_wait_for_write_enabled();
|
||||
|
||||
// Restore previously selected endpoint
|
||||
UENUM = uenum;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -78,6 +78,10 @@ void uart_usb_flush(void);
|
|||
bit uart_usb_test_hit(void);
|
||||
char uart_usb_getchar(void);
|
||||
void uart_usb_set_stdout(void);
|
||||
uint8_t uart_usb_get_control_line_state(void);
|
||||
void uart_usb_set_control_line_state(uint8_t control_line_state);
|
||||
|
||||
extern void uart_usb_configure_endpoints();
|
||||
|
||||
/** @} **/
|
||||
|
||||
|
|
|
@ -55,17 +55,252 @@
|
|||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "rndis/rndis_task.h"
|
||||
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
#define USB_ETH_NET_FUNC_DESC(MACAddrString,etherStat,maxSegmentSize,nMCFilters,nPowerFilters) \
|
||||
{ sizeof(S_usb_ethernet_networking_functional_descriptor) \
|
||||
, 0x24, 0x0F \
|
||||
, MACAddrString \
|
||||
, etherStat \
|
||||
, Usb_write_word_enum_struc(maxSegmentSize) \
|
||||
, Usb_write_word_enum_struc(nMCFilters) \
|
||||
, nPowerFilters \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define USB_CONFIG_DESC(totalsize,interfaceCount,value,stringIndex,attr,power) \
|
||||
{ sizeof(S_usb_configuration_descriptor) \
|
||||
, CONFIGURATION_DESCRIPTOR \
|
||||
, Usb_write_word_enum_struc(totalsize) \
|
||||
, interfaceCount \
|
||||
, value \
|
||||
, stringIndex \
|
||||
, attr \
|
||||
, power \
|
||||
}
|
||||
|
||||
#define USB_ENDPOINT(nb,attr,maxpktsize,interval) \
|
||||
{ sizeof(S_usb_endpoint_descriptor) \
|
||||
, ENDPOINT_DESCRIPTOR \
|
||||
, nb \
|
||||
, attr \
|
||||
, Usb_write_word_enum_struc(maxpktsize) \
|
||||
, interval \
|
||||
}
|
||||
|
||||
#define USB_IAD(firstinterface,interfacecount,funcClass,funcSubClass,funcProto,stringIndex) \
|
||||
{ \
|
||||
sizeof(S_usb_interface_association_descriptor), \
|
||||
DSC_TYPE_IAD, \
|
||||
firstinterface, \
|
||||
interfacecount, \
|
||||
funcClass, \
|
||||
funcSubClass, \
|
||||
funcProto, \
|
||||
stringIndex \
|
||||
}
|
||||
|
||||
#define USB_INTERFACEDESC(nb,altsetting,endpointCount,interfaceClass,interfaceSubClass,interfaceProto,stringIndex) \
|
||||
{ sizeof(S_usb_interface_descriptor) \
|
||||
, INTERFACE_DESCRIPTOR \
|
||||
, nb \
|
||||
, altsetting \
|
||||
, endpointCount \
|
||||
, interfaceClass \
|
||||
, interfaceSubClass \
|
||||
, interfaceProto \
|
||||
, stringIndex \
|
||||
}
|
||||
|
||||
|
||||
#define FUNC_DESC_HEADER \
|
||||
0x05, /* bFunctionLength, Descriptor size in bytes*/ \
|
||||
0x24, /* bDescriptorType, CS_INTERFACE */ \
|
||||
0x00, /* bDescriptorSubtype, Header Functional Descriptor */ \
|
||||
0x10,0x01 /* bcdCDC, CDC specification release number in BCD format (1,1) */
|
||||
|
||||
#define FUNC_DESC_CALL_MANAGEMENT(caps,dataInterface) \
|
||||
0x05, /* bFunctionLength, Descriptor size in bytes */ \
|
||||
0x24, /* bDescriptorType, CS_INTERFACE */ \
|
||||
0x01, /* bDescriptorSubtype, Call Management Functional Descriptor */ \
|
||||
caps, /* bmCapabilities */ \
|
||||
dataInterface /* bDataInterface, Interface used for call management */
|
||||
|
||||
/* Abstract Control Management Functional Descriptor */
|
||||
#define FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT(caps) \
|
||||
0x04, /* bFunctionLength, Descriptor size in bytes */ \
|
||||
0x24, /* bDescriptorType, CS_INTERFACE */ \
|
||||
0x02, /* bDescriptorSubtype, Call Management Functional Descriptor */ \
|
||||
caps /* bmCapabilities */
|
||||
|
||||
/* Union Functional Descriptor */ \
|
||||
#define FUNC_DESC_UNION(masterInterface,slaveInterface) \
|
||||
0x05, /* bFunctionLength, Descriptor size in bytes */ \
|
||||
0x24, /* bDescriptorType, CS_INTERFACE */ \
|
||||
0x06, /* bDescriptorSubtype, Union Functional Descriptor */ \
|
||||
masterInterface, /* bMasterInterface, The controlling interface for the union (bInterfaceNumber of a Communication or Data Class interface in this configuration) */ \
|
||||
slaveInterface /* bSlaveInterface0, The controlled interace in the union (bInterfaceNumber of an interface in this configuration) */ \
|
||||
|
||||
|
||||
#define RNDIS_INTERFACES \
|
||||
USB_INTERFACEDESC( \
|
||||
INTERFACE0_NB, \
|
||||
ALTERNATE0, \
|
||||
NB_ENDPOINT0, \
|
||||
INTERFACE0_CLASS, \
|
||||
INTERFACE0_SUB_CLASS, \
|
||||
INTERFACE0_PROTOCOL, \
|
||||
USB_STRING_INTERFACE_RNDIS \
|
||||
), \
|
||||
{ \
|
||||
FUNC_DESC_HEADER, \
|
||||
FUNC_DESC_CALL_MANAGEMENT(0x00/*caps*/,0x00/*dataInterface*/), \
|
||||
FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT(0x00), \
|
||||
FUNC_DESC_UNION(0x00,0x01), \
|
||||
}, \
|
||||
USB_ENDPOINT(ENDPOINT_NB_1,EP_ATTRIBUTES_1,EP_SIZE_1,EP_INTERVAL_1), \
|
||||
\
|
||||
USB_INTERFACEDESC( \
|
||||
INTERFACE1_NB, \
|
||||
ALTERNATE1, \
|
||||
NB_ENDPOINT1, \
|
||||
INTERFACE1_CLASS, \
|
||||
INTERFACE1_SUB_CLASS, \
|
||||
INTERFACE1_PROTOCOL, \
|
||||
USB_STRING_NONE \
|
||||
), \
|
||||
USB_ENDPOINT(ENDPOINT_NB_2,EP_ATTRIBUTES_2,EP_SIZE_2,EP_INTERVAL_2), \
|
||||
USB_ENDPOINT(ENDPOINT_NB_3,EP_ATTRIBUTES_3,EP_SIZE_3,EP_INTERVAL_3)
|
||||
|
||||
|
||||
|
||||
#define CDC_SERIAL_INTERFACES \
|
||||
USB_INTERFACEDESC( \
|
||||
INTERFACE2_NB, \
|
||||
ALTERNATE2, \
|
||||
NB_ENDPOINT2, \
|
||||
INTERFACE2_CLASS, \
|
||||
INTERFACE2_SUB_CLASS, \
|
||||
INTERFACE2_PROTOCOL, \
|
||||
USB_STRING_INTERFACE_SERIAL \
|
||||
), \
|
||||
{ \
|
||||
FUNC_DESC_HEADER, \
|
||||
FUNC_DESC_CALL_MANAGEMENT(0x03/*caps*/,0x03/*dataInterface*/), \
|
||||
FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT(0x02), \
|
||||
FUNC_DESC_UNION(0x02,0x03), \
|
||||
}, \
|
||||
USB_ENDPOINT(ENDPOINT_NB_4,EP_ATTRIBUTES_4,EP_SIZE_4,EP_INTERVAL_4), \
|
||||
USB_INTERFACEDESC( \
|
||||
INTERFACE3_NB, \
|
||||
ALTERNATE3, \
|
||||
NB_ENDPOINT3, \
|
||||
INTERFACE3_CLASS, \
|
||||
INTERFACE3_SUB_CLASS, \
|
||||
INTERFACE3_PROTOCOL, \
|
||||
USB_STRING_NONE \
|
||||
), \
|
||||
USB_ENDPOINT(ENDPOINT_NB_5,EP_ATTRIBUTES_5,EP_SIZE_5,EP_INTERVAL_5), \
|
||||
USB_ENDPOINT(ENDPOINT_NB_6,EP_ATTRIBUTES_6,EP_SIZE_6,EP_INTERVAL_6)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define CDC_EEM_INTERFACES \
|
||||
USB_INTERFACEDESC( \
|
||||
EEM_INTERFACE0_NB, \
|
||||
EEM_ALTERNATE0, \
|
||||
EEM_NB_ENDPOINT0, \
|
||||
EEM_INTERFACE0_CLASS, \
|
||||
EEM_INTERFACE0_SUB_CLASS, \
|
||||
EEM_INTERFACE0_PROTOCOL, \
|
||||
USB_STRING_INTERFACE_EEM \
|
||||
), \
|
||||
USB_ENDPOINT(ENDPOINT_NB_1,EP_ATTRIBUTES_1,EP_SIZE_1,EP_INTERVAL_1), \
|
||||
USB_ENDPOINT(ENDPOINT_NB_2,EP_ATTRIBUTES_2,EP_SIZE_2,EP_INTERVAL_2)
|
||||
|
||||
|
||||
|
||||
|
||||
#if CDC_ECM_USES_INTERRUPT_ENDPOINT
|
||||
#define CDC_ECM_CONTROL_ENDPOINT_COUNT 1
|
||||
#define CDC_ECM_CONTROL_ENDPOINT USB_ENDPOINT(ENDPOINT_NB_1,EP_ATTRIBUTES_1,EP_SIZE_1,EP_INTERVAL_1),
|
||||
#else
|
||||
#define CDC_ECM_CONTROL_ENDPOINT_COUNT 0
|
||||
#define CDC_ECM_CONTROL_ENDPOINT
|
||||
#endif
|
||||
|
||||
|
||||
#define CDC_ECM_INTERFACES \
|
||||
USB_INTERFACEDESC( \
|
||||
ECM_INTERFACE0_NB, \
|
||||
ECM_ALTERNATE0, \
|
||||
CDC_ECM_CONTROL_ENDPOINT_COUNT, \
|
||||
ECM_INTERFACE0_CLASS, \
|
||||
ECM_INTERFACE0_SUB_CLASS, \
|
||||
ECM_INTERFACE0_PROTOCOL, \
|
||||
USB_STRING_INTERFACE_ECM \
|
||||
), \
|
||||
{ \
|
||||
FUNC_DESC_HEADER, \
|
||||
FUNC_DESC_UNION(0x00,0x01), \
|
||||
}, \
|
||||
USB_ETH_NET_FUNC_DESC( \
|
||||
USB_STRING_MAC_ADDRESS, \
|
||||
0, /* Support no stats for now */ \
|
||||
USB_ETH_MTU, /* maxSegmentSize */ \
|
||||
0, /* nMCFilters*/ \
|
||||
0 /*nPowerFilters*/ \
|
||||
), \
|
||||
CDC_ECM_CONTROL_ENDPOINT \
|
||||
USB_INTERFACEDESC( \
|
||||
ECM_INTERFACE0_NB+1, \
|
||||
0, \
|
||||
2, \
|
||||
10, \
|
||||
0, \
|
||||
0, \
|
||||
USB_STRING_NONE \
|
||||
), \
|
||||
USB_ENDPOINT(ENDPOINT_NB_2,EP_ATTRIBUTES_2,EP_SIZE_2,EP_INTERVAL_2), \
|
||||
USB_ENDPOINT(ENDPOINT_NB_3,EP_ATTRIBUTES_3,EP_SIZE_3,EP_INTERVAL_3)
|
||||
|
||||
/*
|
||||
USB_INTERFACEDESC( \
|
||||
ECM_INTERFACE0_NB+1, \
|
||||
0, \
|
||||
0, \
|
||||
10, \
|
||||
0, \
|
||||
0, \
|
||||
USB_STRING_NONE \
|
||||
), \
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N ________________________________________________
|
||||
|
||||
/************* COMPOSITE DEVICE DESCRIPTORS (using IAD) **********/
|
||||
|
||||
FLASH uint8_t usb_dev_config_order[] = {
|
||||
// USB_CONFIG_RNDIS_DEBUG, //Enable here for Windows COM port debugging? (USB_CONF_CDC=1)
|
||||
USB_CONFIG_RNDIS,
|
||||
USB_CONFIG_ECM_DEBUG,
|
||||
USB_CONFIG_RNDIS_DEBUG, //Enable here for macintosh CDC-ECM enumeration
|
||||
USB_CONFIG_ECM,
|
||||
USB_CONFIG_EEM,
|
||||
#if USB_CONF_STORAGE
|
||||
USB_CONFIG_MS,
|
||||
#endif
|
||||
};
|
||||
|
||||
// usb_user_device_descriptor
|
||||
FLASH S_usb_device_descriptor usb_dev_desc_composite =
|
||||
{
|
||||
|
@ -79,204 +314,46 @@ FLASH S_usb_device_descriptor usb_dev_desc_composite =
|
|||
, Usb_write_word_enum_struc(VENDOR_ID)
|
||||
, Usb_write_word_enum_struc(COMPOSITE_PRODUCT_ID)
|
||||
, Usb_write_word_enum_struc(RELEASE_NUMBER)
|
||||
, MAN_INDEX
|
||||
, PROD_INDEX
|
||||
, SN_INDEX
|
||||
, NB_CONFIGURATION
|
||||
, USB_STRING_MAN
|
||||
, USB_STRING_PRODUCT
|
||||
, USB_STRING_SERIAL
|
||||
, (sizeof(usb_dev_config_order)/sizeof(*usb_dev_config_order))
|
||||
};
|
||||
|
||||
|
||||
// usb_user_configuration_descriptor FS
|
||||
FLASH S_usb_user_configuration_descriptor_composite usb_conf_desc_composite = {
|
||||
{ sizeof(S_usb_configuration_descriptor)
|
||||
, CONFIGURATION_DESCRIPTOR
|
||||
, Usb_write_word_enum_struc(sizeof(S_usb_user_configuration_descriptor_composite))
|
||||
//, 0x0043 //TODO: Change to generic codewith sizeof
|
||||
, COMPOSITE_NB_INTERFACE
|
||||
, CONF_NB
|
||||
, CONF_INDEX
|
||||
, CONF_ATTRIBUTES
|
||||
, MAX_POWER
|
||||
},//9
|
||||
USB_CONFIG_DESC(
|
||||
sizeof(usb_conf_desc_composite),
|
||||
COMPOSITE_NB_INTERFACE,
|
||||
USB_CONFIG_RNDIS_DEBUG,
|
||||
USB_STRING_CONFIG_COMPOSITE,
|
||||
CONF_ATTRIBUTES,
|
||||
MAX_POWER
|
||||
),
|
||||
|
||||
// --------------------------- IAD ----------------------------
|
||||
{ // Interface Association Descriptor
|
||||
sizeof(S_usb_interface_association_descriptor), // bLength
|
||||
DSC_TYPE_IAD, // bDescriptorType = 11
|
||||
0x00, // bFirstInterface
|
||||
0x02, // bInterfaceCount
|
||||
0x02, // bFunctionClass (Communication Class)
|
||||
0x02, // bFunctionSubClass (Abstract Control Model)
|
||||
0xFF, // bFunctionProcotol (Vendor specific)
|
||||
0x00 // iInterface
|
||||
},//8
|
||||
|
||||
/// RNDIS DEVICE
|
||||
{ sizeof(S_usb_interface_descriptor)
|
||||
, INTERFACE_DESCRIPTOR
|
||||
, INTERFACE0_NB
|
||||
, ALTERNATE0
|
||||
, NB_ENDPOINT0
|
||||
, INTERFACE0_CLASS
|
||||
, INTERFACE0_SUB_CLASS
|
||||
, INTERFACE0_PROTOCOL
|
||||
, INTERFACE0_INDEX
|
||||
} //9
|
||||
,
|
||||
{
|
||||
// Header Functional Descriptor (marks beginning of the concatenated set of Functional Descriptors)
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x00, // bDescriptorSubtype, Header Functional Descriptor
|
||||
0x10,0x01, // bcdCDC, CDC specification release number in BCD format (1,1)
|
||||
|
||||
// Call Management Functional Descriptor
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x01, // bDescriptorSubtype, Call Management Functional Descriptor
|
||||
0x00, // bmCapabilities
|
||||
0x01, // bDataInterface, Interface used for call management
|
||||
|
||||
// Abstract Control Management Functional Descriptor
|
||||
0x04, // bDescriptorLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x02, // bDescriptorSubtype, Abstract Control Management Functional Descriptor
|
||||
0x00, // bmCapabilities
|
||||
|
||||
// Union Functional Descriptor
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x06, // bDescriptorSubtype, Union Functional Descriptor
|
||||
0x00, // bMasterInterface, The controlling interface for the union (bInterfaceNumber of a Communication or Data Class interface in this configuration)
|
||||
0x01, // bSlaveInterface0, The controlled interace in the union (bInterfaceNumber of an interface in this configuration)
|
||||
},
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_1
|
||||
, EP_ATTRIBUTES_1
|
||||
, Usb_write_word_enum_struc(EP_SIZE_1)
|
||||
, EP_INTERVAL_1
|
||||
} //7
|
||||
,
|
||||
{ sizeof(S_usb_interface_descriptor)
|
||||
, INTERFACE_DESCRIPTOR
|
||||
, INTERFACE1_NB
|
||||
, ALTERNATE1
|
||||
, NB_ENDPOINT1
|
||||
, INTERFACE1_CLASS
|
||||
, INTERFACE1_SUB_CLASS
|
||||
, INTERFACE1_PROTOCOL
|
||||
, INTERFACE1_INDEX
|
||||
},
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_2
|
||||
, EP_ATTRIBUTES_2
|
||||
, Usb_write_word_enum_struc(EP_SIZE_2)
|
||||
, EP_INTERVAL_2
|
||||
},
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_3
|
||||
, EP_ATTRIBUTES_3
|
||||
, Usb_write_word_enum_struc(EP_SIZE_3)
|
||||
, EP_INTERVAL_3
|
||||
},
|
||||
|
||||
// --------------------------- IAD ----------------------------
|
||||
{ // Interface Association Descriptor
|
||||
sizeof(S_usb_interface_association_descriptor), // bLength
|
||||
DSC_TYPE_IAD, // bDescriptorType = 11
|
||||
0x02, // bFirstInterface
|
||||
0x02, // bInterfaceCount
|
||||
0x02, // bFunctionClass (Communication Class)
|
||||
0x02, // bFunctionSubClass (Abstract Control Model)
|
||||
0x01, // bFunctionProcotol (V.25ter, Common AT commands)
|
||||
0x00 // iInterface
|
||||
},//8
|
||||
|
||||
/// SERIAL PORT DEVICE
|
||||
|
||||
{ sizeof(S_usb_interface_descriptor)
|
||||
, INTERFACE_DESCRIPTOR
|
||||
, INTERFACE2_NB
|
||||
, ALTERNATE2
|
||||
, NB_ENDPOINT2
|
||||
, INTERFACE2_CLASS
|
||||
, INTERFACE2_SUB_CLASS
|
||||
, INTERFACE2_PROTOCOL
|
||||
, INTERFACE2_INDEX
|
||||
}//9
|
||||
,
|
||||
{
|
||||
// Header Functional Descriptor (marks beginning of the concatenated set of Functional Descriptors)
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x00, // bDescriptorSubtype, Header Functional Descriptor
|
||||
0x10,0x01, // bcdCDC, CDC specification release number in BCD format (1,1)
|
||||
|
||||
// Call Management Functional Descriptor
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x01, // bDescriptorSubtype, Call Management Functional Descriptor
|
||||
0x03, // bmCapabilities, can do calls on it's own
|
||||
0x03, // bDataInterface, Interface used for call management
|
||||
|
||||
// Abstract Control Management Functional Descriptor
|
||||
0x04, // bDescriptorLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x02, // bDescriptorSubtype, Abstract Control Management Functional Descriptor
|
||||
0x00, // bmCapabilities, support nothing!!! Deal with it
|
||||
|
||||
//Old was 0x06 indicating support for the GET/SET_LINE_CODING, BREAK & SET_CONTROL_LINE_STATE (2->6)
|
||||
|
||||
// Union Functional Descriptor
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x06, // bDescriptorSubtype, Union Functional Descriptor
|
||||
0x02, // bMasterInterface, The controlling interface for the union (bInterfaceNumber of a Communication or Data Class interface in this configuration)
|
||||
0x03, // bSlaveInterface0, The controlled interace in the union (bInterfaceNumber of an interface in this configuration)
|
||||
|
||||
},
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_4
|
||||
, EP_ATTRIBUTES_4
|
||||
, Usb_write_word_enum_struc(EP_SIZE_4)
|
||||
, EP_INTERVAL_4
|
||||
} //7
|
||||
,
|
||||
{ sizeof(S_usb_interface_descriptor)
|
||||
, INTERFACE_DESCRIPTOR
|
||||
, INTERFACE3_NB
|
||||
, ALTERNATE3
|
||||
, NB_ENDPOINT3
|
||||
, INTERFACE3_CLASS
|
||||
, INTERFACE3_SUB_CLASS
|
||||
, INTERFACE3_PROTOCOL
|
||||
, INTERFACE3_INDEX
|
||||
}
|
||||
,
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_5
|
||||
, EP_ATTRIBUTES_5
|
||||
, Usb_write_word_enum_struc(EP_SIZE_5)
|
||||
, EP_INTERVAL_5
|
||||
}
|
||||
,
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_6
|
||||
, EP_ATTRIBUTES_6
|
||||
, Usb_write_word_enum_struc(EP_SIZE_6)
|
||||
, EP_INTERVAL_6
|
||||
}
|
||||
USB_IAD(
|
||||
0x00, // First interface
|
||||
0x02, // Interface count
|
||||
0x02, // Function Class
|
||||
0x02, // Function Subclass
|
||||
0xFF, // Function Protocol
|
||||
USB_STRING_INTERFACE_RNDIS
|
||||
),RNDIS_INTERFACES,
|
||||
|
||||
USB_IAD(
|
||||
0x02, // First interface
|
||||
0x02, // Interface count
|
||||
0x02, // Function Class
|
||||
0x02, // Function Subclass
|
||||
0x01, // Function Protocol
|
||||
USB_STRING_INTERFACE_SERIAL
|
||||
),CDC_SERIAL_INTERFACES
|
||||
};
|
||||
|
||||
/****************** NETWORK-ONLY DEVICE DESCRIPTORS **************************/
|
||||
|
||||
/*
|
||||
FLASH S_usb_device_descriptor usb_dev_desc_network =
|
||||
{
|
||||
sizeof(usb_dev_desc_network)
|
||||
|
@ -289,101 +366,115 @@ FLASH S_usb_device_descriptor usb_dev_desc_network =
|
|||
, Usb_write_word_enum_struc(VENDOR_ID)
|
||||
, Usb_write_word_enum_struc(NETWORK_PRODUCT_ID)
|
||||
, Usb_write_word_enum_struc(RELEASE_NUMBER)
|
||||
, MAN_INDEX
|
||||
, PROD_INDEX
|
||||
, SN_INDEX
|
||||
, USB_STRING_MAN
|
||||
, USB_STRING_PRODUCT
|
||||
, USB_STRING_SERIAL
|
||||
, NB_CONFIGURATION
|
||||
};
|
||||
*/
|
||||
|
||||
// usb_user_configuration_descriptor FS
|
||||
FLASH S_usb_user_configuration_descriptor_network usb_conf_desc_network = {
|
||||
{ sizeof(S_usb_configuration_descriptor)
|
||||
, CONFIGURATION_DESCRIPTOR
|
||||
, Usb_write_word_enum_struc(sizeof(S_usb_user_configuration_descriptor_network))
|
||||
//, 0x0043 //TODO: Change to generic codewith sizeof
|
||||
, NETWORK_NB_INTERFACE
|
||||
, CONF_NB
|
||||
, CONF_INDEX
|
||||
, CONF_ATTRIBUTES
|
||||
, MAX_POWER
|
||||
},//9
|
||||
|
||||
/// RNDIS DEVICE
|
||||
{ sizeof(S_usb_interface_descriptor)
|
||||
, INTERFACE_DESCRIPTOR
|
||||
, INTERFACE0_NB
|
||||
, ALTERNATE0
|
||||
, NB_ENDPOINT0
|
||||
, INTERFACE0_CLASS
|
||||
, INTERFACE0_SUB_CLASS
|
||||
, INTERFACE0_PROTOCOL
|
||||
, INTERFACE0_INDEX
|
||||
} //9
|
||||
,
|
||||
{
|
||||
// Header Functional Descriptor (marks beginning of the concatenated set of Functional Descriptors)
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x00, // bDescriptorSubtype, Header Functional Descriptor
|
||||
0x10,0x01, // bcdCDC, CDC specification release number in BCD format (1,1)
|
||||
|
||||
// Call Management Functional Descriptor
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x01, // bDescriptorSubtype, Call Management Functional Descriptor
|
||||
0x00, // bmCapabilities
|
||||
0x01, // bDataInterface, Interface used for call management
|
||||
|
||||
// Abstract Control Management Functional Descriptor
|
||||
0x04, // bDescriptorLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x02, // bDescriptorSubtype, Abstract Control Management Functional Descriptor
|
||||
0x00, // bmCapabilities
|
||||
|
||||
// Union Functional Descriptor
|
||||
0x05, // bFunctionLength, Descriptor size in bytes
|
||||
0x24, // bDescriptorType, CS_INTERFACE
|
||||
0x06, // bDescriptorSubtype, Union Functional Descriptor
|
||||
0x00, // bMasterInterface, The controlling interface for the union (bInterfaceNumber of a Communication or Data Class interface in this configuration)
|
||||
0x01, // bSlaveInterface0, The controlled interace in the union (bInterfaceNumber of an interface in this configuration)
|
||||
},
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_1
|
||||
, EP_ATTRIBUTES_1
|
||||
, Usb_write_word_enum_struc(EP_SIZE_1)
|
||||
, EP_INTERVAL_1
|
||||
} //7
|
||||
,
|
||||
{ sizeof(S_usb_interface_descriptor)
|
||||
, INTERFACE_DESCRIPTOR
|
||||
, INTERFACE1_NB
|
||||
, ALTERNATE1
|
||||
, NB_ENDPOINT1
|
||||
, INTERFACE1_CLASS
|
||||
, INTERFACE1_SUB_CLASS
|
||||
, INTERFACE1_PROTOCOL
|
||||
, INTERFACE1_INDEX
|
||||
},
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_2
|
||||
, EP_ATTRIBUTES_2
|
||||
, Usb_write_word_enum_struc(EP_SIZE_2)
|
||||
, EP_INTERVAL_2
|
||||
},
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, ENDPOINT_NB_3
|
||||
, EP_ATTRIBUTES_3
|
||||
, Usb_write_word_enum_struc(EP_SIZE_3)
|
||||
, EP_INTERVAL_3
|
||||
}
|
||||
USB_CONFIG_DESC(
|
||||
sizeof(usb_conf_desc_network),
|
||||
NETWORK_NB_INTERFACE,
|
||||
CONF_NB, // value
|
||||
USB_STRING_CONFIG_RNDIS,
|
||||
CONF_ATTRIBUTES,
|
||||
MAX_POWER
|
||||
),
|
||||
RNDIS_INTERFACES
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************* EEM-ONLY ***************/
|
||||
|
||||
// usb_user_device_descriptor
|
||||
/*
|
||||
FLASH S_usb_device_descriptor usb_dev_desc_eem =
|
||||
{
|
||||
sizeof(usb_dev_desc_composite)
|
||||
, DEVICE_DESCRIPTOR
|
||||
, Usb_write_word_enum_struc(USB_SPECIFICATION)
|
||||
, EEM_DEVICE_CLASS
|
||||
, EEM_DEVICE_SUB_CLASS
|
||||
, EEM_DEVICE_PROTOCOL
|
||||
, EP_CONTROL_LENGTH
|
||||
, Usb_write_word_enum_struc(VENDOR_ID)
|
||||
, Usb_write_word_enum_struc(COMPOSITE_PRODUCT_ID)
|
||||
, Usb_write_word_enum_struc(RELEASE_NUMBER)
|
||||
, USB_STRING_MAN
|
||||
, USB_STRING_PRODUCT
|
||||
, USB_STRING_SERIAL
|
||||
, NB_CONFIGURATION
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
// usb_user_configuration_descriptor FS
|
||||
FLASH S_usb_user_configuration_descriptor_eem usb_conf_desc_eem = {
|
||||
USB_CONFIG_DESC(
|
||||
sizeof(usb_conf_desc_eem),
|
||||
EEM_NB_INTERFACE,
|
||||
USB_CONFIG_EEM, // value
|
||||
USB_STRING_CONFIG_EEM,
|
||||
CONF_ATTRIBUTES,
|
||||
MAX_POWER
|
||||
),
|
||||
CDC_EEM_INTERFACES
|
||||
};
|
||||
|
||||
|
||||
FLASH S_usb_user_configuration_descriptor_ecm usb_conf_desc_ecm = {
|
||||
USB_CONFIG_DESC(
|
||||
sizeof(usb_conf_desc_ecm),
|
||||
2, // Interface Count
|
||||
USB_CONFIG_ECM, // value
|
||||
USB_STRING_CONFIG_ECM,
|
||||
CONF_ATTRIBUTES,
|
||||
MAX_POWER
|
||||
),
|
||||
CDC_ECM_INTERFACES
|
||||
};
|
||||
|
||||
FLASH S_usb_user_configuration_descriptor_ecm_debug usb_conf_desc_ecm_debug = {
|
||||
USB_CONFIG_DESC(
|
||||
sizeof(usb_conf_desc_ecm_debug),
|
||||
4, // Interface Count
|
||||
USB_CONFIG_ECM_DEBUG, // value
|
||||
USB_STRING_CONFIG_ECM_DEBUG,
|
||||
CONF_ATTRIBUTES,
|
||||
MAX_POWER
|
||||
),
|
||||
|
||||
USB_IAD(
|
||||
0x00, // First interface
|
||||
0x02, // Interface count
|
||||
0x02, // Function Class
|
||||
0x06, // Function Subclass
|
||||
0x00, // Function Protocol
|
||||
USB_STRING_INTERFACE_ECM
|
||||
),CDC_ECM_INTERFACES,
|
||||
|
||||
USB_IAD(
|
||||
0x02, // First interface
|
||||
0x02, // Interface count
|
||||
0x02, // Function Class
|
||||
0x02, // Function Subclass
|
||||
0x01, // Function Protocol
|
||||
USB_STRING_INTERFACE_SERIAL
|
||||
),CDC_SERIAL_INTERFACES
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/****************** MASS-STORAGE DEVICE DESCRIPTORS **************************/
|
||||
|
||||
/*
|
||||
FLASH S_usb_device_descriptor usb_dev_desc_mass =
|
||||
{
|
||||
sizeof(usb_dev_desc_mass)
|
||||
|
@ -396,11 +487,13 @@ FLASH S_usb_device_descriptor usb_dev_desc_mass =
|
|||
, Usb_write_word_enum_struc(VENDOR_ID)
|
||||
, Usb_write_word_enum_struc(MASS_PRODUCT_ID)
|
||||
, Usb_write_word_enum_struc(RELEASE_NUMBER)
|
||||
, MAN_INDEX
|
||||
, PROD_INDEX
|
||||
, SN_INDEX
|
||||
, USB_STRING_MAN
|
||||
, USB_STRING_PRODUCT
|
||||
, USB_STRING_SERIAL
|
||||
, NB_CONFIGURATION
|
||||
};
|
||||
*/
|
||||
#if USB_CONF_STORAGE
|
||||
|
||||
// usb_user_configuration_descriptor FS
|
||||
FLASH S_usb_user_configuration_descriptor_mass usb_conf_desc_mass = {
|
||||
|
@ -409,7 +502,7 @@ FLASH S_usb_user_configuration_descriptor_mass usb_conf_desc_mass = {
|
|||
, Usb_write_word_enum_struc(sizeof(S_usb_user_configuration_descriptor_mass))
|
||||
, MASS_NB_INTERFACE
|
||||
, CONF_NB
|
||||
, CONF_INDEX
|
||||
, USB_STRING_CONFIG_MS
|
||||
, CONF_ATTRIBUTES
|
||||
, MAX_POWER
|
||||
},//9
|
||||
|
@ -423,7 +516,7 @@ FLASH S_usb_user_configuration_descriptor_mass usb_conf_desc_mass = {
|
|||
, MS_INTERFACE_CLASS
|
||||
, MS_INTERFACE_SUB_CLASS
|
||||
, MS_INTERFACE_PROTOCOL
|
||||
, MS_INTERFACE_INDEX
|
||||
, USB_STRING_INTERFACE_MS
|
||||
} //9
|
||||
,
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
|
@ -443,96 +536,11 @@ FLASH S_usb_user_configuration_descriptor_mass usb_conf_desc_mass = {
|
|||
}
|
||||
};
|
||||
|
||||
/************* EEM-ONLY ***************/
|
||||
|
||||
// usb_user_device_descriptor
|
||||
FLASH S_usb_device_descriptor usb_dev_desc_eem =
|
||||
{
|
||||
sizeof(usb_dev_desc_composite)
|
||||
, DEVICE_DESCRIPTOR
|
||||
, Usb_write_word_enum_struc(USB_SPECIFICATION)
|
||||
, EEM_DEVICE_CLASS
|
||||
, EEM_DEVICE_SUB_CLASS
|
||||
, EEM_DEVICE_PROTOCOL
|
||||
, EP_CONTROL_LENGTH
|
||||
, Usb_write_word_enum_struc(VENDOR_ID)
|
||||
, Usb_write_word_enum_struc(COMPOSITE_PRODUCT_ID)
|
||||
, Usb_write_word_enum_struc(RELEASE_NUMBER)
|
||||
, MAN_INDEX
|
||||
, PROD_INDEX
|
||||
, SN_INDEX
|
||||
, NB_CONFIGURATION
|
||||
};
|
||||
|
||||
|
||||
// usb_user_configuration_descriptor FS
|
||||
FLASH S_usb_user_configuration_descriptor_eem usb_conf_desc_eem = {
|
||||
{ sizeof(S_usb_configuration_descriptor)
|
||||
, CONFIGURATION_DESCRIPTOR
|
||||
, Usb_write_word_enum_struc(sizeof(S_usb_user_configuration_descriptor_eem))
|
||||
, EEM_NB_INTERFACE
|
||||
, CONF_NB
|
||||
, CONF_INDEX
|
||||
, CONF_ATTRIBUTES
|
||||
, MAX_POWER
|
||||
},//9
|
||||
/// EEM DEVICE
|
||||
{ sizeof(S_usb_interface_descriptor)
|
||||
, INTERFACE_DESCRIPTOR
|
||||
, EEM_INTERFACE0_NB
|
||||
, EEM_ALTERNATE0
|
||||
, EEM_NB_ENDPOINT0
|
||||
, EEM_INTERFACE0_CLASS
|
||||
, EEM_INTERFACE0_SUB_CLASS
|
||||
, EEM_INTERFACE0_PROTOCOL
|
||||
, EEM_INTERFACE0_INDEX
|
||||
} //9
|
||||
,
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, EEM_ENDPOINT_NB_1
|
||||
, EEM_EP_ATTRIBUTES_1
|
||||
, Usb_write_word_enum_struc(EEM_EP_SIZE_1)
|
||||
, EEM_EP_INTERVAL_1
|
||||
} //7
|
||||
,
|
||||
{ sizeof(S_usb_endpoint_descriptor)
|
||||
, ENDPOINT_DESCRIPTOR
|
||||
, EEM_ENDPOINT_NB_2
|
||||
, EEM_EP_ATTRIBUTES_2
|
||||
, Usb_write_word_enum_struc(EEM_EP_SIZE_2)
|
||||
, EEM_EP_INTERVAL_2
|
||||
} //7
|
||||
};
|
||||
#endif
|
||||
|
||||
/************* COMMON *****************/
|
||||
|
||||
|
||||
// usb_user_manufacturer_string_descriptor
|
||||
FLASH S_usb_manufacturer_string_descriptor usb_user_manufacturer_string_descriptor = {
|
||||
sizeof(usb_user_manufacturer_string_descriptor)
|
||||
, STRING_DESCRIPTOR
|
||||
, USB_MANUFACTURER_NAME
|
||||
};
|
||||
|
||||
|
||||
// usb_user_product_string_descriptor
|
||||
|
||||
FLASH S_usb_product_string_descriptor usb_user_product_string_descriptor = {
|
||||
sizeof(usb_user_product_string_descriptor)
|
||||
, STRING_DESCRIPTOR
|
||||
, USB_PRODUCT_NAME
|
||||
};
|
||||
|
||||
|
||||
// usb_user_serial_number
|
||||
|
||||
FLASH S_usb_serial_number usb_user_serial_number = {
|
||||
sizeof(usb_user_serial_number)
|
||||
, STRING_DESCRIPTOR
|
||||
, USB_SERIAL_NUMBER
|
||||
};
|
||||
|
||||
|
||||
// usb_user_language_id
|
||||
|
||||
|
@ -548,6 +556,8 @@ FLASH S_usb_language_id usb_user_language_id = {
|
|||
|
||||
PGM_VOID_P Usb_get_dev_desc_pointer(void)
|
||||
{
|
||||
return &(usb_dev_desc_composite.bLength);
|
||||
/*
|
||||
if (usb_mode == rndis_only)
|
||||
return &(usb_dev_desc_network.bLength);
|
||||
|
||||
|
@ -558,11 +568,14 @@ PGM_VOID_P Usb_get_dev_desc_pointer(void)
|
|||
return &(usb_dev_desc_eem.bLength);
|
||||
|
||||
return &(usb_dev_desc_mass.bLength);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
U8 Usb_get_dev_desc_length(void)
|
||||
{
|
||||
return sizeof(usb_dev_desc_composite);
|
||||
/*
|
||||
|
||||
if (usb_mode == rndis_only)
|
||||
return sizeof(usb_dev_desc_network);
|
||||
|
@ -574,37 +587,54 @@ U8 Usb_get_dev_desc_length(void)
|
|||
return sizeof(usb_dev_desc_eem);
|
||||
|
||||
return sizeof(usb_dev_desc_mass);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
PGM_VOID_P Usb_get_conf_desc_pointer(void)
|
||||
PGM_VOID_P Usb_get_conf_desc_pointer(U8 index)
|
||||
{
|
||||
if (usb_mode == rndis_only)
|
||||
return &(usb_conf_desc_network.cfg.bLength);
|
||||
|
||||
if (usb_mode == rndis_debug)
|
||||
return &(usb_conf_desc_composite.cfg.bLength);
|
||||
|
||||
if (usb_mode == eem)
|
||||
return &(usb_conf_desc_eem.cfg.bLength);
|
||||
|
||||
return &(usb_conf_desc_mass.cfg.bLength);
|
||||
|
||||
switch(pgm_read_byte_near(&usb_dev_config_order[index])) {
|
||||
case USB_CONFIG_ECM:
|
||||
return &(usb_conf_desc_ecm.cfg.bLength);
|
||||
case USB_CONFIG_ECM_DEBUG:
|
||||
return &(usb_conf_desc_ecm_debug.cfg.bLength);
|
||||
case USB_CONFIG_RNDIS_DEBUG:
|
||||
return &(usb_conf_desc_composite.cfg.bLength);
|
||||
case USB_CONFIG_RNDIS:
|
||||
return &(usb_conf_desc_network.cfg.bLength);
|
||||
case USB_CONFIG_EEM:
|
||||
return &(usb_conf_desc_eem.cfg.bLength);
|
||||
#if USB_CONF_STORAGE
|
||||
case USB_CONFIG_MS:
|
||||
return &(usb_conf_desc_mass.cfg.bLength);
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
U8 Usb_get_conf_desc_length(void)
|
||||
U8 Usb_get_conf_desc_length(U8 index)
|
||||
{
|
||||
|
||||
if (usb_mode == rndis_only)
|
||||
return sizeof (usb_conf_desc_network);
|
||||
|
||||
if (usb_mode == rndis_debug)
|
||||
return sizeof(usb_conf_desc_composite);
|
||||
|
||||
if (usb_mode == eem)
|
||||
return sizeof(usb_conf_desc_eem);
|
||||
|
||||
return sizeof(usb_conf_desc_mass);
|
||||
switch(pgm_read_byte_near(&usb_dev_config_order[index])) {
|
||||
case USB_CONFIG_ECM:
|
||||
return sizeof(usb_conf_desc_ecm);
|
||||
case USB_CONFIG_ECM_DEBUG:
|
||||
return sizeof(usb_conf_desc_ecm_debug);
|
||||
case USB_CONFIG_RNDIS_DEBUG:
|
||||
return sizeof(usb_conf_desc_composite);
|
||||
case USB_CONFIG_RNDIS:
|
||||
return sizeof (usb_conf_desc_network);
|
||||
case USB_CONFIG_EEM:
|
||||
return sizeof(usb_conf_desc_eem);
|
||||
#if USB_CONF_STORAGE
|
||||
case USB_CONFIG_MS:
|
||||
return sizeof(usb_conf_desc_mass);
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -66,9 +66,9 @@
|
|||
// USB Device descriptor
|
||||
#define USB_SPECIFICATION 0x0200
|
||||
|
||||
#define COMPOSITE_DEVICE_CLASS 0xEF // Misc
|
||||
#define COMPOSITE_DEVICE_SUB_CLASS 0x02 // Common
|
||||
#define COMPOSITE_DEVICE_PROTOCOL 0x01 // IAD
|
||||
#define COMPOSITE_DEVICE_CLASS 0x02 // Misc
|
||||
#define COMPOSITE_DEVICE_SUB_CLASS 0x00 // Common
|
||||
#define COMPOSITE_DEVICE_PROTOCOL 0x00 // IAD
|
||||
|
||||
#define NETWORK_DEVICE_CLASS 0x02 // CDC ACM
|
||||
#define NETWORK_DEVICE_SUB_CLASS 0x02 //
|
||||
|
@ -88,10 +88,49 @@
|
|||
#define NETWORK_PRODUCT_ID 0x2019 //Product ID for just RNDIS device
|
||||
#define MASS_PRODUCT_ID 0x202F //Product ID for mass storage
|
||||
#define RELEASE_NUMBER 0x1000
|
||||
#define MAN_INDEX 0x01
|
||||
#define PROD_INDEX 0x02
|
||||
#define SN_INDEX 0x03
|
||||
#define NB_CONFIGURATION 1
|
||||
|
||||
enum {
|
||||
USB_STRING_NONE = 0,
|
||||
USB_STRING_MAN = 1,
|
||||
USB_STRING_PRODUCT,
|
||||
USB_STRING_SERIAL,
|
||||
USB_STRING_MAC_ADDRESS,
|
||||
USB_STRING_CONFIG_COMPOSITE,
|
||||
USB_STRING_CONFIG_RNDIS,
|
||||
USB_STRING_CONFIG_EEM,
|
||||
USB_STRING_CONFIG_ECM,
|
||||
USB_STRING_CONFIG_ECM_DEBUG,
|
||||
USB_STRING_CONFIG_MS,
|
||||
USB_STRING_INTERFACE_RNDIS,
|
||||
USB_STRING_INTERFACE_EEM,
|
||||
USB_STRING_INTERFACE_ECM,
|
||||
USB_STRING_INTERFACE_ECM_ATTACHED,
|
||||
USB_STRING_INTERFACE_ECM_DETACHED,
|
||||
USB_STRING_INTERFACE_SERIAL,
|
||||
USB_STRING_INTERFACE_MS,
|
||||
|
||||
};
|
||||
|
||||
enum {
|
||||
USB_CONFIG_UNCONFIGURED = 0,
|
||||
|
||||
USB_CONFIG_RNDIS = 1,
|
||||
USB_CONFIG_RNDIS_DEBUG = 1+(1<<7),
|
||||
|
||||
USB_CONFIG_ECM = 2,
|
||||
USB_CONFIG_ECM_DEBUG = 2+(1<<7),
|
||||
|
||||
USB_CONFIG_EEM = 3,
|
||||
|
||||
#if USB_CONF_STORAGE
|
||||
USB_CONFIG_MS = 4,
|
||||
#endif
|
||||
};
|
||||
|
||||
#define USB_CONFIG_HAS_DEBUG_PORT(x) ((x==USB_CONFIG_ECM_DEBUG)||(x==USB_CONFIG_RNDIS_DEBUG))
|
||||
|
||||
//#define USB_CONFIG_COUNT (USB_CONFIG_COUNT_PLUS_ONE-1)
|
||||
//#define NB_CONFIGURATION USB_CONFIG_COUNT
|
||||
|
||||
#define NETWORK_NB_INTERFACE 2
|
||||
#define COMPOSITE_NB_INTERFACE 4
|
||||
|
@ -134,14 +173,14 @@
|
|||
#define ENDPOINT_NB_2 0x80 | TX_EP
|
||||
#define EP_ATTRIBUTES_2 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||
#define EP_SIZE_2 0x40 //64 byte max size
|
||||
#define EP_INTERVAL_2 0x00
|
||||
#define EP_INTERVAL_2 0x01
|
||||
|
||||
// USB Endpoint 2 descriptor
|
||||
//Bulk OUT RX endpoint
|
||||
#define ENDPOINT_NB_3 RX_EP
|
||||
#define EP_ATTRIBUTES_3 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||
#define EP_SIZE_3 0x40 //64 byte max size
|
||||
#define EP_INTERVAL_3 0x00
|
||||
#define EP_INTERVAL_3 0x01
|
||||
|
||||
/*** CDC Virtual Serial Port ***/
|
||||
|
||||
|
@ -176,14 +215,14 @@
|
|||
#define ENDPOINT_NB_5 0x80 | VCP_TX_EP
|
||||
#define EP_ATTRIBUTES_5 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||
#define EP_SIZE_5 0x20
|
||||
#define EP_INTERVAL_5 0x00
|
||||
#define EP_INTERVAL_5 0x01
|
||||
|
||||
// USB Endpoint 6 descriptor
|
||||
// Bulk OUT
|
||||
#define ENDPOINT_NB_6 VCP_RX_EP
|
||||
#define EP_ATTRIBUTES_6 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||
#define EP_SIZE_6 0x20
|
||||
#define EP_INTERVAL_6 0x00
|
||||
#define EP_INTERVAL_6 0x01
|
||||
|
||||
|
||||
/*** Mass Storage ***/
|
||||
|
@ -227,61 +266,34 @@
|
|||
#define EEM_ENDPOINT_NB_1 0x80 | TX_EP
|
||||
#define EEM_EP_ATTRIBUTES_1 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||
#define EEM_EP_SIZE_1 0x40 //64 byte max size
|
||||
#define EEM_EP_INTERVAL_1 0x00
|
||||
#define EEM_EP_INTERVAL_1 0x01
|
||||
|
||||
// USB Endpoint 2 descriptor
|
||||
// Bulk OUT
|
||||
#define EEM_ENDPOINT_NB_2 RX_EP
|
||||
#define EEM_EP_ATTRIBUTES_2 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||
#define EEM_EP_SIZE_2 0x40 //64 byte max size
|
||||
#define EEM_EP_INTERVAL_2 0x00
|
||||
#define EEM_EP_INTERVAL_2 0x01
|
||||
|
||||
|
||||
/******* ECM Configuration *******/
|
||||
|
||||
// Interface 0 descriptor
|
||||
#define ECM_INTERFACE0_NB 0
|
||||
#define ECM_ALTERNATE0 0
|
||||
#define ECM_NB_ENDPOINT0 2
|
||||
#define ECM_INTERFACE0_CLASS 0x02 // CDC ACM Com
|
||||
#define ECM_INTERFACE0_SUB_CLASS 0x06 // ECM
|
||||
#define ECM_INTERFACE0_PROTOCOL 0x00 // Empty
|
||||
#define ECM_INTERFACE0_INDEX 0
|
||||
|
||||
|
||||
|
||||
#define DEVICE_STATUS 0x00 // TBD
|
||||
#define INTERFACE_STATUS 0x00 // TBD
|
||||
|
||||
#define LANG_ID 0x00
|
||||
|
||||
|
||||
|
||||
|
||||
#define USB_MN_LENGTH 5
|
||||
#define USB_MANUFACTURER_NAME \
|
||||
{ Usb_unicode('A') \
|
||||
, Usb_unicode('t') \
|
||||
, Usb_unicode('m') \
|
||||
, Usb_unicode('e') \
|
||||
, Usb_unicode('l') \
|
||||
}
|
||||
|
||||
#define USB_PN_LENGTH 16
|
||||
#define USB_PRODUCT_NAME \
|
||||
{ Usb_unicode('R') \
|
||||
,Usb_unicode('Z') \
|
||||
,Usb_unicode('R') \
|
||||
,Usb_unicode('A') \
|
||||
,Usb_unicode('V') \
|
||||
,Usb_unicode('E') \
|
||||
,Usb_unicode('N') \
|
||||
,Usb_unicode(' ') \
|
||||
,Usb_unicode('U') \
|
||||
,Usb_unicode('S') \
|
||||
,Usb_unicode('B') \
|
||||
,Usb_unicode(' ') \
|
||||
,Usb_unicode('D') \
|
||||
,Usb_unicode('E') \
|
||||
,Usb_unicode('M') \
|
||||
,Usb_unicode('O') \
|
||||
}
|
||||
|
||||
#define USB_SN_LENGTH 0x05
|
||||
#define USB_SERIAL_NUMBER \
|
||||
{Usb_unicode('1') \
|
||||
,Usb_unicode('.') \
|
||||
,Usb_unicode('0') \
|
||||
,Usb_unicode('.') \
|
||||
,Usb_unicode('0') \
|
||||
}
|
||||
|
||||
#define LANGUAGE_ID 0x0409
|
||||
|
||||
//! Usb Request
|
||||
|
@ -373,39 +385,6 @@ typedef struct {
|
|||
} S_usb_language_id;
|
||||
|
||||
|
||||
//_____ U S B M A N U F A C T U R E R D E S C R I P T O R _______________
|
||||
|
||||
|
||||
//struct usb_st_manufacturer
|
||||
typedef struct {
|
||||
U8 bLength; // size of this descriptor in bytes
|
||||
U8 bDescriptorType; // STRING descriptor type
|
||||
U16 wstring[USB_MN_LENGTH];// unicode characters
|
||||
} S_usb_manufacturer_string_descriptor;
|
||||
|
||||
|
||||
//_____ U S B P R O D U C T D E S C R I P T O R _________________________
|
||||
|
||||
|
||||
//struct usb_st_product
|
||||
typedef struct {
|
||||
U8 bLength; // size of this descriptor in bytes
|
||||
U8 bDescriptorType; // STRING descriptor type
|
||||
U16 wstring[USB_PN_LENGTH];// unicode characters
|
||||
} S_usb_product_string_descriptor;
|
||||
|
||||
|
||||
//_____ U S B S E R I A L N U M B E R D E S C R I P T O R _____________
|
||||
|
||||
|
||||
//struct usb_st_serial_number
|
||||
typedef struct {
|
||||
U8 bLength; // size of this descriptor in bytes
|
||||
U8 bDescriptorType; // STRING descriptor type
|
||||
U16 wstring[USB_SN_LENGTH];// unicode characters
|
||||
} S_usb_serial_number;
|
||||
|
||||
|
||||
/*_____ U S B I A D _______________________________________________________*/
|
||||
|
||||
#define DSC_TYPE_IAD 11
|
||||
|
@ -460,6 +439,79 @@ typedef struct
|
|||
|
||||
} S_usb_user_configuration_descriptor_network;
|
||||
|
||||
/* EEM */
|
||||
typedef struct
|
||||
{
|
||||
S_usb_configuration_descriptor cfg;
|
||||
S_usb_interface_descriptor ifc0;
|
||||
S_usb_endpoint_descriptor ep1;
|
||||
S_usb_endpoint_descriptor ep2;
|
||||
} S_usb_user_configuration_descriptor_eem;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U8 bLength;
|
||||
U8 bDescriptorType;
|
||||
U8 bDescriptorSubtype;
|
||||
U8 iMACAddress;
|
||||
U32 bmEthernetStatistics;
|
||||
U16 wMaxSegmentSize;
|
||||
U16 wNumberMCFilters;
|
||||
U8 bNumberPowerFilters;
|
||||
} S_usb_ethernet_networking_functional_descriptor;
|
||||
|
||||
|
||||
/* ECM */
|
||||
typedef struct
|
||||
{
|
||||
S_usb_configuration_descriptor cfg;
|
||||
S_usb_interface_descriptor ifc0;
|
||||
U8 CS1_INTERFACE[5+5];
|
||||
S_usb_ethernet_networking_functional_descriptor fd0;
|
||||
#if CDC_ECM_USES_INTERRUPT_ENDPOINT
|
||||
S_usb_endpoint_descriptor ep1;
|
||||
#endif
|
||||
#if 0
|
||||
S_usb_interface_descriptor ifc1_0;
|
||||
#endif
|
||||
S_usb_interface_descriptor ifc1_1;
|
||||
S_usb_endpoint_descriptor ep2;
|
||||
S_usb_endpoint_descriptor ep3;
|
||||
} S_usb_user_configuration_descriptor_ecm;
|
||||
|
||||
|
||||
/* ECM + Serial Port */
|
||||
typedef struct
|
||||
{
|
||||
S_usb_configuration_descriptor cfg;
|
||||
S_usb_interface_association_descriptor iad0;
|
||||
S_usb_interface_descriptor ifc0;
|
||||
U8 CS1_INTERFACE[5+5];
|
||||
S_usb_ethernet_networking_functional_descriptor fd0;
|
||||
#if CDC_ECM_USES_INTERRUPT_ENDPOINT
|
||||
S_usb_endpoint_descriptor ep1;
|
||||
#endif
|
||||
#if 0
|
||||
S_usb_interface_descriptor ifc1_0;
|
||||
#endif
|
||||
S_usb_interface_descriptor ifc1_1;
|
||||
S_usb_endpoint_descriptor ep2;
|
||||
S_usb_endpoint_descriptor ep3;
|
||||
|
||||
S_usb_interface_association_descriptor iad1;
|
||||
S_usb_interface_descriptor ifc2;
|
||||
U8 CS2_INTERFACE[19];
|
||||
S_usb_endpoint_descriptor ep4;
|
||||
S_usb_interface_descriptor ifc3;
|
||||
S_usb_endpoint_descriptor ep5;
|
||||
S_usb_endpoint_descriptor ep6;
|
||||
|
||||
} S_usb_user_configuration_descriptor_ecm_debug;
|
||||
|
||||
|
||||
/* Mass Storage */
|
||||
|
||||
typedef struct
|
||||
|
@ -471,20 +523,12 @@ typedef struct
|
|||
|
||||
} S_usb_user_configuration_descriptor_mass;
|
||||
|
||||
/* EEM */
|
||||
typedef struct
|
||||
{
|
||||
S_usb_configuration_descriptor cfg;
|
||||
S_usb_interface_descriptor ifc0;
|
||||
S_usb_endpoint_descriptor ep1;
|
||||
S_usb_endpoint_descriptor ep2;
|
||||
} S_usb_user_configuration_descriptor_eem;
|
||||
|
||||
|
||||
PGM_VOID_P Usb_get_dev_desc_pointer(void);
|
||||
U8 Usb_get_dev_desc_length(void);
|
||||
PGM_VOID_P Usb_get_conf_desc_pointer(void) ;
|
||||
U8 Usb_get_conf_desc_length(void);
|
||||
PGM_VOID_P Usb_get_conf_desc_pointer(U8 index) ;
|
||||
U8 Usb_get_conf_desc_length(U8 index);
|
||||
|
||||
#endif // _USB_USERCONFIG_H_
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "config.h"
|
||||
#include "conf_usb.h"
|
||||
#include "usb_drv.h"
|
||||
#include <util/delay.h>
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
@ -61,6 +62,102 @@
|
|||
|
||||
#if (USB_DEVICE_FEATURE == ENABLED)
|
||||
|
||||
#define USB_ENDPOINT_WAIT_TIMEOUT 250
|
||||
|
||||
U8 usb_endpoint_wait_for_write_enabled() {
|
||||
#if USB_ENDPOINT_WAIT_TIMEOUT
|
||||
U16 timeout=USB_ENDPOINT_WAIT_TIMEOUT;
|
||||
while(timeout) {
|
||||
if(Is_usb_sof()) {
|
||||
Usb_ack_sof();
|
||||
timeout--;
|
||||
}
|
||||
#else
|
||||
while(1) {
|
||||
#endif
|
||||
if(Is_usb_write_enabled())
|
||||
return 0;
|
||||
if((!Is_usb_enabled()) || Is_usb_detached())
|
||||
return 1;
|
||||
if(!Is_usb_endpoint_enabled())
|
||||
return 2;
|
||||
if(Is_usb_endpoint_stall_requested())
|
||||
return 3;
|
||||
}
|
||||
return 10;
|
||||
}
|
||||
|
||||
U8 usb_endpoint_wait_for_read_control_enabled() {
|
||||
#if USB_ENDPOINT_WAIT_TIMEOUT
|
||||
U16 timeout=USB_ENDPOINT_WAIT_TIMEOUT;
|
||||
while(timeout) {
|
||||
if(Is_usb_sof()) {
|
||||
Usb_ack_sof();
|
||||
timeout--;
|
||||
}
|
||||
#else
|
||||
while(1) {
|
||||
#endif
|
||||
if(Is_usb_read_control_enabled())
|
||||
return 0;
|
||||
if((!Is_usb_enabled()) || Is_usb_detached())
|
||||
return 1;
|
||||
if(!Is_usb_endpoint_enabled())
|
||||
return 2;
|
||||
if(Is_usb_endpoint_stall_requested())
|
||||
return 3;
|
||||
}
|
||||
return 10;
|
||||
}
|
||||
|
||||
|
||||
U8 usb_endpoint_wait_for_IN_ready() {
|
||||
#if USB_ENDPOINT_WAIT_TIMEOUT
|
||||
U16 timeout=USB_ENDPOINT_WAIT_TIMEOUT;
|
||||
while(timeout) {
|
||||
if(Is_usb_sof()) {
|
||||
Usb_ack_sof();
|
||||
timeout--;
|
||||
}
|
||||
#else
|
||||
while(1) {
|
||||
#endif
|
||||
if(Is_usb_in_ready())
|
||||
return 0;
|
||||
if((!Is_usb_enabled()) || Is_usb_detached())
|
||||
return 1;
|
||||
if(!Is_usb_endpoint_enabled())
|
||||
return 2;
|
||||
if(Is_usb_endpoint_stall_requested())
|
||||
return 3;
|
||||
}
|
||||
return 10;
|
||||
}
|
||||
|
||||
|
||||
U8 usb_endpoint_wait_for_receive_out() {
|
||||
#if USB_ENDPOINT_WAIT_TIMEOUT
|
||||
U16 timeout=USB_ENDPOINT_WAIT_TIMEOUT;
|
||||
while(timeout) {
|
||||
if(Is_usb_sof()) {
|
||||
Usb_ack_sof();
|
||||
timeout--;
|
||||
}
|
||||
#else
|
||||
while(1) {
|
||||
#endif
|
||||
if(Is_usb_receive_out())
|
||||
return 0;
|
||||
if((!Is_usb_enabled()) || Is_usb_detached())
|
||||
return 1;
|
||||
if(!Is_usb_endpoint_enabled())
|
||||
return 2;
|
||||
if(Is_usb_endpoint_stall_requested())
|
||||
return 3;
|
||||
}
|
||||
return 10;
|
||||
}
|
||||
|
||||
//! usb_configure_endpoint.
|
||||
//!
|
||||
//! This function configures an endpoint with the selected type.
|
||||
|
|
|
@ -160,7 +160,7 @@ typedef enum endpoint_parameter{ep_num, ep_type, ep_direction, ep_size, ep_bank,
|
|||
//! @defgroup Endpoints_configuration Configuration macros for endpoints
|
||||
//! List of the standard macro used to configure pipes and endpoints
|
||||
//! @{
|
||||
#define Usb_build_ep_config0(type, dir, nyet) ((type<<6) | (nyet<<1) | (dir))
|
||||
#define Usb_build_ep_config0(type, dir, nyet) ((type<<6) /*| (nyet<<1)*/ | (dir))
|
||||
#define Usb_build_ep_config1(size, bank ) ((size<<4) | (bank<<2) )
|
||||
#define usb_configure_endpoint(num, type, dir, size, bank, nyet) \
|
||||
( Usb_select_endpoint(num), \
|
||||
|
@ -929,6 +929,13 @@ U8 host_determine_pipe_size (U16);
|
|||
void host_disable_all_pipe (void);
|
||||
U8 usb_get_nb_pipe_interrupt (void);
|
||||
|
||||
U8 usb_endpoint_wait_for_read_control_enabled();
|
||||
U8 usb_endpoint_wait_for_write_enabled();
|
||||
U8 usb_endpoint_wait_for_receive_out();
|
||||
U8 usb_endpoint_wait_for_IN_ready();
|
||||
|
||||
#define usb_endpoint_wait_for_read_enabled usb_endpoint_wait_for_write_enabled
|
||||
|
||||
#endif // _USB_DRV_H_
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -50,10 +50,12 @@
|
|||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "rndis/rndis_protocol.h"
|
||||
#include "rndis/cdc_ecm.h"
|
||||
#include "serial/uart_usb_lib.h"
|
||||
#include "storage/ctrl_access.h"
|
||||
#include "uip.h"
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <string.h>
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
@ -85,30 +87,44 @@ Bool usb_user_read_request(U8 type, U8 request)
|
|||
{
|
||||
U16 wLength;
|
||||
|
||||
//Both protocols have two bytes we throw away
|
||||
Usb_read_byte();
|
||||
Usb_read_byte();
|
||||
|
||||
switch(request)
|
||||
{
|
||||
case SEND_ENCAPSULATED_COMMAND:
|
||||
Usb_read_byte();
|
||||
Usb_read_byte();
|
||||
Usb_read_byte();//wIndex LSB
|
||||
Usb_read_byte();//wIndex MSB
|
||||
|
||||
LSB(wLength) = Usb_read_byte();
|
||||
MSB(wLength) = Usb_read_byte();
|
||||
return send_encapsulated_command(wLength);
|
||||
if((usb_configuration_nb==USB_CONFIG_RNDIS)||(usb_configuration_nb==USB_CONFIG_RNDIS_DEBUG))
|
||||
return rndis_send_encapsulated_command(wLength);
|
||||
else
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case GET_ENCAPSULATED_COMMAND:
|
||||
Usb_read_byte();
|
||||
Usb_read_byte();
|
||||
Usb_read_byte();//wIndex LSB
|
||||
Usb_read_byte();//wIndex MSB
|
||||
|
||||
LSB(wLength) = Usb_read_byte();
|
||||
MSB(wLength) = Usb_read_byte();
|
||||
return get_encapsulated_command();
|
||||
if((usb_configuration_nb==USB_CONFIG_RNDIS)||(usb_configuration_nb==USB_CONFIG_RNDIS_DEBUG))
|
||||
return rndis_get_encapsulated_command();
|
||||
else
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case SET_ETHERNET_PACKET_FILTER:
|
||||
if((usb_configuration_nb==USB_CONFIG_ECM) || (usb_configuration_nb==USB_CONFIG_ECM_DEBUG)) {
|
||||
cdc_ecm_set_ethernet_packet_filter();
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
#if USB_CONF_STORAGE
|
||||
case MASS_STORAGE_RESET:
|
||||
Usb_ack_receive_setup();
|
||||
|
@ -130,18 +146,34 @@ Bool usb_user_read_request(U8 type, U8 request)
|
|||
/* We don't have a real serial port - so these aren't applicable. We
|
||||
advertise that we support nothing, so shouldn't get them anyway */
|
||||
case GET_LINE_CODING:
|
||||
cdc_get_line_coding();
|
||||
return TRUE;
|
||||
Usb_read_byte();
|
||||
Usb_read_byte();
|
||||
if(USB_CONFIG_HAS_DEBUG_PORT(usb_configuration_nb)) {
|
||||
cdc_get_line_coding();
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case SET_LINE_CODING:
|
||||
cdc_set_line_coding();
|
||||
return TRUE;
|
||||
Usb_read_byte();
|
||||
Usb_read_byte();
|
||||
if(USB_CONFIG_HAS_DEBUG_PORT(usb_configuration_nb)) {
|
||||
cdc_set_line_coding();
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case SET_CONTROL_LINE_STATE:
|
||||
cdc_set_control_line_state();
|
||||
return TRUE;
|
||||
if(USB_CONFIG_HAS_DEBUG_PORT(usb_configuration_nb)) {
|
||||
cdc_set_control_line_state();
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
#endif /* USB_CONF_CDC */
|
||||
default:
|
||||
|
@ -174,21 +206,6 @@ Bool usb_user_get_descriptor(U8 type, U8 string)
|
|||
pbuffer = &(usb_user_language_id.bLength);
|
||||
return TRUE;
|
||||
break;
|
||||
case MAN_INDEX:
|
||||
data_to_transfer = sizeof (usb_user_manufacturer_string_descriptor);
|
||||
pbuffer = &(usb_user_manufacturer_string_descriptor.bLength);
|
||||
return TRUE;
|
||||
break;
|
||||
case PROD_INDEX:
|
||||
data_to_transfer = sizeof (usb_user_product_string_descriptor);
|
||||
pbuffer = &(usb_user_product_string_descriptor.bLength);
|
||||
return TRUE;
|
||||
break;
|
||||
case SN_INDEX:
|
||||
data_to_transfer = sizeof (usb_user_serial_number);
|
||||
pbuffer = &(usb_user_serial_number.bLength);
|
||||
return TRUE;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -198,6 +215,94 @@ Bool usb_user_get_descriptor(U8 type, U8 string)
|
|||
|
||||
return FALSE;
|
||||
}
|
||||
static char itoh(unsigned char i) {
|
||||
char ret;
|
||||
ret = pgm_read_byte_near(PSTR("0123456789abcdef")+(i&0xF));
|
||||
return ret;
|
||||
}
|
||||
const char* usb_user_get_string_sram(U8 string_type) {
|
||||
static char serial[13];
|
||||
uint8_t i;
|
||||
|
||||
switch (string_type)
|
||||
{
|
||||
case USB_STRING_SERIAL:
|
||||
case USB_STRING_MAC_ADDRESS:
|
||||
{
|
||||
uint8_t mac_address[6];
|
||||
usb_eth_get_mac_address(mac_address);
|
||||
|
||||
for(i=0;i<6;i++) {
|
||||
serial[i*2] = itoh(mac_address[i]>>4);
|
||||
serial[i*2+1] = itoh(mac_address[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
serial[0] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return serial;
|
||||
}
|
||||
|
||||
PGM_P usb_user_get_string(U8 string_type) {
|
||||
switch (string_type)
|
||||
{
|
||||
case USB_STRING_MAN:
|
||||
return PSTR("Atmel");
|
||||
|
||||
case USB_STRING_PRODUCT:
|
||||
return PSTR("Jackdaw 6LoWPAN Adaptor");
|
||||
|
||||
case USB_STRING_CONFIG_COMPOSITE:
|
||||
return PSTR("RNDIS+Debug");
|
||||
|
||||
case USB_STRING_CONFIG_RNDIS:
|
||||
case USB_STRING_INTERFACE_RNDIS:
|
||||
return PSTR("RNDIS");
|
||||
|
||||
case USB_STRING_CONFIG_EEM:
|
||||
case USB_STRING_INTERFACE_EEM:
|
||||
return PSTR("CDC-EEM");
|
||||
|
||||
case USB_STRING_CONFIG_ECM:
|
||||
case USB_STRING_INTERFACE_ECM:
|
||||
return PSTR("CDC-ECM");
|
||||
|
||||
case USB_STRING_CONFIG_ECM_DEBUG:
|
||||
return PSTR("CDC-ECM+DEBUG");
|
||||
|
||||
case USB_STRING_INTERFACE_SERIAL:
|
||||
return PSTR("Debug Port");
|
||||
/*
|
||||
case USB_STRING_INTERFACE_ECM_ATTACHED:
|
||||
return PSTR("Attached");
|
||||
case USB_STRING_INTERFACE_ECM_DETACHED:
|
||||
return PSTR("Detached");
|
||||
*/
|
||||
#if USB_CONF_STORAGE
|
||||
case USB_STRING_CONFIG_MS:
|
||||
case USB_STRING_INTERFACE_MS:
|
||||
return PSTR("Mass Storage");
|
||||
#endif
|
||||
|
||||
/*
|
||||
// This is now handled by usb_user_get_string_sram.
|
||||
case USB_STRING_SERIAL:
|
||||
return PSTR("JD01");
|
||||
|
||||
case USB_STRING_MAC_ADDRESS:
|
||||
return PSTR("021213141516");
|
||||
|
||||
*/
|
||||
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! usb_user_endpoint_init.
|
||||
//!
|
||||
|
@ -206,115 +311,54 @@ Bool usb_user_get_descriptor(U8 type, U8 string)
|
|||
//! @param conf_nb Not used
|
||||
void usb_user_endpoint_init(U8 conf_nb)
|
||||
{
|
||||
if(USB_CONFIG_HAS_DEBUG_PORT(conf_nb)) {
|
||||
uart_usb_configure_endpoints();
|
||||
}
|
||||
|
||||
/* If we use RNDIS endpoints */
|
||||
if ((usb_mode == rndis_only) || (usb_mode == rndis_debug)) {
|
||||
switch(conf_nb) {
|
||||
case USB_CONFIG_ECM:
|
||||
case USB_CONFIG_ECM_DEBUG:
|
||||
cdc_ecm_configure_endpoints();
|
||||
break;
|
||||
|
||||
usb_configure_endpoint(INT_EP, \
|
||||
TYPE_INTERRUPT, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_64, \
|
||||
ONE_BANK, \
|
||||
NYET_ENABLED);
|
||||
case USB_CONFIG_RNDIS_DEBUG:
|
||||
case USB_CONFIG_RNDIS:
|
||||
rndis_configure_endpoints();
|
||||
break;
|
||||
case USB_CONFIG_EEM:
|
||||
cdc_ecm_configure_endpoints();
|
||||
|
||||
usb_configure_endpoint(TX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_64, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
break;
|
||||
#if USB_CONF_STORAGE
|
||||
case USB_CONFIG_MS:
|
||||
usb_configure_endpoint(VCP_INT_EP, \
|
||||
TYPE_INTERRUPT, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_32, \
|
||||
ONE_BANK, \
|
||||
NYET_ENABLED);
|
||||
|
||||
usb_configure_endpoint(RX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_OUT, \
|
||||
SIZE_64, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
usb_configure_endpoint(VCP_TX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_32, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
|
||||
}
|
||||
|
||||
/* If we use virtual comm port (VCP) endpoints */
|
||||
if (usb_mode == rndis_debug) {
|
||||
usb_configure_endpoint(VCP_INT_EP, \
|
||||
TYPE_INTERRUPT, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_32, \
|
||||
ONE_BANK, \
|
||||
NYET_ENABLED);
|
||||
|
||||
usb_configure_endpoint(VCP_TX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_32, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
|
||||
usb_configure_endpoint(VCP_RX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_OUT, \
|
||||
SIZE_32, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
}
|
||||
|
||||
/* If we use mass storage endpoints */
|
||||
if (usb_mode == mass_storage) {
|
||||
|
||||
usb_configure_endpoint(MS_IN_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_64, \
|
||||
ONE_BANK, \
|
||||
NYET_ENABLED);
|
||||
|
||||
usb_configure_endpoint(MS_OUT_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_OUT, \
|
||||
SIZE_64, \
|
||||
ONE_BANK, \
|
||||
NYET_ENABLED);
|
||||
}
|
||||
|
||||
if (usb_mode == eem ) {
|
||||
usb_configure_endpoint(TX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_IN, \
|
||||
SIZE_64, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
|
||||
usb_configure_endpoint(RX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_OUT, \
|
||||
SIZE_64, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((usb_mode == rndis_only) || (usb_mode == rndis_debug)) {
|
||||
Usb_reset_endpoint(INT_EP);
|
||||
Usb_reset_endpoint(TX_EP);
|
||||
Usb_reset_endpoint(RX_EP);
|
||||
}
|
||||
|
||||
if (usb_mode == rndis_debug){
|
||||
Usb_reset_endpoint(VCP_INT_EP);
|
||||
Usb_reset_endpoint(VCP_TX_EP);
|
||||
Usb_reset_endpoint(VCP_RX_EP);
|
||||
}
|
||||
|
||||
if (usb_mode == mass_storage) {
|
||||
Usb_reset_endpoint(VCP_TX_EP);
|
||||
Usb_reset_endpoint(VCP_RX_EP);
|
||||
}
|
||||
|
||||
if (usb_mode == eem){
|
||||
Usb_reset_endpoint(TX_EP);
|
||||
Usb_reset_endpoint(RX_EP);
|
||||
}
|
||||
usb_configure_endpoint(VCP_RX_EP, \
|
||||
TYPE_BULK, \
|
||||
DIRECTION_OUT, \
|
||||
SIZE_32, \
|
||||
TWO_BANKS, \
|
||||
NYET_ENABLED);
|
||||
Usb_reset_endpoint(VCP_INT_EP);
|
||||
Usb_reset_endpoint(VCP_TX_EP);
|
||||
Usb_reset_endpoint(VCP_RX_EP);
|
||||
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
Led0_on();
|
||||
}
|
||||
|
||||
#if USB_CONF_CDC
|
||||
|
@ -337,12 +381,7 @@ void cdc_get_line_coding(void)
|
|||
Usb_write_byte(line_coding.bParityType);
|
||||
Usb_write_byte(line_coding.bDataBits);
|
||||
|
||||
Usb_send_control_in();
|
||||
while(!(Is_usb_read_control_enabled()));
|
||||
//Usb_clear_tx_complete();
|
||||
|
||||
while(!Is_usb_receive_out());
|
||||
Usb_ack_receive_out();
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
|
||||
|
@ -352,19 +391,20 @@ void cdc_get_line_coding(void)
|
|||
//!
|
||||
void cdc_set_line_coding (void)
|
||||
{
|
||||
Usb_ack_receive_setup();
|
||||
while (!(Is_usb_receive_out()));
|
||||
LSB0(line_coding.dwDTERate) = Usb_read_byte();
|
||||
LSB1(line_coding.dwDTERate) = Usb_read_byte();
|
||||
LSB2(line_coding.dwDTERate) = Usb_read_byte();
|
||||
LSB3(line_coding.dwDTERate) = Usb_read_byte();
|
||||
line_coding.bCharFormat = Usb_read_byte();
|
||||
line_coding.bParityType = Usb_read_byte();
|
||||
line_coding.bDataBits = Usb_read_byte();
|
||||
Usb_ack_receive_out();
|
||||
Usb_ack_receive_setup();
|
||||
if(usb_endpoint_wait_for_receive_out()==0) {
|
||||
LSB0(line_coding.dwDTERate) = Usb_read_byte();
|
||||
LSB1(line_coding.dwDTERate) = Usb_read_byte();
|
||||
LSB2(line_coding.dwDTERate) = Usb_read_byte();
|
||||
LSB3(line_coding.dwDTERate) = Usb_read_byte();
|
||||
line_coding.bCharFormat = Usb_read_byte();
|
||||
line_coding.bParityType = Usb_read_byte();
|
||||
line_coding.bDataBits = Usb_read_byte();
|
||||
Usb_ack_receive_out();
|
||||
|
||||
Usb_send_control_in(); // send a ZLP for STATUS phase
|
||||
while(!(Is_usb_read_control_enabled()));
|
||||
Usb_send_control_in(); // send a ZLP for STATUS phase
|
||||
usb_endpoint_wait_for_read_control_enabled();
|
||||
}
|
||||
}
|
||||
|
||||
//! cdc_set_control_line_state.
|
||||
|
@ -375,8 +415,27 @@ void cdc_set_line_coding (void)
|
|||
//!
|
||||
void cdc_set_control_line_state (void)
|
||||
{
|
||||
U8 controlLineState = Usb_read_byte();
|
||||
U8 dummy = Usb_read_byte();
|
||||
U8 interface = Usb_read_byte();
|
||||
|
||||
Usb_ack_receive_setup();
|
||||
Usb_send_control_in();
|
||||
while(!(Is_usb_read_control_enabled()));
|
||||
usb_endpoint_wait_for_read_control_enabled();
|
||||
|
||||
if(interface == INTERFACE2_NB) {
|
||||
uart_usb_set_control_line_state(controlLineState);
|
||||
}
|
||||
}
|
||||
#endif /* USB_CONF_CDC */
|
||||
|
||||
Bool usb_user_set_alt_interface(U8 interface, U8 alt_setting) {
|
||||
return FALSE;
|
||||
if((interface==ECM_INTERFACE0_NB) && ((usb_configuration_nb==USB_CONFIG_ECM) || (usb_configuration_nb==USB_CONFIG_ECM_DEBUG))) {
|
||||
// The alt_setting in this case corresponds to
|
||||
// if the interface is enabled or not.
|
||||
usb_eth_set_active(alt_setting);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,9 +65,6 @@ extern FLASH S_usb_device_descriptor usb_dev_desc_network;
|
|||
extern FLASH S_usb_user_configuration_descriptor_composite usb_conf_desc_composite;
|
||||
extern FLASH S_usb_user_configuration_descriptor_network usb_conf_desc_network;
|
||||
extern FLASH S_usb_device_qualifier_descriptor usb_qual_desc;
|
||||
extern FLASH S_usb_manufacturer_string_descriptor usb_user_manufacturer_string_descriptor;
|
||||
extern FLASH S_usb_product_string_descriptor usb_user_product_string_descriptor;
|
||||
extern FLASH S_usb_serial_number usb_user_serial_number;
|
||||
extern FLASH S_usb_language_id usb_user_language_id;
|
||||
|
||||
|
||||
|
@ -76,6 +73,10 @@ extern FLASH S_usb_language_id usb_user_language_id;
|
|||
Bool usb_user_read_request(U8, U8);
|
||||
Bool usb_user_get_descriptor(U8 , U8);
|
||||
void usb_user_endpoint_init(U8);
|
||||
Bool usb_user_set_alt_interface(U8 interface, U8 alt_setting);
|
||||
|
||||
PGM_P usb_user_get_string(U8 string_type);
|
||||
const char* usb_user_get_string_sram(U8 string_type);
|
||||
|
||||
void cdc_get_line_coding();
|
||||
void cdc_set_line_coding();
|
||||
|
|
|
@ -52,11 +52,14 @@
|
|||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include <string.h>
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
//_____ D E F I N I T I O N ________________________________________________
|
||||
#define PRINTF printf
|
||||
#define PRINTF_P printf_P
|
||||
|
||||
//_____ P R I V A T E D E C L A R A T I O N ______________________________
|
||||
|
||||
|
@ -123,43 +126,43 @@ void usb_process_request(void)
|
|||
{
|
||||
case GET_DESCRIPTOR:
|
||||
if (0x80 == bmRequestType) { usb_get_descriptor(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
else goto user_read;
|
||||
break;
|
||||
|
||||
case GET_CONFIGURATION:
|
||||
if (0x80 == bmRequestType) { usb_get_configuration(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
else goto user_read;
|
||||
break;
|
||||
|
||||
case SET_ADDRESS:
|
||||
if (0x00 == bmRequestType) { usb_set_address(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
else goto user_read;
|
||||
break;
|
||||
|
||||
case SET_CONFIGURATION:
|
||||
if (0x00 == bmRequestType) { usb_set_configuration(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
else goto user_read;
|
||||
break;
|
||||
|
||||
case CLEAR_FEATURE:
|
||||
if (0x02 >= bmRequestType) { usb_clear_feature(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
else goto user_read;
|
||||
break;
|
||||
|
||||
case SET_FEATURE:
|
||||
if (0x02 >= bmRequestType) { usb_set_feature(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
else goto user_read;
|
||||
break;
|
||||
|
||||
case GET_STATUS:
|
||||
if ((0x7F < bmRequestType) & (0x82 >= bmRequestType))
|
||||
{ usb_get_status(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
else goto user_read;
|
||||
break;
|
||||
|
||||
case GET_INTERFACE:
|
||||
if (bmRequestType == 0x81) { usb_get_interface(); }
|
||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
||||
else goto user_read;
|
||||
break;
|
||||
|
||||
|
||||
|
@ -170,14 +173,23 @@ void usb_process_request(void)
|
|||
case SET_DESCRIPTOR:
|
||||
case SYNCH_FRAME:
|
||||
default: //!< un-supported request => call to user read request
|
||||
if(usb_user_read_request(bmRequestType, bmRequest) == FALSE)
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
user_read:
|
||||
usb_user_read_request(bmRequestType, bmRequest);
|
||||
break;
|
||||
}
|
||||
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
|
||||
// If the receive setup flag hasn't been cleared
|
||||
// by this point then we can assume that we didn't
|
||||
// support this request and should stall.
|
||||
if(Is_usb_receive_setup())
|
||||
Usb_enable_stall_handshake();
|
||||
|
||||
// Clear some flags.
|
||||
Usb_ack_receive_setup();
|
||||
Usb_ack_receive_out();
|
||||
Usb_ack_in_ready();
|
||||
}
|
||||
|
||||
//! usb_set_address.
|
||||
|
@ -214,26 +226,205 @@ U8 configuration_number;
|
|||
|
||||
configuration_number = Usb_read_byte();
|
||||
|
||||
if (configuration_number <= NB_CONFIGURATION)
|
||||
{
|
||||
Usb_ack_receive_setup();
|
||||
usb_configuration_nb = configuration_number;
|
||||
}
|
||||
else
|
||||
{
|
||||
//!< keep that order (set StallRq/clear RxSetup) or a
|
||||
//!< OUT request following the SETUP may be acknowledged
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
// TODO: Verify configuration_number!
|
||||
Usb_ack_receive_setup();
|
||||
usb_configuration_nb = configuration_number;
|
||||
|
||||
Usb_send_control_in(); //!< send a ZLP for STATUS phase
|
||||
while(!Is_usb_in_ready());
|
||||
|
||||
usb_user_endpoint_init(usb_configuration_nb); //!< endpoint configuration
|
||||
Usb_set_configuration_action();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void usb_get_string_descriptor_sram(U8 string_type) {
|
||||
U16 requested_length;
|
||||
U8 dummy;
|
||||
const char* user_str;
|
||||
|
||||
user_str = usb_user_get_string_sram(string_type);
|
||||
|
||||
dummy = Usb_read_byte(); //!< don't care of wIndex field
|
||||
dummy = Usb_read_byte();
|
||||
requested_length = Usb_read_byte(); //!< read wLength
|
||||
requested_length |= Usb_read_byte()<<8;
|
||||
|
||||
if(!user_str)
|
||||
return;
|
||||
|
||||
const U8 actual_descriptor_size = 2+strlen(user_str)*2;
|
||||
|
||||
if (requested_length > actual_descriptor_size) {
|
||||
zlp = ((actual_descriptor_size % EP_CONTROL_LENGTH) == 0);
|
||||
requested_length = actual_descriptor_size;
|
||||
}
|
||||
|
||||
Usb_ack_receive_setup() ; //!< clear the receive setup flag
|
||||
|
||||
if(usb_endpoint_wait_for_read_control_enabled()!=0) {
|
||||
Usb_enable_stall_handshake();
|
||||
return;
|
||||
}
|
||||
|
||||
// Output the length
|
||||
Usb_write_byte(actual_descriptor_size);
|
||||
|
||||
// Output the type
|
||||
Usb_write_byte(STRING_DESCRIPTOR);
|
||||
|
||||
requested_length -= 2;
|
||||
U8 nb_byte = 2;
|
||||
|
||||
if(!requested_length) {
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
while((requested_length != 0) && (!Is_usb_receive_out()))
|
||||
{
|
||||
if(usb_endpoint_wait_for_read_control_enabled()!=0) {
|
||||
Usb_enable_stall_handshake();
|
||||
break;
|
||||
}
|
||||
|
||||
while(requested_length != 0) //!< Send data until necessary
|
||||
{
|
||||
if(nb_byte==EP_CONTROL_LENGTH) //!< Check endpoint 0 size
|
||||
{
|
||||
nb_byte=0;
|
||||
break;
|
||||
}
|
||||
|
||||
Usb_write_byte(*user_str);
|
||||
Usb_write_byte(0);
|
||||
user_str++;
|
||||
requested_length -=2;
|
||||
nb_byte+=2;
|
||||
}
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
bail:
|
||||
if(Is_usb_receive_out()) {
|
||||
//! abort from Host
|
||||
Usb_ack_receive_out();
|
||||
return;
|
||||
}
|
||||
|
||||
if(zlp == TRUE) {
|
||||
if(usb_endpoint_wait_for_read_control_enabled()!=0) {
|
||||
Usb_enable_stall_handshake();
|
||||
return;
|
||||
}
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
usb_endpoint_wait_for_receive_out();
|
||||
Usb_ack_receive_out();
|
||||
}
|
||||
|
||||
|
||||
void usb_get_string_descriptor(U8 string_type) {
|
||||
U16 requested_length;
|
||||
U8 dummy;
|
||||
PGM_P user_str;
|
||||
|
||||
user_str = usb_user_get_string(string_type);
|
||||
|
||||
if(!user_str) {
|
||||
usb_get_string_descriptor_sram(string_type);
|
||||
return;
|
||||
}
|
||||
|
||||
dummy = Usb_read_byte(); //!< don't care of wIndex field
|
||||
dummy = Usb_read_byte();
|
||||
requested_length = Usb_read_byte(); //!< read wLength
|
||||
requested_length |= Usb_read_byte()<<8;
|
||||
|
||||
|
||||
const U8 actual_descriptor_size = 2+strlen_P(user_str)*2;
|
||||
|
||||
if (requested_length > actual_descriptor_size) {
|
||||
zlp = ((actual_descriptor_size % EP_CONTROL_LENGTH) == 0);
|
||||
requested_length = actual_descriptor_size;
|
||||
}
|
||||
|
||||
Usb_ack_receive_setup() ; //!< clear the receive setup flag
|
||||
|
||||
if(usb_endpoint_wait_for_read_control_enabled()!=0) {
|
||||
Usb_enable_stall_handshake();
|
||||
return;
|
||||
}
|
||||
U8 nb_byte = 0;
|
||||
|
||||
// Output the length
|
||||
if(requested_length) {
|
||||
Usb_write_byte(actual_descriptor_size);
|
||||
requested_length--;
|
||||
nb_byte++;
|
||||
}
|
||||
|
||||
// Output the type
|
||||
if(requested_length) {
|
||||
Usb_write_byte(STRING_DESCRIPTOR);
|
||||
requested_length--;
|
||||
nb_byte++;
|
||||
}
|
||||
|
||||
if(!requested_length) {
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
while((requested_length != 0) && (!Is_usb_receive_out()))
|
||||
{
|
||||
if(usb_endpoint_wait_for_read_control_enabled()!=0) {
|
||||
Usb_enable_stall_handshake();
|
||||
break;
|
||||
}
|
||||
|
||||
while(requested_length != 0) //!< Send data until necessary
|
||||
{
|
||||
if(nb_byte==EP_CONTROL_LENGTH) { //!< Check endpoint 0 size
|
||||
nb_byte=0;
|
||||
break;
|
||||
}
|
||||
|
||||
Usb_write_byte(pgm_read_byte_near((unsigned int)user_str++));
|
||||
requested_length--;
|
||||
nb_byte++;
|
||||
if(requested_length) {
|
||||
Usb_write_byte(0);
|
||||
requested_length--;
|
||||
nb_byte++;
|
||||
}
|
||||
}
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
bail:
|
||||
|
||||
if(Is_usb_receive_out()) {
|
||||
//! abort from Host
|
||||
Usb_ack_receive_out();
|
||||
return;
|
||||
}
|
||||
|
||||
if(zlp == TRUE) {
|
||||
if(usb_endpoint_wait_for_read_control_enabled()!=0) {
|
||||
Usb_enable_stall_handshake();
|
||||
return;
|
||||
}
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
usb_endpoint_wait_for_receive_out();
|
||||
Usb_ack_receive_out();
|
||||
}
|
||||
|
||||
|
||||
//! usb_get_descriptor.
|
||||
//!
|
||||
//! This function manages the GET DESCRIPTOR request. The device descriptor,
|
||||
|
@ -246,91 +437,93 @@ U8 configuration_number;
|
|||
//!
|
||||
void usb_get_descriptor(void)
|
||||
{
|
||||
U8 LSBwLength, MSBwLength;
|
||||
U8 descriptor_type ;
|
||||
U8 string_type ;
|
||||
U8 dummy;
|
||||
U8 nb_byte;
|
||||
U8 LSBwLength, MSBwLength;
|
||||
U8 descriptor_type ;
|
||||
U8 string_type ;
|
||||
U8 dummy;
|
||||
|
||||
zlp = FALSE; /* no zero length packet */
|
||||
string_type = Usb_read_byte(); /* read LSB of wValue */
|
||||
descriptor_type = Usb_read_byte(); /* read MSB of wValue */
|
||||
zlp = FALSE; /* no zero length packet */
|
||||
string_type = Usb_read_byte(); /* read LSB of wValue */
|
||||
descriptor_type = Usb_read_byte(); /* read MSB of wValue */
|
||||
|
||||
dummy = Usb_read_byte(); //!< don't care of wIndex field
|
||||
dummy = Usb_read_byte();
|
||||
LSBwLength = Usb_read_byte(); //!< read wLength
|
||||
MSBwLength = Usb_read_byte();
|
||||
switch (descriptor_type)
|
||||
{
|
||||
case DEVICE_DESCRIPTOR:
|
||||
data_to_transfer = Usb_get_dev_desc_length(); //!< sizeof (usb_user_device_descriptor);
|
||||
pbuffer = Usb_get_dev_desc_pointer();
|
||||
break;
|
||||
case CONFIGURATION_DESCRIPTOR:
|
||||
data_to_transfer = Usb_get_conf_desc_length(string_type); //!< sizeof (usb_user_configuration_descriptor);
|
||||
pbuffer = Usb_get_conf_desc_pointer(string_type);
|
||||
break;
|
||||
case STRING_DESCRIPTOR:
|
||||
if(string_type!=LANG_ID) {
|
||||
usb_get_string_descriptor(string_type);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
dummy = Usb_read_byte();
|
||||
dummy = Usb_read_byte();
|
||||
dummy = Usb_read_byte();
|
||||
dummy = Usb_read_byte();
|
||||
if( usb_user_get_descriptor(descriptor_type, string_type)==FALSE )
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (descriptor_type)
|
||||
{
|
||||
case DEVICE_DESCRIPTOR:
|
||||
data_to_transfer = Usb_get_dev_desc_length(); //!< sizeof (usb_user_device_descriptor);
|
||||
pbuffer = Usb_get_dev_desc_pointer();
|
||||
break;
|
||||
case CONFIGURATION_DESCRIPTOR:
|
||||
data_to_transfer = Usb_get_conf_desc_length(); //!< sizeof (usb_user_configuration_descriptor);
|
||||
pbuffer = Usb_get_conf_desc_pointer();
|
||||
break;
|
||||
default:
|
||||
if( usb_user_get_descriptor(descriptor_type, string_type)==FALSE )
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
dummy = Usb_read_byte(); //!< don't care of wIndex field
|
||||
dummy = Usb_read_byte();
|
||||
LSBwLength = Usb_read_byte(); //!< read wLength
|
||||
MSBwLength = Usb_read_byte();
|
||||
|
||||
Usb_ack_receive_setup() ; //!< clear the receive setup flag
|
||||
|
||||
Usb_ack_receive_setup() ; //!< clear the receive setup flag
|
||||
if ((LSBwLength > data_to_transfer) || (MSBwLength)) {
|
||||
if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; }
|
||||
else { zlp = FALSE; } //!< no need of zero length packet
|
||||
|
||||
if ((LSBwLength > data_to_transfer) || (MSBwLength))
|
||||
{
|
||||
if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; }
|
||||
else { zlp = FALSE; } //!< no need of zero length packet
|
||||
LSBwLength = data_to_transfer;
|
||||
MSBwLength = 0x00;
|
||||
} else {
|
||||
data_to_transfer = LSBwLength; //!< send only requested number of data
|
||||
}
|
||||
|
||||
while((data_to_transfer != 0) && (!Is_usb_receive_out())) {
|
||||
U8 nb_byte = 0;
|
||||
if(usb_endpoint_wait_for_read_control_enabled()!=0) {
|
||||
Usb_enable_stall_handshake();
|
||||
break;
|
||||
}
|
||||
|
||||
LSBwLength = data_to_transfer;
|
||||
MSBwLength = 0x00;
|
||||
}
|
||||
else
|
||||
{
|
||||
data_to_transfer = LSBwLength; //!< send only requested number of data
|
||||
}
|
||||
//! Send data until necessary
|
||||
while(data_to_transfer != 0) {
|
||||
// if(Is_usb_write_enabled()) //!< Check endpoint 0 size
|
||||
if(nb_byte++==EP_CONTROL_LENGTH) //!< Check endpoint 0 size
|
||||
break;
|
||||
|
||||
Usb_write_byte(pgm_read_byte_near((unsigned int)pbuffer++));
|
||||
data_to_transfer --;
|
||||
|
||||
while((data_to_transfer != 0) && (!Is_usb_receive_out()))
|
||||
{
|
||||
while(!Is_usb_read_control_enabled());
|
||||
}
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
nb_byte=0;
|
||||
while(data_to_transfer != 0) //!< Send data until necessary
|
||||
{
|
||||
if(nb_byte++==EP_CONTROL_LENGTH) //!< Check endpoint 0 size
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(Is_usb_receive_out()) {
|
||||
//! abort from Host
|
||||
Usb_ack_receive_out();
|
||||
return;
|
||||
}
|
||||
|
||||
if(zlp == TRUE) {
|
||||
if(usb_endpoint_wait_for_read_control_enabled()!=0) {
|
||||
Usb_enable_stall_handshake();
|
||||
return;
|
||||
}
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
//#ifndef AVRGCC
|
||||
// Usb_write_byte(*pbuffer++);
|
||||
//#else // AVRGCC does not support point to PGM space
|
||||
//#warning AVRGCC assumes devices descriptors are stored in the lower 64Kbytes of on-chip flash memory
|
||||
Usb_write_byte(pgm_read_byte_near((unsigned int)pbuffer++));
|
||||
//#endif
|
||||
data_to_transfer --;
|
||||
|
||||
}
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
if(Is_usb_receive_out()) { Usb_ack_receive_out(); return; } //!< abort from Host
|
||||
if(zlp == TRUE)
|
||||
{
|
||||
while(!Is_usb_read_control_enabled());
|
||||
Usb_send_control_in();
|
||||
}
|
||||
|
||||
while(!Is_usb_receive_out());
|
||||
Usb_ack_receive_out();
|
||||
usb_endpoint_wait_for_receive_out();
|
||||
Usb_ack_receive_out();
|
||||
}
|
||||
|
||||
//! usb_get_configuration.
|
||||
|
@ -345,9 +538,9 @@ void usb_get_configuration(void)
|
|||
Usb_ack_receive_setup();
|
||||
|
||||
Usb_write_byte(usb_configuration_nb);
|
||||
Usb_ack_in_ready();
|
||||
Usb_send_control_in();
|
||||
|
||||
while( !Is_usb_receive_out() );
|
||||
usb_endpoint_wait_for_receive_out();
|
||||
Usb_ack_receive_out();
|
||||
}
|
||||
|
||||
|
@ -390,7 +583,7 @@ U8 dummy;
|
|||
Usb_write_byte(0x00);
|
||||
Usb_send_control_in();
|
||||
|
||||
while( !Is_usb_receive_out() );
|
||||
usb_endpoint_wait_for_receive_out();
|
||||
Usb_ack_receive_out();
|
||||
}
|
||||
|
||||
|
@ -409,10 +602,6 @@ U8 dummy;
|
|||
|
||||
if (bmRequestType == INTERFACE_TYPE)
|
||||
{
|
||||
//!< keep that order (set StallRq/clear RxSetup) or a
|
||||
//!< OUT request following the SETUP may be acknowledged
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
else if (bmRequestType == ENDPOINT_TYPE)
|
||||
|
@ -426,8 +615,6 @@ U8 dummy;
|
|||
|
||||
if (wIndex == EP_CONTROL)
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -443,15 +630,11 @@ U8 dummy;
|
|||
else
|
||||
{
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -471,18 +654,10 @@ U8 dummy;
|
|||
|
||||
if (bmRequestType == ZERO_TYPE)
|
||||
{
|
||||
//!< keep that order (set StallRq/clear RxSetup) or a
|
||||
//!< OUT request following the SETUP may be acknowledged
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
else if (bmRequestType == INTERFACE_TYPE)
|
||||
{
|
||||
//!< keep that order (set StallRq/clear RxSetup) or a
|
||||
//!< OUT request following the SETUP may be acknowledged
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
else if (bmRequestType == ENDPOINT_TYPE)
|
||||
|
@ -507,19 +682,15 @@ U8 dummy;
|
|||
endpoint_status[wIndex] = 0x00;
|
||||
Usb_ack_receive_setup();
|
||||
Usb_send_control_in();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -533,8 +704,7 @@ U8 dummy;
|
|||
//!
|
||||
void usb_get_interface (void)
|
||||
{
|
||||
Usb_enable_stall_handshake();
|
||||
Usb_ack_receive_setup();
|
||||
// Not yet implemented.
|
||||
}
|
||||
|
||||
//! usb_set_interface.
|
||||
|
@ -545,7 +715,21 @@ void usb_get_interface (void)
|
|||
//!
|
||||
void usb_set_interface (void)
|
||||
{
|
||||
Usb_ack_receive_setup();
|
||||
Usb_send_control_in(); //!< send a ZLP for STATUS phase
|
||||
while(!Is_usb_in_ready());
|
||||
U8 alt_setting;
|
||||
U8 dummy;
|
||||
U8 interface;
|
||||
|
||||
alt_setting = Usb_read_byte();
|
||||
dummy = Usb_read_byte();
|
||||
interface = Usb_read_byte();
|
||||
|
||||
if(usb_user_set_alt_interface(interface, alt_setting)) {
|
||||
Usb_ack_receive_setup();
|
||||
Usb_send_control_in(); //!< send a ZLP for STATUS phase
|
||||
while(!Is_usb_in_ready());
|
||||
|
||||
usb_endpoint_wait_for_receive_out();
|
||||
Usb_ack_receive_out();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -166,53 +166,44 @@ void usb_start_device (void)
|
|||
*/
|
||||
static void pollhandler(void)
|
||||
{
|
||||
/* Check for setup packets */
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
if (Is_usb_receive_setup()) {
|
||||
usb_process_request();
|
||||
}
|
||||
|
||||
/* The previous call might have requested we send
|
||||
out something to the RNDIS interrupt endpoint */
|
||||
if (schedule_interrupt) {
|
||||
Usb_select_endpoint(INT_EP);
|
||||
|
||||
//RNDIS needs a delay where this isn't called, as it will switch endpoints
|
||||
//and screw up the data transfers
|
||||
if (!usb_busy) {
|
||||
//Linux is a bunch of lies, and won't read
|
||||
//the interrupt endpoint. Hence if this isn't ready just exit
|
||||
//while(!Is_usb_write_enabled());
|
||||
|
||||
/* Check for setup packets */
|
||||
Usb_select_endpoint(EP_CONTROL);
|
||||
if (Is_usb_receive_setup()) {
|
||||
usb_process_request();
|
||||
if (Is_usb_write_enabled()) {
|
||||
|
||||
// Only valid interrupt is:
|
||||
// 0x00000001 0x00000000
|
||||
//
|
||||
Usb_write_byte(0x01);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
|
||||
//Send back
|
||||
Usb_send_in();
|
||||
|
||||
schedule_interrupt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The previous call might have requested we send
|
||||
out something to the RNDIS interrupt endpoint */
|
||||
if (schedule_interrupt) {
|
||||
Usb_select_endpoint(INT_EP);
|
||||
|
||||
//Linux is a bunch of lies, and won't read
|
||||
//the interrupt endpoint. Hence if this isn't ready just exit
|
||||
//while(!Is_usb_write_enabled());
|
||||
|
||||
if (Is_usb_write_enabled()) {
|
||||
|
||||
// Only valid interrupt is:
|
||||
// 0x00000001 0x00000000
|
||||
//
|
||||
Usb_write_byte(0x01);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
Usb_write_byte(0x00);
|
||||
|
||||
//Send back
|
||||
Usb_send_in();
|
||||
|
||||
schedule_interrupt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Continue polling */
|
||||
process_poll(&usb_process);
|
||||
/* Continue polling */
|
||||
process_poll(&usb_process);
|
||||
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* @(#)$Id: rf230bb.c,v 1.11 2010/06/18 15:44:53 dak664 Exp $
|
||||
* @(#)$Id: rf230bb.c,v 1.12 2010/09/17 21:59:09 dak664 Exp $
|
||||
*/
|
||||
/*
|
||||
* This code is almost device independent and should be easy to port.
|
||||
|
@ -56,20 +56,6 @@
|
|||
#include "net/rime/rimestats.h"
|
||||
#include "net/netstack.h"
|
||||
|
||||
#if JACKDAW
|
||||
#include "sicslow_ethernet.h"
|
||||
#include "uip.h"
|
||||
#include "uip_arp.h" //For ethernet header structure
|
||||
#define ETHBUF(x) ((struct uip_eth_hdr *)x)
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
/* 6lowpan max size + ethernet header size + 1 */
|
||||
static uint8_t raw_buf[127+ UIP_LLH_LEN +1];
|
||||
extern uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan);
|
||||
extern rimeaddr_t macLongAddr;
|
||||
#include "rndis/rndis_task.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "sys/timetable.h"
|
||||
|
||||
#define WITH_SEND_CCA 0
|
||||
|
@ -91,17 +77,19 @@ extern rimeaddr_t macLongAddr;
|
|||
#define RF230_CONF_AUTOACK 1
|
||||
#endif /* RF230_CONF_AUTOACK */
|
||||
|
||||
#if RF230_CONF_AUTOACK
|
||||
static bool is_promiscuous;
|
||||
#endif
|
||||
|
||||
#ifndef RF230_CONF_AUTORETRIES
|
||||
#define RF230_CONF_AUTORETRIES 2
|
||||
#endif /* RF230_CONF_AUTOACK */
|
||||
|
||||
//Automatic and manual CRC both append 2 bytes to packets
|
||||
#if RF230_CONF_CHECKSUM
|
||||
#if RF230_CONF_CHECKSUM || defined(RF230BB_HOOK_TX_PACKET)
|
||||
#include "lib/crc16.h"
|
||||
#define CHECKSUM_LEN 2
|
||||
#else
|
||||
#define CHECKSUM_LEN 2
|
||||
#endif /* RF230_CONF_CHECKSUM */
|
||||
#define CHECKSUM_LEN 2
|
||||
|
||||
#define AUX_LEN (CHECKSUM_LEN + TIMESTAMP_LEN + FOOTER_LEN)
|
||||
|
||||
|
@ -212,7 +200,7 @@ const struct radio_driver rf230_driver =
|
|||
};
|
||||
|
||||
uint8_t RF230_receive_on,RF230_sleeping;
|
||||
static int channel;
|
||||
static uint8_t channel;
|
||||
|
||||
/* Received frames are buffered to rxframe in the interrupt routine in hal.c */
|
||||
hal_rx_frame_t rxframe;
|
||||
|
@ -424,6 +412,33 @@ radio_set_trx_state(uint8_t new_state)
|
|||
return set_state_status;
|
||||
}
|
||||
|
||||
void
|
||||
rf230_set_promiscuous_mode(bool isPromiscuous) {
|
||||
if(isPromiscuous) {
|
||||
is_promiscuous = true;
|
||||
#if RF230_CONF_AUTOACK
|
||||
radio_set_trx_state(RX_ON);
|
||||
#endif
|
||||
} else {
|
||||
is_promiscuous = false;
|
||||
#if RF230_CONF_AUTOACK
|
||||
radio_set_trx_state(RX_AACK_ON);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
rf230_is_ready_to_send() {
|
||||
switch(radio_get_trx_state()) {
|
||||
case BUSY_TX:
|
||||
case BUSY_TX_ARET:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
flushrx(void)
|
||||
{
|
||||
|
@ -436,20 +451,9 @@ static void
|
|||
on(void)
|
||||
{
|
||||
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
|
||||
#if JACKDAW
|
||||
//blue=0 red=1 green=2 yellow=3
|
||||
#define Led0_on() (PORTD |= 0x80)
|
||||
#define Led1_on() (PORTD &= ~0x20)
|
||||
#define Led2_on() (PORTE &= ~0x80)
|
||||
#define Led3_on() (PORTE &= ~0x40)
|
||||
#define Led0_off() (PORTD &= ~0x80)
|
||||
#define Led1_off() (PORTD |= 0x20)
|
||||
#define Led2_off() (PORTE |= 0x80)
|
||||
#define Led3_off() (PORTE |= 0x40)
|
||||
Led1_on();
|
||||
#else
|
||||
// PRINTSHORT("o");
|
||||
// PRINTF("on\n");
|
||||
|
||||
#ifdef RF230BB_HOOK_RADIO_ON
|
||||
RF230BB_HOOK_RADIO_ON();
|
||||
#endif
|
||||
|
||||
if (RF230_sleeping) {
|
||||
|
@ -461,7 +465,7 @@ on(void)
|
|||
rf230_waitidle();
|
||||
|
||||
#if RF230_CONF_AUTOACK
|
||||
radio_set_trx_state(RX_AACK_ON);
|
||||
radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON);
|
||||
#else
|
||||
radio_set_trx_state(RX_ON);
|
||||
#endif
|
||||
|
@ -475,10 +479,8 @@ off(void)
|
|||
// rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
|
||||
RF230_receive_on = 0;
|
||||
|
||||
#if JACKDAW
|
||||
Led1_off();
|
||||
#else
|
||||
// PRINTSHORT("f");
|
||||
#ifdef RF230BB_HOOK_RADIO_OFF
|
||||
RF230BB_HOOK_RADIO_OFF();
|
||||
#endif
|
||||
|
||||
// DEBUGFLOW('F');
|
||||
|
@ -581,7 +583,7 @@ rf230_init(void)
|
|||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t buffer[RF230_MAX_TX_FRAME_LENGTH];
|
||||
static uint8_t buffer[RF230_MAX_TX_FRAME_LENGTH+AUX_LEN];
|
||||
static int
|
||||
rf230_transmit(unsigned short payload_len)
|
||||
{
|
||||
|
@ -711,6 +713,7 @@ rf230_transmit(unsigned short payload_len)
|
|||
static int
|
||||
rf230_prepare(const void *payload, unsigned short payload_len)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t total_len,*pbuf;
|
||||
#if RF230_CONF_TIMESTAMPS
|
||||
struct timestamp timestamp;
|
||||
|
@ -736,8 +739,12 @@ rf230_prepare(const void *payload, unsigned short payload_len)
|
|||
if (total_len > RF230_MAX_TX_FRAME_LENGTH){
|
||||
#if RADIOSTATS
|
||||
RF230_sendfail++;
|
||||
#endif
|
||||
return -1;
|
||||
#endif
|
||||
#if DEBUG
|
||||
printf_P(PSTR("rf230_prepare: packet too large (%d, max: %d)\n"),total_len,RF230_MAX_TX_FRAME_LENGTH);
|
||||
#endif
|
||||
ret = -1;
|
||||
goto bail;
|
||||
}
|
||||
pbuf=&buffer[0];
|
||||
memcpy(pbuf,payload,payload_len);
|
||||
|
@ -755,66 +762,46 @@ rf230_prepare(const void *payload, unsigned short payload_len)
|
|||
pbuf+=TIMESTAMP_LEN;
|
||||
#endif /* RF230_CONF_TIMESTAMPS */
|
||||
/*------------------------------------------------------------*/
|
||||
/* If jackdaw report frame to ethernet interface */
|
||||
#if JACKDAW
|
||||
// mac_logTXtoEthernet(¶ms, &result);
|
||||
if (usbstick_mode.raw != 0) {
|
||||
uint8_t sendlen;
|
||||
|
||||
/* Get the raw frame */
|
||||
memcpy(&raw_buf[UIP_LLH_LEN], buffer, total_len);
|
||||
sendlen = total_len;
|
||||
|
||||
/* Setup generic ethernet stuff */
|
||||
ETHBUF(raw_buf)->type = htons(0x809A); //UIP_ETHTYPE_802154 0x809A
|
||||
|
||||
// uint64_t tempaddr;
|
||||
|
||||
/* Check for broadcast message */
|
||||
if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) {
|
||||
ETHBUF(raw_buf)->dest.addr[0] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[1] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
|
||||
ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
|
||||
ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
|
||||
ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
|
||||
} else {
|
||||
/* Otherwise we have a real address */
|
||||
// tempaddr = p->dest_addr.addr64;
|
||||
// byte_reverse((uint8_t *)&tempaddr, 8);
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||
}
|
||||
|
||||
// tempaddr = p->src_addr.addr64;
|
||||
// memcpy(&tempaddr,packetbuf_addr(PACKETBUF_ADDR_SENDER),sizeof(tempaddr));
|
||||
// byte_reverse((uint8_t *)&tempaddr, 8);
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),(uip_lladdr_t *)&uip_lladdr.addr);
|
||||
|
||||
// printf("Low2Eth: Sending 802.15.4 packet to ethernet\n\r");
|
||||
|
||||
sendlen += UIP_LLH_LEN;
|
||||
usb_eth_send(raw_buf, sendlen, 0);
|
||||
// rndis_stat.rxok++;
|
||||
#ifdef RF230BB_HOOK_TX_PACKET
|
||||
#if !RF230_CONF_CHECKSUM
|
||||
{ // Add a checksum before we log the packet out
|
||||
uint16_t checksum;
|
||||
checksum = crc16_data(payload, payload_len, 0);
|
||||
memcpy(buffer+total_len-CHECKSUM_LEN,&checksum,CHECKSUM_LEN);
|
||||
}
|
||||
#endif /* JACKDAW */
|
||||
#endif /* RF230_CONF_CHECKSUM */
|
||||
RF230BB_HOOK_TX_PACKET(buffer,total_len);
|
||||
#endif
|
||||
|
||||
|
||||
bail:
|
||||
RELEASE_LOCK();
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
rf230_send(const void *payload, unsigned short payload_len)
|
||||
{
|
||||
rf230_prepare(payload, payload_len);
|
||||
#if JACKDAW
|
||||
// In sniffer mode we don't ever send anything
|
||||
if (usbstick_mode.sendToRf == 0) {
|
||||
uip_len = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif /* JACKDAW */
|
||||
return rf230_transmit(payload_len);
|
||||
int ret = 0;
|
||||
|
||||
#ifdef RF230BB_HOOK_IS_SEND_ENABLED
|
||||
if(!RF230BB_HOOK_IS_SEND_ENABLED()) {
|
||||
goto bail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if((ret=rf230_prepare(payload, payload_len))) {
|
||||
#if DEBUG
|
||||
printf_P(PSTR("rf230_send: Unable to send, prep failed (%d)\n"),ret);
|
||||
#endif
|
||||
goto bail;
|
||||
}
|
||||
|
||||
ret = rf230_transmit(payload_len);
|
||||
|
||||
bail:
|
||||
return ret;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
|
@ -862,7 +849,7 @@ rf230_on(void)
|
|||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
uint8_t
|
||||
rf230_get_channel(void)
|
||||
{
|
||||
//jackdaw reads zero channel, raven reads correct channel?
|
||||
|
@ -871,7 +858,7 @@ rf230_get_channel(void)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rf230_set_channel(int c)
|
||||
rf230_set_channel(uint8_t c)
|
||||
{
|
||||
/* Wait for any transmission to end. */
|
||||
// PRINTF("rf230: Set Channel %u\n",c);
|
||||
|
@ -883,7 +870,7 @@ rf230_set_channel(int c)
|
|||
void
|
||||
rf230_set_pan_addr(unsigned pan,
|
||||
unsigned addr,
|
||||
const uint8_t *ieee_addr)
|
||||
const uint8_t ieee_addr[8])
|
||||
//rf230_set_pan_addr(uint16_t pan,uint16_t addr,uint8_t *ieee_addr)
|
||||
{
|
||||
PRINTF("rf230: PAN=%x Short Addr=%x\n",pan,addr);
|
||||
|
@ -1083,19 +1070,19 @@ if (RF230_receive_on) {
|
|||
}
|
||||
/* Transfer the frame, stripping the footer */
|
||||
framep=&(rxframe.data[0]);
|
||||
memcpy(buf,framep,len-AUX_LEN);
|
||||
memcpy(buf,framep,len-AUX_LEN+CHECKSUM_LEN);
|
||||
framep+=len-AUX_LEN;
|
||||
/* Clear the length field to allow buffering of the next packet */
|
||||
rxframe.length=0;
|
||||
|
||||
#if RF230_CONF_CHECKSUM
|
||||
memcpy(&checksum,framep,CHECKSUM_LEN);
|
||||
framep+=CHECKSUM_LEN;
|
||||
#endif /* RF230_CONF_CHECKSUM */
|
||||
framep+=CHECKSUM_LEN;
|
||||
#if RF230_CONF_TIMESTAMPS
|
||||
memcpy(&t,framep,TIMESTAMP_LEN);
|
||||
framep+=TIMESTAMP_LEN;
|
||||
#endif /* RF230_CONF_TIMESTAMPS */
|
||||
framep+=TIMESTAMP_LEN;
|
||||
#if FOOTER_LEN
|
||||
memcpy(footer,framep,FOOTER_LEN);
|
||||
#endif
|
||||
|
@ -1152,52 +1139,11 @@ if (RF230_receive_on) {
|
|||
// }
|
||||
|
||||
// RELEASE_LOCK();
|
||||
if(len < AUX_LEN) {
|
||||
return 0;
|
||||
}
|
||||
#if JACKDAW
|
||||
/*------------------------------------------------------------*/
|
||||
/* If jackdaw report frame to ethernet interface */
|
||||
// mac_logRXtoEthernet(¶ms, &result);
|
||||
if (usbstick_mode.raw != 0) {
|
||||
uint8_t sendlen;
|
||||
|
||||
/* Get the raw frame */
|
||||
memcpy(&raw_buf[UIP_LLH_LEN], buf, len);
|
||||
sendlen = len;
|
||||
#ifdef RF230BB_HOOK_RX_PACKET
|
||||
RF230BB_HOOK_RX_PACKET(buf,len);
|
||||
#endif
|
||||
|
||||
/* Setup generic ethernet stuff */
|
||||
ETHBUF(raw_buf)->type = htons(0x809A); //UIP_ETHTYPE_802154 0x809A
|
||||
|
||||
// uint64_t tempaddr;
|
||||
|
||||
/* Check for broadcast message */
|
||||
if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) {
|
||||
ETHBUF(raw_buf)->dest.addr[0] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[1] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
|
||||
ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
|
||||
ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
|
||||
ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
|
||||
} else {
|
||||
/* Otherwise we have a real address */
|
||||
// tempaddr = p->dest_addr.addr64;
|
||||
// byte_reverse((uint8_t *)&tempaddr, 8);
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||
}
|
||||
|
||||
// tempaddr = p->src_addr.addr64;
|
||||
// memcpy(&tempaddr,packetbuf_addr(PACKETBUF_ADDR_SENDER),sizeof(tempaddr));
|
||||
// byte_reverse((uint8_t *)&tempaddr, 8);
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),(uip_lladdr_t *)&uip_lladdr.addr);
|
||||
|
||||
// printf("Low2Eth: Sending 802.15.4 packet to ethernet\n\r");
|
||||
|
||||
sendlen += UIP_LLH_LEN;
|
||||
usb_eth_send(raw_buf, sendlen, 0);
|
||||
}
|
||||
#endif /* JACKDAW */
|
||||
|
||||
return len - AUX_LEN;
|
||||
|
||||
|
@ -1217,30 +1163,23 @@ rf230_set_txpower(uint8_t power)
|
|||
RELEASE_LOCK();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
uint8_t
|
||||
rf230_get_txpower(void)
|
||||
{
|
||||
uint8_t power;
|
||||
if (radio_is_sleeping() ==true) {
|
||||
PRINTF("rf230_get_txpower:Sleeping");
|
||||
return 0;
|
||||
} else {
|
||||
// return hal_subregister_read(SR_TX_PWR);
|
||||
power=hal_subregister_read(SR_TX_PWR);
|
||||
if (power==0) {
|
||||
PRINTSHORT("PZ");
|
||||
return 1;
|
||||
} else {
|
||||
return power;
|
||||
}
|
||||
}
|
||||
uint8_t power = TX_PWR_UNDEFINED;
|
||||
if (radio_is_sleeping()) {
|
||||
PRINTF("rf230_get_txpower:Sleeping");
|
||||
} else {
|
||||
power = hal_subregister_read(SR_TX_PWR);
|
||||
}
|
||||
return power;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rf230_rssi(void)
|
||||
uint8_t
|
||||
rf230_get_raw_rssi(void)
|
||||
{
|
||||
int rssi;
|
||||
int radio_was_off = 0;
|
||||
uint8_t rssi;
|
||||
bool radio_was_off = 0;
|
||||
|
||||
/*The RSSI measurement should only be done in RX_ON or BUSY_RX.*/
|
||||
if(!RF230_receive_on) {
|
||||
|
@ -1249,11 +1188,6 @@ rf230_rssi(void)
|
|||
}
|
||||
|
||||
rssi = (int)((signed char)hal_subregister_read(SR_RSSI));
|
||||
if (rssi==0) {
|
||||
DEBUGFLOW('r');
|
||||
PRINTF("RSZ");
|
||||
rssi=1;
|
||||
}
|
||||
|
||||
if(radio_was_off) {
|
||||
rf230_off();
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
* \file
|
||||
* \brief This file contains radio driver code.
|
||||
*
|
||||
* $Id: rf230bb.h,v 1.2 2010/02/22 22:23:18 dak664 Exp $
|
||||
* $Id: rf230bb.h,v 1.3 2010/09/17 21:59:09 dak664 Exp $
|
||||
*/
|
||||
|
||||
#ifndef RADIO_H
|
||||
|
@ -73,6 +73,11 @@
|
|||
#define TX_PWR_3DBM ( 0 )
|
||||
#define TX_PWR_17_2DBM ( 15 )
|
||||
|
||||
#define TX_PWR_MAX TX_PWR_3DBM
|
||||
#define TX_PWR_MIN TX_PWR_17_2DBM
|
||||
#define TX_PWR_UNDEFINED (TX_PWR_MIN+1)
|
||||
|
||||
|
||||
#define BATTERY_MONITOR_HIGHEST_VOLTAGE ( 15 )
|
||||
#define BATTERY_MONITOR_VOLTAGE_UNDER_THRESHOLD ( 0 )
|
||||
#define BATTERY_MONITOR_HIGH_VOLTAGE ( 1 )
|
||||
|
@ -168,89 +173,44 @@ typedef enum{
|
|||
}radio_clkm_speed_t;
|
||||
|
||||
typedef void (*radio_rx_callback) (uint16_t data);
|
||||
extern uint8_t rxMode;
|
||||
|
||||
|
||||
/* Hook Documentation
|
||||
**
|
||||
** Sniffing Hooks:
|
||||
** RF230BB_HOOK_TX_PACKET(buffer,total_len)
|
||||
** RF230BB_HOOK_RX_PACKET(buf,len)
|
||||
**
|
||||
** RF230BB_HOOK_IS_SEND_ENABLED()
|
||||
** RF230BB_HOOK_RADIO_ON()
|
||||
** RF230BB_HOOK_RADIO_OFF()
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
/*============================ PROTOTYPES ====================================*/
|
||||
|
||||
const struct radio_driver rf230_driver;
|
||||
|
||||
int rf230_init(void);
|
||||
//int rf230_on(void);
|
||||
//int rf230_off(void);
|
||||
void rf230_set_channel(int channel);
|
||||
int rf230_get_channel(void);
|
||||
void rf230_set_pan_addr(unsigned pan,unsigned addr,const uint8_t *ieee_addr);
|
||||
//void rf230_set_pan_addr(uint16_t pan,uint16_t addr,uint8_t *ieee_addr);
|
||||
//void rf230_set_txpower(uint8_t power);
|
||||
int rf230_get_txpower(void);
|
||||
void rf230_set_channel(uint8_t channel);
|
||||
uint8_t rf230_get_channel(void);
|
||||
void rf230_set_pan_addr(unsigned pan,unsigned addr,const uint8_t ieee_addr[8]);
|
||||
void rf230_set_txpower(uint8_t power);
|
||||
uint8_t rf230_get_txpower(void);
|
||||
|
||||
//extern signed char rf230_last_rssi;
|
||||
//extern uint8_t rf230_last_correlation;
|
||||
void rf230_set_promiscuous_mode(bool isPromiscuous);
|
||||
bool rf230_is_ready_to_send();
|
||||
|
||||
//int rf230_rssi(void);
|
||||
extern signed char rf230_last_rssi;
|
||||
extern uint8_t rf230_last_correlation;
|
||||
|
||||
uint8_t rf230_get_raw_rssi(void);
|
||||
|
||||
#define rf230_rssi rf230_get_raw_rssi
|
||||
|
||||
//#define CC2420_TXPOWER_MAX 31
|
||||
//#define CC2420_TXPOWER_MIN 0
|
||||
|
||||
/**
|
||||
* Interrupt function, called from the simple-cc2420-arch driver.
|
||||
*
|
||||
*/
|
||||
//int cc2420_interrupt(void);
|
||||
|
||||
/* XXX hack: these will be made as Chameleon packet attributes */
|
||||
//extern rtimer_clock_t rf230_time_of_arrival,rf230_time_of_departure;
|
||||
//extern int rf230_authority_level_of_sender;
|
||||
|
||||
|
||||
//radio_status_t radio_init(bool cal_rc_osc,
|
||||
// hal_rx_start_isr_event_handler_t rx_event,
|
||||
// hal_trx_end_isr_event_handler_t trx_end_event,
|
||||
// radio_rx_callback rx_callback);
|
||||
//uint8_t radio_get_saved_rssi_value(void);
|
||||
//uint8_t radio_get_operating_channel( void );
|
||||
//radio_status_t radio_set_operating_channel( uint8_t channel );
|
||||
//uint8_t radio_get_tx_power_level( void );
|
||||
//radio_status_t radio_set_tx_power_level( uint8_t power_level );
|
||||
|
||||
//uint8_t radio_get_cca_mode( void );
|
||||
//uint8_t radio_get_ed_threshold( void );
|
||||
//radio_status_t radio_set_cca_mode( uint8_t mode, uint8_t ed_threshold );
|
||||
//radio_status_t radio_do_cca( void );
|
||||
//radio_status_t radio_get_rssi_value( uint8_t *rssi );
|
||||
|
||||
//uint8_t radio_batmon_get_voltage_threshold( void );
|
||||
//uint8_t radio_batmon_get_voltage_range( void );
|
||||
//radio_status_t radio_batmon_configure( bool range, uint8_t voltage_threshold );
|
||||
//radio_status_t radio_batmon_get_status( void );
|
||||
|
||||
//uint8_t radio_get_clock_speed( void );
|
||||
//radio_status_t radio_set_clock_speed( bool direct, uint8_t clock_speed );
|
||||
//radio_status_t radio_calibrate_filter( void );
|
||||
//radio_status_t radio_calibrate_pll( void );
|
||||
|
||||
//uint8_t radio_get_trx_state( void );
|
||||
//radio_status_t radio_set_trx_state( uint8_t new_state );
|
||||
//radio_status_t radio_enter_sleep_mode( void );
|
||||
//radio_status_t radio_leave_sleep_mode( void );
|
||||
//void radio_reset_state_machine( void );
|
||||
//void radio_reset_trx( void );
|
||||
|
||||
//void radio_use_auto_tx_crc( bool auto_crc_on );
|
||||
//radio_status_t radio_send_data( uint8_t data_length, uint8_t *data );
|
||||
|
||||
//uint8_t radio_get_device_role( void );
|
||||
//void radio_set_device_role( bool i_am_coordinator );
|
||||
//uint16_t radio_get_pan_id( void );
|
||||
//void radio_set_pan_id( uint16_t new_pan_id );
|
||||
//uint16_t radio_get_short_address( void );
|
||||
//void radio_set_short_address( uint16_t new_short_address );
|
||||
//void radio_get_extended_address( uint8_t *extended_address );
|
||||
//void radio_set_extended_address( uint8_t *extended_address );
|
||||
//radio_status_t radio_configure_csma( uint8_t seed0, uint8_t be_csma_seed1 );
|
||||
//bool calibrate_rc_osc_clkm(void);
|
||||
//void calibrate_rc_osc_32k(void);
|
||||
//uint8_t * radio_frame_data(void);
|
||||
//uint8_t radio_frame_length(void);
|
||||
#define delay_us( us ) ( _delay_loop_2( ( F_CPU / 4000000UL ) * ( us ) ) )
|
||||
|
||||
#endif
|
||||
|
|
275
cpu/avr/settings.c
Normal file
275
cpu/avr/settings.c
Normal file
|
@ -0,0 +1,275 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
//#include <sys/param.h>
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#include <avr/io.h>
|
||||
#include "settings.h"
|
||||
#include "dev/eeprom.h"
|
||||
#include <stdio.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/wdt.h>
|
||||
#include "contiki.h"
|
||||
|
||||
#ifndef SETTINGS_TOP_ADDR
|
||||
#define SETTINGS_TOP_ADDR (E2END-4) //!< Defaults to end of EEPROM, minus 4 bytes for avrdude erase count
|
||||
#endif
|
||||
|
||||
#ifndef SETTINGS_MAX_SIZE
|
||||
#define SETTINGS_MAX_SIZE (1024) //!< Defaults to 1KB
|
||||
#endif
|
||||
|
||||
//#pragma mark -
|
||||
//#pragma mark Private Functions
|
||||
|
||||
typedef struct {
|
||||
uint8_t size_extra;
|
||||
uint8_t size_low;
|
||||
uint8_t size_check;
|
||||
settings_key_t key;
|
||||
} item_header_t;
|
||||
|
||||
inline static bool
|
||||
settings_is_item_valid_(eeprom_addr_t item_addr) {
|
||||
item_header_t header = {};
|
||||
|
||||
if(item_addr==EEPROM_NULL)
|
||||
return false;
|
||||
|
||||
// if((SETTINGS_TOP_ADDR-item_addr)>=SETTINGS_MAX_SIZE-3)
|
||||
// return false;
|
||||
|
||||
eeprom_read(
|
||||
item_addr+1-sizeof(header),
|
||||
(unsigned char*)&header,
|
||||
sizeof(header)
|
||||
);
|
||||
|
||||
if((uint8_t)header.size_check!=(uint8_t)~header.size_low)
|
||||
return false;
|
||||
|
||||
// TODO: Check length as well
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline static settings_key_t
|
||||
settings_get_key_(eeprom_addr_t item_addr) {
|
||||
item_header_t header;
|
||||
|
||||
eeprom_read(
|
||||
item_addr+1-sizeof(header),
|
||||
(unsigned char*)&header,
|
||||
sizeof(header)
|
||||
);
|
||||
|
||||
if((uint8_t)header.size_check!=(uint8_t)~header.size_low)
|
||||
return SETTINGS_INVALID_KEY;
|
||||
|
||||
return header.key;
|
||||
}
|
||||
|
||||
inline static size_t
|
||||
settings_get_value_length_(eeprom_addr_t item_addr) {
|
||||
item_header_t header;
|
||||
size_t ret = 0;
|
||||
|
||||
eeprom_read(
|
||||
item_addr+1-sizeof(header),
|
||||
(unsigned char*)&header,
|
||||
sizeof(header)
|
||||
);
|
||||
|
||||
if((uint8_t)header.size_check!=(uint8_t)~header.size_low)
|
||||
goto bail;
|
||||
|
||||
ret = header.size_low;
|
||||
|
||||
if(ret&(1<<7)) {
|
||||
ret = ((ret&~(1<<7))<<8) | header.size_extra;
|
||||
}
|
||||
|
||||
bail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline static eeprom_addr_t
|
||||
settings_get_value_addr_(eeprom_addr_t item_addr) {
|
||||
size_t len = settings_get_value_length_(item_addr);
|
||||
|
||||
if(len>128)
|
||||
return item_addr+1-sizeof(item_header_t)-len;
|
||||
|
||||
return item_addr+1-sizeof(item_header_t)+1-len;
|
||||
}
|
||||
|
||||
inline static eeprom_addr_t
|
||||
settings_next_item_(eeprom_addr_t item_addr) {
|
||||
return settings_get_value_addr_(item_addr)-1;
|
||||
}
|
||||
|
||||
|
||||
//#pragma mark -
|
||||
//#pragma mark Public Functions
|
||||
|
||||
bool
|
||||
settings_check(settings_key_t key,uint8_t index) {
|
||||
bool ret = false;
|
||||
eeprom_addr_t current_item = SETTINGS_TOP_ADDR;
|
||||
|
||||
for(current_item=SETTINGS_TOP_ADDR;settings_is_item_valid_(current_item);current_item=settings_next_item_(current_item)) {
|
||||
if(settings_get_key_(current_item)==key) {
|
||||
if(!index) {
|
||||
ret = true;
|
||||
break;
|
||||
} else {
|
||||
// Nope, keep looking
|
||||
index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
settings_status_t
|
||||
settings_get(settings_key_t key,uint8_t index,unsigned char* value,size_t* value_size) {
|
||||
settings_status_t ret = SETTINGS_STATUS_NOT_FOUND;
|
||||
eeprom_addr_t current_item = SETTINGS_TOP_ADDR;
|
||||
|
||||
for(current_item=SETTINGS_TOP_ADDR;settings_is_item_valid_(current_item);current_item=settings_next_item_(current_item)) {
|
||||
if(settings_get_key_(current_item)==key) {
|
||||
if(!index) {
|
||||
// We found it!
|
||||
*value_size = MIN(*value_size,settings_get_value_length_(current_item));
|
||||
eeprom_read(
|
||||
settings_get_value_addr_(current_item),
|
||||
value,
|
||||
*value_size
|
||||
);
|
||||
ret = SETTINGS_STATUS_OK;
|
||||
break;
|
||||
} else {
|
||||
// Nope, keep looking
|
||||
index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
settings_status_t
|
||||
settings_add(settings_key_t key,const unsigned char* value,size_t value_size) {
|
||||
settings_status_t ret = SETTINGS_STATUS_FAILURE;
|
||||
eeprom_addr_t current_item = SETTINGS_TOP_ADDR;
|
||||
item_header_t header;
|
||||
|
||||
// Find end of list
|
||||
for(current_item=SETTINGS_TOP_ADDR;settings_is_item_valid_(current_item);current_item=settings_next_item_(current_item));
|
||||
|
||||
if(current_item==EEPROM_NULL)
|
||||
goto bail;
|
||||
|
||||
// TODO: size check!
|
||||
|
||||
header.key = key;
|
||||
|
||||
if(value_size<0x80) {
|
||||
// If the value size is less than 128, then
|
||||
// we can get away with only using one byte
|
||||
// as the size.
|
||||
header.size_low = value_size;
|
||||
} else if(value_size<=SETTINGS_MAX_VALUE_SIZE) {
|
||||
// If the value size of larger than 128,
|
||||
// then we need to use two bytes. Store
|
||||
// the most significant 7 bits in the first
|
||||
// size byte (with MSB set) and store the
|
||||
// least significant bits in the second
|
||||
// byte (with LSB clear)
|
||||
header.size_low = (value_size>>7) | 0x80;
|
||||
header.size_extra = value_size & ~0x80;
|
||||
} else {
|
||||
// Value size way too big!
|
||||
goto bail;
|
||||
}
|
||||
|
||||
header.size_check = ~header.size_low;
|
||||
|
||||
// Write the header first
|
||||
eeprom_write(
|
||||
current_item+1-sizeof(header),
|
||||
(unsigned char*)&header,
|
||||
sizeof(header)
|
||||
);
|
||||
|
||||
// Sanity check, remove once confident
|
||||
if(settings_get_value_length_(current_item)!=value_size) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
// Now write the data
|
||||
eeprom_write(
|
||||
settings_get_value_addr_(current_item),
|
||||
(unsigned char*)value,
|
||||
value_size
|
||||
);
|
||||
|
||||
ret = SETTINGS_STATUS_OK;
|
||||
|
||||
bail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
settings_status_t
|
||||
settings_set(settings_key_t key,const unsigned char* value,size_t value_size) {
|
||||
settings_status_t ret = SETTINGS_STATUS_FAILURE;
|
||||
eeprom_addr_t current_item = SETTINGS_TOP_ADDR;
|
||||
|
||||
for(current_item=SETTINGS_TOP_ADDR;settings_is_item_valid_(current_item);current_item=settings_next_item_(current_item)) {
|
||||
if(settings_get_key_(current_item)==key) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if((current_item==EEPROM_NULL) || !settings_is_item_valid_(current_item)) {
|
||||
ret = settings_add(key,value,value_size);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if(value_size!=settings_get_value_length_(current_item)) {
|
||||
// Requires the settings store to be shifted. Currently unimplemented.
|
||||
goto bail;
|
||||
}
|
||||
|
||||
// Now write the data
|
||||
eeprom_write(
|
||||
settings_get_value_addr_(current_item),
|
||||
(unsigned char*)value,
|
||||
value_size
|
||||
);
|
||||
|
||||
ret = SETTINGS_STATUS_OK;
|
||||
|
||||
bail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
settings_status_t
|
||||
settings_delete(settings_key_t key,uint8_t index) {
|
||||
// Requires the settings store to be shifted. Currently unimplemented.
|
||||
// TODO: Writeme!
|
||||
return SETTINGS_STATUS_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
settings_wipe(void) {
|
||||
size_t i = SETTINGS_TOP_ADDR-SETTINGS_MAX_SIZE;
|
||||
for(;i<=SETTINGS_TOP_ADDR;i++) {
|
||||
eeprom_write_byte((uint8_t*)i,0xFF);
|
||||
wdt_reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
118
cpu/avr/settings.h
Normal file
118
cpu/avr/settings.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
#ifndef __AVR_SETTINGS_H__
|
||||
#define __AVR_SETTINGS_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef uint16_t settings_key_t;
|
||||
|
||||
#define SETTINGS_KEY_EUI64 'E8' //!< Value always 8 bytes long
|
||||
#define SETTINGS_KEY_EUI48 'E6' //!< Value always 6 bytes long
|
||||
#define SETTINGS_KEY_CHANNEL 'CH' //!< Value always 1 byte long
|
||||
#define SETTINGS_KEY_TXPOWER 'TP' //!< Value always 1 byte long
|
||||
#define SETTINGS_KEY_PAN_ID 'PN' //!< Value always 2 bytes long
|
||||
#define SETTINGS_KEY_PAN_ADDR 'PA' //!< Value always 2 bytes long
|
||||
#define SETTINGS_KEY_AES128KEY 'SK' //!< Value always 16 bytes long
|
||||
#define SETTINGS_KEY_AES128ENABLED 'SE' //!< Value always 16 bytes long
|
||||
|
||||
typedef enum {
|
||||
SETTINGS_STATUS_OK=0,
|
||||
SETTINGS_STATUS_INVALID_ARGUMENT,
|
||||
SETTINGS_STATUS_NOT_FOUND,
|
||||
SETTINGS_STATUS_OUT_OF_SPACE,
|
||||
SETTINGS_STATUS_UNIMPLEMENTED,
|
||||
SETTINGS_STATUS_FAILURE,
|
||||
} settings_status_t;
|
||||
|
||||
// Use this when you want to retrieve the last item
|
||||
#define SETTINGS_LAST_INDEX (0xFF)
|
||||
|
||||
#define SETTINGS_INVALID_KEY (0x00)
|
||||
|
||||
#define SETTINGS_MAX_VALUE_SIZE (0x3FFF) // 16383 bytes
|
||||
|
||||
extern settings_status_t settings_get(settings_key_t key,uint8_t index,unsigned char* value,size_t* value_size);
|
||||
extern settings_status_t settings_add(settings_key_t key,const unsigned char* value,size_t value_size);
|
||||
extern bool settings_check(settings_key_t key,uint8_t index);
|
||||
extern void settings_wipe(void);
|
||||
|
||||
extern settings_status_t settings_set(settings_key_t key,const unsigned char* value,size_t value_size);
|
||||
extern settings_status_t settings_delete(settings_key_t key,uint8_t index);
|
||||
|
||||
//#pragma mark -
|
||||
//#pragma mark Inline convenience functions
|
||||
|
||||
static inline uint8_t
|
||||
settings_get_uint8(settings_key_t key,uint8_t index) {
|
||||
uint8_t ret = 0;
|
||||
size_t sizeof_uint8 = sizeof(uint8_t);
|
||||
settings_get(key,index,(unsigned char*)&ret,&sizeof_uint8);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline settings_status_t
|
||||
settings_add_uint8(settings_key_t key,uint8_t value) {
|
||||
return settings_add(key,(const unsigned char*)&value,sizeof(uint8_t));
|
||||
}
|
||||
|
||||
static inline settings_status_t
|
||||
settings_set_uint8(settings_key_t key,uint8_t value) {
|
||||
return settings_set(key,(const unsigned char*)&value,sizeof(uint8_t));
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
settings_get_uint16(settings_key_t key,uint8_t index) {
|
||||
uint16_t ret = 0;
|
||||
size_t sizeof_uint16 = sizeof(uint16_t);
|
||||
settings_get(key,index,(unsigned char*)&ret,&sizeof_uint16);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline settings_status_t
|
||||
settings_add_uint16(settings_key_t key,uint16_t value) {
|
||||
return settings_add(key,(const unsigned char*)&value,sizeof(uint16_t));
|
||||
}
|
||||
|
||||
static inline settings_status_t
|
||||
settings_set_uint16(settings_key_t key,uint16_t value) {
|
||||
return settings_set(key,(const unsigned char*)&value,sizeof(uint16_t));
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
settings_get_uint32(settings_key_t key,uint8_t index) {
|
||||
uint32_t ret = 0;
|
||||
size_t sizeof_uint32 = sizeof(uint32_t);
|
||||
settings_get(key,index,(unsigned char*)&ret,&sizeof_uint32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline settings_status_t
|
||||
settings_add_uint32(settings_key_t key,uint32_t value) {
|
||||
return settings_add(key,(const unsigned char*)&value,sizeof(uint32_t));
|
||||
}
|
||||
|
||||
static inline settings_status_t
|
||||
settings_set_uint32(settings_key_t key,uint32_t value) {
|
||||
return settings_set(key,(const unsigned char*)&value,sizeof(uint32_t));
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
settings_get_uint64(settings_key_t key,uint8_t index) {
|
||||
uint64_t ret = 0;
|
||||
size_t sizeof_uint64 = sizeof(uint64_t);
|
||||
settings_get(key,index,(unsigned char*)&ret,&sizeof_uint64);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline settings_status_t
|
||||
settings_add_uint64(settings_key_t key,uint64_t value) {
|
||||
return settings_add(key,(const unsigned char*)&value,sizeof(uint64_t));
|
||||
}
|
||||
|
||||
static inline settings_status_t
|
||||
settings_set_uint64(settings_key_t key,uint64_t value) {
|
||||
return settings_set(key,(const unsigned char*)&value,sizeof(uint64_t));
|
||||
}
|
||||
|
||||
#endif
|
|
@ -28,35 +28,52 @@
|
|||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* @(#)$Id: watchdog.c,v 1.1 2010/02/07 07:43:35 adamdunkels Exp $
|
||||
* @(#)$Id: watchdog.c,v 1.2 2010/09/17 21:59:09 dak664 Exp $
|
||||
*/
|
||||
|
||||
/* Dummy watchdog routines for the Raven 1284p */
|
||||
#include "dev/watchdog.h"
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
static int stopped = 0;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
watchdog_init(void)
|
||||
{
|
||||
MCUSR&=~(1<<WDRF);
|
||||
stopped = 0;
|
||||
watchdog_stop();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
watchdog_start(void)
|
||||
{
|
||||
stopped--;
|
||||
if(!stopped)
|
||||
wdt_enable(WDTO_2S);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
watchdog_periodic(void)
|
||||
{
|
||||
if(!stopped)
|
||||
wdt_reset();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
watchdog_stop(void)
|
||||
{
|
||||
stopped++;
|
||||
wdt_disable();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
watchdog_reboot(void)
|
||||
{
|
||||
cli();
|
||||
wdt_enable(WDTO_15MS); //wd on,250ms
|
||||
while(1); //loop
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -115,12 +115,43 @@ extern uint8_t domain_name[30];
|
|||
uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
|
||||
#endif
|
||||
|
||||
|
||||
static uint8_t get_channel_from_eeprom() {
|
||||
uint8_t eeprom_channel;
|
||||
uint8_t eeprom_check;
|
||||
|
||||
eeprom_channel = eeprom_read_byte((uint8_t *)9);
|
||||
eeprom_check = eeprom_read_byte((uint8_t *)10);
|
||||
|
||||
if(eeprom_channel==~eeprom_check)
|
||||
return eeprom_channel;
|
||||
return 26;
|
||||
}
|
||||
|
||||
static bool get_mac_from_eeprom(uint8_t* macptr) {
|
||||
eeprom_read_block ((void *)macptr, &mac_address, 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint16_t get_panid_from_eeprom(void) {
|
||||
// TODO: Writeme!
|
||||
return IEEE802154_PANID;
|
||||
}
|
||||
|
||||
static uint16_t get_panaddr_from_eeprom(void) {
|
||||
// TODO: Writeme!
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------Low level initialization------------------------*/
|
||||
/*------Done in a subroutine to keep main routine stack usage small--------*/
|
||||
void initialize(void)
|
||||
{
|
||||
//calibrate_rc_osc_32k(); //CO: Had to comment this out
|
||||
|
||||
watchdog_init();
|
||||
watchdog_start();
|
||||
|
||||
#ifdef RAVEN_LCD_INTERFACE
|
||||
/* First rs232 port for Raven 3290 port */
|
||||
rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
|
||||
|
@ -155,13 +186,15 @@ void initialize(void)
|
|||
|
||||
rimeaddr_t addr;
|
||||
memset(&addr, 0, sizeof(rimeaddr_t));
|
||||
AVR_ENTER_CRITICAL_REGION();
|
||||
eeprom_read_block ((void *)&addr.u8, &mac_address, 8);
|
||||
AVR_LEAVE_CRITICAL_REGION();
|
||||
get_mac_from_eeprom(addr.u8);
|
||||
|
||||
memcpy(&uip_lladdr.addr, &addr.u8, 8);
|
||||
rf230_set_pan_addr(IEEE802154_PANID, 0, (uint8_t *)&addr.u8);
|
||||
rf230_set_channel(26);
|
||||
rf230_set_pan_addr(
|
||||
get_panid_from_eeprom(),
|
||||
get_panaddr_from_eeprom(),
|
||||
(uint8_t *)&addr.u8
|
||||
);
|
||||
rf230_set_channel(get_channel_from_eeprom());
|
||||
|
||||
rimeaddr_set_node_addr(&addr);
|
||||
|
||||
|
@ -312,7 +345,7 @@ main(void)
|
|||
// len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE);
|
||||
// packetbuf_set_datalen(42);
|
||||
// NETSTACK_RDC.input();
|
||||
|
||||
watchdog_periodic();
|
||||
#if TESTRTIMER
|
||||
if (rtimerflag) { //8 seconds is maximum interval, my raven 6% slow
|
||||
rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
|
||||
|
|
|
@ -7,15 +7,16 @@ USB = uart_usb_lib.c \
|
|||
cdc_task.c \
|
||||
rndis_task.c \
|
||||
rndis.c \
|
||||
cdc_eem.c \
|
||||
cdc_ecm.c \
|
||||
usb_descriptors.c \
|
||||
usb_drv.c \
|
||||
usb_specific_request.c \
|
||||
usb_standard_request.c \
|
||||
usb_task.c \
|
||||
scsi_decoder.c \
|
||||
ctrl_access.c \
|
||||
storage_task.c \
|
||||
avr_flash.c
|
||||
usb_task.c
|
||||
|
||||
#Files needed for USB Mass storage device enumeration
|
||||
USB += scsi_decoder.c ctrl_access.c storage_task.c avr_flash.c
|
||||
|
||||
#As of September 2010 the following are needed for rpl. They need explicit inclusion if CONTIKI_NO_NET=1
|
||||
#If CONTIKI_NO_NET=1 the tcpip_input routine in tcpip.c must be commented out; it expects a tcpip process and conflicts with the one in fakeuip.c
|
||||
|
@ -24,7 +25,7 @@ USB = uart_usb_lib.c \
|
|||
CONTIKI_TARGET_SOURCEFILES += cfs-eeprom.c eeprom.c random.c \
|
||||
mmem.c contiki-raven-default-init-lowlevel.c \
|
||||
contiki-raven-default-init-net.c contiki-raven-main.c httpd-simple-avr.c \
|
||||
sicslow_ethernet.c queuebuf.c packetbuf.c \
|
||||
sicslow_ethernet.c queuebuf.c packetbuf.c rng.c \
|
||||
$(RPL) \
|
||||
$(USB)
|
||||
|
||||
|
|
578
platform/avr-ravenusb/cdc_task.c
Normal file
578
platform/avr-ravenusb/cdc_task.c
Normal file
|
@ -0,0 +1,578 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file cdc_task.c **********************************************************
|
||||
*
|
||||
* \brief
|
||||
* Manages the CDC-ACM Virtual Serial Port Dataclass for the USB Device
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY 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 COPYRIGHT OWNER 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.
|
||||
*/
|
||||
/**
|
||||
\ingroup usbstick
|
||||
\defgroup cdctask CDC Task
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ___________________________________________________
|
||||
|
||||
|
||||
#include "contiki.h"
|
||||
#include "usb_drv.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include "cdc_task.h"
|
||||
#include "serial/uart_usb_lib.h"
|
||||
#include "rndis/rndis_protocol.h"
|
||||
#include "rndis/rndis_task.h"
|
||||
#include "sicslow_ethernet.h"
|
||||
#if RF230BB
|
||||
#include "rf230bb.h"
|
||||
#else
|
||||
#include "radio.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "dev/watchdog.h"
|
||||
#include "rng.h"
|
||||
|
||||
#include "bootloader.h"
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#if JACKDAW_CONF_USE_SETTINGS
|
||||
#include "settings.h"
|
||||
#endif
|
||||
|
||||
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
#define PRINTF printf
|
||||
#define PRINTF_P printf_P
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
#define bzero(ptr,size) memset(ptr,0,size)
|
||||
|
||||
//_____ D E F I N I T I O N S ______________________________________________
|
||||
|
||||
|
||||
#define IAD_TIMEOUT_DETACH 300
|
||||
#define IAD_TIMEOUT_ATTACH 600
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
void menu_print(void);
|
||||
void menu_process(char c);
|
||||
|
||||
extern char usb_busy;
|
||||
|
||||
//! Counter for USB Serial port
|
||||
extern U8 tx_counter;
|
||||
|
||||
//! Timers for LEDs
|
||||
uint8_t led3_timer;
|
||||
|
||||
|
||||
//! previous configuration
|
||||
static uint8_t previous_uart_usb_control_line_state = 0;
|
||||
|
||||
|
||||
static uint8_t timer = 0;
|
||||
static struct etimer et;
|
||||
|
||||
|
||||
PROCESS(cdc_process, "CDC serial process");
|
||||
|
||||
/**
|
||||
* \brief Communication Data Class (CDC) Process
|
||||
*
|
||||
* This is the link between USB and the "good stuff". In this routine data
|
||||
* is received and processed by CDC-ACM Class
|
||||
*/
|
||||
PROCESS_THREAD(cdc_process, ev, data_proc)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
while(1) {
|
||||
// turn off LED's if necessary
|
||||
if (led3_timer) led3_timer--;
|
||||
else Led3_off();
|
||||
|
||||
|
||||
if(Is_device_enumerated()) {
|
||||
// If the configuration is different than the last time we checked...
|
||||
if((uart_usb_get_control_line_state()&1)!=previous_uart_usb_control_line_state) {
|
||||
previous_uart_usb_control_line_state = uart_usb_get_control_line_state()&1;
|
||||
static FILE* previous_stdout;
|
||||
|
||||
if(previous_uart_usb_control_line_state&1) {
|
||||
previous_stdout = stdout;
|
||||
uart_usb_init();
|
||||
uart_usb_set_stdout();
|
||||
menu_print();
|
||||
} else {
|
||||
stdout = previous_stdout;
|
||||
}
|
||||
}
|
||||
|
||||
//Flush buffer if timeout
|
||||
if(timer >= 4 && tx_counter!=0 ){
|
||||
timer = 0;
|
||||
uart_usb_flush();
|
||||
} else {
|
||||
timer++;
|
||||
}
|
||||
|
||||
while (uart_usb_test_hit()){
|
||||
menu_process(uart_usb_getchar()); // See what they want
|
||||
}
|
||||
|
||||
|
||||
}//if (Is_device_enumerated())
|
||||
|
||||
|
||||
if (USB_CONFIG_HAS_DEBUG_PORT(usb_configuration_nb)) {
|
||||
etimer_set(&et, CLOCK_SECOND/80);
|
||||
} else {
|
||||
etimer_set(&et, CLOCK_SECOND);
|
||||
}
|
||||
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
|
||||
|
||||
} // while(1)
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Print debug menu
|
||||
*/
|
||||
void menu_print(void)
|
||||
{
|
||||
PRINTF_P(PSTR("\n\r********** Jackdaw Menu ******************\n\r"));
|
||||
PRINTF_P(PSTR("* *\n\r"));
|
||||
PRINTF_P(PSTR("* Main Menu: *\n\r"));
|
||||
PRINTF_P(PSTR("* h,? Print this menu *\n\r"));
|
||||
PRINTF_P(PSTR("* m Print current mode *\n\r"));
|
||||
PRINTF_P(PSTR("* s Set to sniffer mode *\n\r"));
|
||||
PRINTF_P(PSTR("* n Set to network mode *\n\r"));
|
||||
PRINTF_P(PSTR("* c Set RF channel *\n\r"));
|
||||
PRINTF_P(PSTR("* 6 Toggle 6lowpan *\n\r"));
|
||||
PRINTF_P(PSTR("* r Toggle raw mode *\n\r"));
|
||||
PRINTF_P(PSTR("* e Energy Scan *\n\r"));
|
||||
#if USB_CONF_STORAGE
|
||||
PRINTF_P(PSTR("* u Switch to mass-storage*\n\r"));
|
||||
#endif
|
||||
if(bootloader_is_present())
|
||||
PRINTF_P(PSTR("* D Switch to DFU mode *\n\r"));
|
||||
PRINTF_P(PSTR("* R Reset (via WDT) *\n\r"));
|
||||
PRINTF_P(PSTR("* *\n\r"));
|
||||
PRINTF_P(PSTR("* Make selection at any time by pressing *\n\r"));
|
||||
PRINTF_P(PSTR("* your choice on keyboard. *\n\r"));
|
||||
PRINTF_P(PSTR("******************************************\n\r"));
|
||||
PRINTF_P(PSTR("[Built "__DATE__"]\n\r"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Process incomming char on debug port
|
||||
*/
|
||||
void menu_process(char c)
|
||||
{
|
||||
|
||||
static enum menustate_enum /* Defines an enumeration type */
|
||||
{
|
||||
normal,
|
||||
channel
|
||||
} menustate = normal;
|
||||
|
||||
static char channel_string[3];
|
||||
static uint8_t channel_string_i = 0;
|
||||
|
||||
int tempchannel;
|
||||
|
||||
if (menustate == channel) {
|
||||
|
||||
switch(c) {
|
||||
case '\r':
|
||||
case '\n':
|
||||
|
||||
if (channel_string_i) {
|
||||
channel_string[channel_string_i] = 0;
|
||||
tempchannel = atoi(channel_string);
|
||||
|
||||
#if RF230BB
|
||||
if ((tempchannel < 11) || (tempchannel > 26)) {
|
||||
PRINTF_P(PSTR("\n\rInvalid input\n\r"));
|
||||
} else {
|
||||
rf230_set_channel(tempchannel);
|
||||
#else
|
||||
if(radio_set_operating_channel(tempchannel)!=RADIO_SUCCESS) {
|
||||
PRINTF_P(PSTR("\n\rInvalid input\n\r"));
|
||||
} else {
|
||||
#endif
|
||||
#if JACKDAW_CONF_USE_SETTINGS
|
||||
if(settings_set_uint8(SETTINGS_KEY_CHANNEL, tempchannel)!=SETTINGS_STATUS_OK) {
|
||||
PRINTF_P(PSTR("\n\rChannel changed to %d, but unable to store in EEPROM!\n\r"),tempchannel);
|
||||
} else
|
||||
#else
|
||||
AVR_ENTER_CRITICAL_REGION();
|
||||
eeprom_write_byte((uint8_t *) 9, tempchannel); //Write channel
|
||||
eeprom_write_byte((uint8_t *)10, ~tempchannel); //Bit inverse as check
|
||||
AVR_LEAVE_CRITICAL_REGION();
|
||||
#endif
|
||||
PRINTF_P(PSTR("\n\rChannel changed to %d and stored in EEPROM.\n\r"),tempchannel);
|
||||
}
|
||||
} else {
|
||||
PRINTF_P(PSTR("\n\rChannel unchanged.\n\r"));
|
||||
}
|
||||
|
||||
menustate = normal;
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
|
||||
if (channel_string_i) {
|
||||
channel_string_i--;
|
||||
PRINTF_P(PSTR("\b \b"));
|
||||
}
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (channel_string_i > 1) {
|
||||
// This time the user has gone too far.
|
||||
// Beep at them.
|
||||
putc('\a', stdout);
|
||||
//uart_usb_putchar('\a');
|
||||
break;
|
||||
}
|
||||
putc(c, stdout);
|
||||
//uart_usb_putchar(c);
|
||||
|
||||
channel_string[channel_string_i] = c;
|
||||
channel_string_i++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
uint8_t i;
|
||||
switch(c) {
|
||||
case '\r':
|
||||
case '\n':
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
menu_print();
|
||||
break;
|
||||
case '-':
|
||||
PRINTF_P(PSTR("Bringing interface down\n\r"));
|
||||
usb_eth_set_active(0);
|
||||
break;
|
||||
case '=':
|
||||
case '+':
|
||||
PRINTF_P(PSTR("Bringing interface up\n\r"));
|
||||
usb_eth_set_active(1);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
// I added this to test my "strong" random number generator.
|
||||
PRINTF_P(PSTR("RNG Output: "));
|
||||
{
|
||||
uint8_t value = rng_get_uint8();
|
||||
uint8_t i;
|
||||
for(i=0;i<8;i++) {
|
||||
uart_usb_putchar(((value>>(7-i))&1)?'1':'0');
|
||||
}
|
||||
PRINTF_P(PSTR("\n\r"));
|
||||
uart_usb_flush();
|
||||
watchdog_periodic();
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
PRINTF_P(PSTR("Jackdaw now in sniffer mode\n\r"));
|
||||
usbstick_mode.sendToRf = 0;
|
||||
usbstick_mode.translate = 0;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
PRINTF_P(PSTR("Jackdaw now in network mode\n\r"));
|
||||
usbstick_mode.sendToRf = 1;
|
||||
usbstick_mode.translate = 1;
|
||||
break;
|
||||
|
||||
case '6':
|
||||
if (usbstick_mode.sicslowpan) {
|
||||
PRINTF_P(PSTR("Jackdaw does not perform 6lowpan translation\n\r"));
|
||||
usbstick_mode.sicslowpan = 0;
|
||||
} else {
|
||||
PRINTF_P(PSTR("Jackdaw now performs 6lowpan translations\n\r"));
|
||||
usbstick_mode.sicslowpan = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if (usbstick_mode.raw) {
|
||||
PRINTF_P(PSTR("Jackdaw does not capture raw frames\n\r"));
|
||||
usbstick_mode.raw = 0;
|
||||
} else {
|
||||
PRINTF_P(PSTR("Jackdaw now captures raw frames\n\r"));
|
||||
usbstick_mode.raw = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
#if RF230BB
|
||||
PRINTF_P(PSTR("Select 802.15.4 Channel in range 11-26 [%d]: "), rf230_get_channel());
|
||||
#else
|
||||
PRINTF_P(PSTR("Select 802.15.4 Channel in range 11-26 [%d]: "), radio_get_operating_channel());
|
||||
#endif
|
||||
menustate = channel;
|
||||
channel_string_i = 0;
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case 'm':
|
||||
PRINTF_P(PSTR("Currently Jackdaw:\n\r * Will "));
|
||||
if (usbstick_mode.sendToRf == 0) { PRINTF_P(PSTR("not "));}
|
||||
PRINTF_P(PSTR("send data over RF\n\r * Will "));
|
||||
if (usbstick_mode.translate == 0) { PRINTF_P(PSTR("not "));}
|
||||
PRINTF_P(PSTR("change link-local addresses inside IP messages\n\r * Will "));
|
||||
if (usbstick_mode.sicslowpan == 0) { PRINTF_P(PSTR("not "));}
|
||||
PRINTF_P(PSTR("decompress 6lowpan headers\n\r * Will "));
|
||||
if (usbstick_mode.raw == 0) { PRINTF_P(PSTR("not "));}
|
||||
PRINTF_P(PSTR("Output raw 802.15.4 frames\n\r"));
|
||||
PRINTF_P(PSTR(" * USB Ethernet MAC: %02x:%02x:%02x:%02x:%02x:%02x\n"),
|
||||
((uint8_t *)&usb_ethernet_addr)[0],
|
||||
((uint8_t *)&usb_ethernet_addr)[1],
|
||||
((uint8_t *)&usb_ethernet_addr)[2],
|
||||
((uint8_t *)&usb_ethernet_addr)[3],
|
||||
((uint8_t *)&usb_ethernet_addr)[4],
|
||||
((uint8_t *)&usb_ethernet_addr)[5]
|
||||
);
|
||||
extern uint64_t macLongAddr;
|
||||
PRINTF_P(PSTR(" * 802.15.4 EUI-64: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n"),
|
||||
((uint8_t *)&macLongAddr)[0],
|
||||
((uint8_t *)&macLongAddr)[1],
|
||||
((uint8_t *)&macLongAddr)[2],
|
||||
((uint8_t *)&macLongAddr)[3],
|
||||
((uint8_t *)&macLongAddr)[4],
|
||||
((uint8_t *)&macLongAddr)[5],
|
||||
((uint8_t *)&macLongAddr)[6],
|
||||
((uint8_t *)&macLongAddr)[7]
|
||||
);
|
||||
#if RF230BB
|
||||
PRINTF_P(PSTR(" * Operates on channel %d\n\r"), rf230_get_channel());
|
||||
PRINTF_P(PSTR(" * TX Power Level: 0x%02X\n\r"), rf230_get_txpower());
|
||||
PRINTF_P(PSTR(" * Current RSSI: %ddB\n\r"), -91+3*(rf230_rssi()-1));
|
||||
PRINTF_P(PSTR(" * Last RSSI: %ddB\n\r"), -91+3*(rf230_last_rssi-1));
|
||||
#else // RF230BB
|
||||
PRINTF_P(PSTR(" * Operates on channel %d\n\r"), radio_get_operating_channel());
|
||||
PRINTF_P(PSTR(" * TX Power Level: 0x%02X\n\r"), radio_get_tx_power_level());
|
||||
{
|
||||
PRINTF_P(PSTR(" * Current RSSI: "));
|
||||
int8_t rssi = 0;
|
||||
if(radio_get_rssi_value(&rssi)==RADIO_SUCCESS)
|
||||
PRINTF_P(PSTR("%ddB\n\r"), -91+3*(rssi-1));
|
||||
else
|
||||
PRINTF_P(PSTR("Unknown\n\r"));
|
||||
}
|
||||
|
||||
#endif // !RF230BB
|
||||
PRINTF_P(PSTR(" * Configuration: %d\n\r"), usb_configuration_nb);
|
||||
PRINTF_P(PSTR(" * usb_eth_is_active: %d\n\r"), usb_eth_is_active);
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
PRINTF_P(PSTR("Energy Scan:\n"));
|
||||
uart_usb_flush();
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t j;
|
||||
#if RF230BB
|
||||
uint8_t previous_channel = rf230_get_channel();
|
||||
#else // RF230BB
|
||||
uint8_t previous_channel = radio_get_operating_channel();
|
||||
#endif
|
||||
int8_t RSSI, maxRSSI[17];
|
||||
uint16_t accRSSI[17];
|
||||
|
||||
bzero((void*)accRSSI,sizeof(accRSSI));
|
||||
bzero((void*)maxRSSI,sizeof(maxRSSI));
|
||||
|
||||
for(j=0;j<(1<<12);j++) {
|
||||
for(i=11;i<=26;i++) {
|
||||
#if RF230BB
|
||||
rf230_set_channel(i);
|
||||
#else // RF230BB
|
||||
radio_set_operating_channel(i);
|
||||
#endif
|
||||
_delay_us(3*10);
|
||||
#if RF230BB
|
||||
RSSI = rf230_rssi();
|
||||
#else // RF230BB
|
||||
radio_get_rssi_value(&RSSI);
|
||||
#endif
|
||||
maxRSSI[i-11]=Max(maxRSSI[i-11],RSSI);
|
||||
accRSSI[i-11]+=RSSI;
|
||||
}
|
||||
if(j&(1<<7)) {
|
||||
Led3_on();
|
||||
if(!(j&((1<<7)-1))) {
|
||||
PRINTF_P(PSTR("."));
|
||||
uart_usb_flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
Led3_off();
|
||||
watchdog_periodic();
|
||||
}
|
||||
#if RF230BB
|
||||
rf230_set_channel(previous_channel);
|
||||
#else // RF230BB
|
||||
radio_set_operating_channel(previous_channel);
|
||||
#endif
|
||||
PRINTF_P(PSTR("\n"));
|
||||
for(i=11;i<=26;i++) {
|
||||
uint8_t activity=Min(maxRSSI[i-11],accRSSI[i-11]/(1<<7));
|
||||
PRINTF_P(PSTR(" %d: %02ddB "),i, -91+3*(maxRSSI[i-11]-1));
|
||||
for(;activity--;maxRSSI[i-11]--) {
|
||||
PRINTF_P(PSTR("#"));
|
||||
}
|
||||
for(;maxRSSI[i-11]>0;maxRSSI[i-11]--) {
|
||||
PRINTF_P(PSTR(":"));
|
||||
}
|
||||
PRINTF_P(PSTR("\n"));
|
||||
uart_usb_flush();
|
||||
}
|
||||
|
||||
}
|
||||
PRINTF_P(PSTR("Done.\n"));
|
||||
uart_usb_flush();
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case 'D':
|
||||
{
|
||||
PRINTF_P(PSTR("Entering DFU Mode...\n\r"));
|
||||
uart_usb_flush();
|
||||
Leds_on();
|
||||
for(i = 0; i < 10; i++)_delay_ms(100);
|
||||
Leds_off();
|
||||
Jump_To_Bootloader();
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
{
|
||||
PRINTF_P(PSTR("Resetting...\n\r"));
|
||||
uart_usb_flush();
|
||||
Leds_on();
|
||||
for(i = 0; i < 10; i++)_delay_ms(100);
|
||||
Usb_detach();
|
||||
for(i = 0; i < 20; i++)_delay_ms(100);
|
||||
watchdog_reboot();
|
||||
}
|
||||
break;
|
||||
|
||||
#if USB_CONF_STORAGE
|
||||
case 'u':
|
||||
|
||||
//Mass storage mode
|
||||
usb_mode = mass_storage;
|
||||
|
||||
//No more serial port
|
||||
stdout = NULL;
|
||||
|
||||
//RNDIS is over
|
||||
rndis_state = rndis_uninitialized;
|
||||
Leds_off();
|
||||
|
||||
//Deatch USB
|
||||
Usb_detach();
|
||||
|
||||
//Wait a few seconds
|
||||
for(i = 0; i < 50; i++)
|
||||
_delay_ms(100);
|
||||
|
||||
//Attach USB
|
||||
Usb_attach();
|
||||
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
PRINTF_P(PSTR("%c is not a valid option! h for menu\n\r"), c);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief This will enable the VCP_TRX_END LED for a period
|
||||
*/
|
||||
void vcptx_end_led(void)
|
||||
{
|
||||
Led3_on();
|
||||
led3_timer = 5;
|
||||
}
|
||||
/** @} */
|
||||
|
74
platform/avr-ravenusb/cdc_task.h
Normal file
74
platform/avr-ravenusb/cdc_task.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/* This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file cdc_task.h ************************************************************
|
||||
*
|
||||
* \brief
|
||||
* This file manages the CDC task for the virtual COM port.
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2008 ATMEL Corporation
|
||||
Copyright (c) 2008 Colin O'Flynn
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY 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 COPYRIGHT OWNER 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.
|
||||
*/
|
||||
|
||||
#ifndef _CDC_TASK_H_
|
||||
#define _CDC_TASK_H_
|
||||
|
||||
/**
|
||||
\addtogroup cdctask
|
||||
@{
|
||||
*/
|
||||
|
||||
//_____ I N C L U D E S ____________________________________________________
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
//_____ M A C R O S ________________________________________________________
|
||||
|
||||
|
||||
|
||||
//_____ D E C L A R A T I O N S ____________________________________________
|
||||
|
||||
|
||||
void sof_action(void);
|
||||
void vcptx_end_led(void);
|
||||
|
||||
void rawmode_enable(void);
|
||||
void rawmode_disable(void);
|
||||
|
||||
PROCESS_NAME(cdc_process);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _CDC_TASK_H_ */
|
||||
|
|
@ -43,6 +43,14 @@
|
|||
#ifndef __CONTIKI_CONF_H__
|
||||
#define __CONTIKI_CONF_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ************************************************************************** */
|
||||
//#pragma mark Basic Configuration
|
||||
/* ************************************************************************** */
|
||||
|
||||
/* MCU and clock rate */
|
||||
#define MCU_MHZ 8
|
||||
#define PLATFORM PLATFORM_AVR
|
||||
|
@ -51,6 +59,14 @@
|
|||
/* Clock ticks per second */
|
||||
#define CLOCK_CONF_SECOND 125
|
||||
|
||||
/* Mac address, RF channel, PANID from EEPROM settings manager */
|
||||
/* Generate random MAC address on first startup */
|
||||
/* Random number from radio clock skew or ADC noise */
|
||||
#define JACKDAW_CONF_USE_SETTINGS 1
|
||||
#define JACKDAW_CONF_RANDOM_MAC 0
|
||||
#define RNG_CONF_USE_RADIO_CLOCK 1
|
||||
//#define RNG_CONF_USE_ADC 1
|
||||
|
||||
/* Since clock_time_t is 16 bits, maximum interval is 524 seconds */
|
||||
#define RIME_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME CLOCK_CONF_SECOND * 524UL /*Default uses 600*/
|
||||
|
||||
|
@ -74,13 +90,71 @@
|
|||
#define CCIF
|
||||
#define CLIF
|
||||
|
||||
#define RIMEADDR_CONF_SIZE 8
|
||||
/* ************************************************************************** */
|
||||
//#pragma mark USB Ethernet Hooks
|
||||
/* ************************************************************************** */
|
||||
|
||||
#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06
|
||||
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2
|
||||
#ifndef USB_ETH_HOOK_IS_READY_FOR_INBOUND_PACKET
|
||||
#if RF230BB
|
||||
#define USB_ETH_HOOK_IS_READY_FOR_INBOUND_PACKET() rf230_is_ready_to_send()
|
||||
#else
|
||||
static inline uint8_t radio_is_ready_to_send_() {
|
||||
switch(radio_get_trx_state()) {
|
||||
case BUSY_TX:
|
||||
case BUSY_TX_ARET:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#define USB_ETH_HOOK_IS_READY_FOR_INBOUND_PACKET() radio_is_ready_to_send_()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef USB_ETH_HOOK_HANDLE_INBOUND_PACKET
|
||||
#define USB_ETH_HOOK_HANDLE_INBOUND_PACKET(buffer,len) do { uip_len = len ; mac_ethernetToLowpan(buffer); } while(0)
|
||||
#endif
|
||||
|
||||
#ifndef USB_ETH_HOOK_SET_PROMISCIOUS_MODE
|
||||
#if RF230BB
|
||||
#define USB_ETH_HOOK_SET_PROMISCIOUS_MODE(value) rf230_set_promiscuous_mode(value)
|
||||
#else
|
||||
#define USB_ETH_HOOK_SET_PROMISCIOUS_MODE(value) radio_set_trx_state(value?RX_ON:RX_AACK_ON)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef USB_ETH_HOOK_INIT
|
||||
#define USB_ETH_HOOK_INIT() mac_ethernetSetup()
|
||||
#endif
|
||||
|
||||
/* ************************************************************************** */
|
||||
//#pragma mark RF230BB Hooks
|
||||
/* ************************************************************************** */
|
||||
|
||||
//#define RF230BB_HOOK_RADIO_OFF() Led1_off()
|
||||
//#define RF230BB_HOOK_RADIO_ON() Led1_on()
|
||||
#define RF230BB_HOOK_TX_PACKET(buffer,total_len) mac_log_802_15_4_tx(buffer,total_len)
|
||||
#define RF230BB_HOOK_RX_PACKET(buffer,total_len) mac_log_802_15_4_rx(buffer,total_len)
|
||||
#define RF230BB_HOOK_IS_SEND_ENABLED() mac_is_send_enabled()
|
||||
extern bool mac_is_send_enabled(void);
|
||||
extern void mac_log_802_15_4_tx(const uint8_t* buffer, size_t total_len);
|
||||
extern void mac_log_802_15_4_rx(const uint8_t* buffer, size_t total_len);
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
//#pragma mark USB CDC-ACM (UART) Hooks
|
||||
/* ************************************************************************** */
|
||||
|
||||
#define USB_CDC_ACM_HOOK_TX_END(char) vcptx_end_led()
|
||||
#define USB_CDC_ACM_HOOK_CLS_CHANGED(state) vcptx_end_led()
|
||||
#define USB_CDC_ACM_HOOK_CONFIGURED() vcptx_end_led()
|
||||
|
||||
/* ************************************************************************** */
|
||||
//#pragma mark UIP Settings
|
||||
/* ************************************************************************** */
|
||||
|
||||
#define UIP_CONF_LL_802154 1
|
||||
#define UIP_CONF_LLH_LEN 14
|
||||
#define UIP_CONF_BUFSIZE UIP_LINK_MTU + UIP_LLH_LEN + 4 // +4 for vlan on macosx
|
||||
|
||||
#define UIP_CONF_MAX_CONNECTIONS 4
|
||||
#define UIP_CONF_MAX_LISTENPORTS 4
|
||||
|
@ -104,15 +178,38 @@
|
|||
#define UIP_CONF_TCP_SPLIT 1
|
||||
|
||||
#define UIP_CONF_STATISTICS 1
|
||||
/* Disable mass storage enumeration for more debug string space */
|
||||
//#define USB_CONF_STORAGE 1
|
||||
/* Use either USB CDC or RS232 for stdout (or neither) */
|
||||
//#define USB_CONF_CDC 1
|
||||
#define USB_CONF_RS232 1
|
||||
|
||||
/* ************************************************************************** */
|
||||
//#pragma mark Serial Port Settings
|
||||
/* ************************************************************************** */
|
||||
|
||||
/* Disable mass storage enumeration for more program space */
|
||||
/* TODO: Mass storage is currently broken */
|
||||
#define USB_CONF_STORAGE 0
|
||||
/* Use either USB CDC or RS232 for stdout (or neither) */
|
||||
/* TODO:CDC is currently broken on windows/linux, use RS232 */
|
||||
#define USB_CONF_CDC 1
|
||||
//#define USB_CONF_RS232 1
|
||||
|
||||
/* ************************************************************************** */
|
||||
//#pragma mark RIME Settings
|
||||
/* ************************************************************************** */
|
||||
|
||||
#define RIMEADDR_CONF_SIZE 8
|
||||
|
||||
/* ************************************************************************** */
|
||||
//#pragma mark SICSLOWPAN Settings
|
||||
/* ************************************************************************** */
|
||||
|
||||
#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06
|
||||
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2
|
||||
#ifdef RF230BB
|
||||
#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 //for barebones driver, sicslowpan calls radio->read function
|
||||
|
||||
/* ************************************************************************** */
|
||||
//#pragma mark NETSTACK Settings
|
||||
/* ************************************************************************** */
|
||||
|
||||
#if 1 /* Network setup */
|
||||
/* No radio cycling */
|
||||
#define NETSTACK_CONF_NETWORK sicslowpan_driver
|
||||
|
@ -158,12 +255,19 @@
|
|||
#error Network configuration not specified!
|
||||
#endif /* Network setup */
|
||||
|
||||
#if 0 /* RPL */
|
||||
|
||||
/* ************************************************************************** */
|
||||
//#pragma mark RPL Settings
|
||||
/* ************************************************************************** */
|
||||
|
||||
#define UIP_CONF_IPV6_RPL 0
|
||||
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
|
||||
/* Not completely working yet. Link local pings work but address prefixes do not get assigned */
|
||||
/* RPL requires the uip stack. Change #CONTIKI_NO_NET=1 to UIP_CONF_IPV6=1 in the examples makefile,
|
||||
or include the needed source files in /plaftorm/avr-ravenusb/Makefile.avr-ravenusb */
|
||||
|
||||
#define UIP_CONF_IPV6_RPL 1
|
||||
#define UIP_CONF_ROUTER 1
|
||||
#define RPL_CONF_STATS 0
|
||||
#define PROCESS_CONF_NO_PROCESS_NAMES 0
|
||||
|
@ -212,11 +316,13 @@ or include the needed source files in /plaftorm/avr-ravenusb/Makefile.avr-ravenu
|
|||
#define UIP_CONF_PINGADDRCONF 0
|
||||
#define UIP_CONF_LOGGING 0
|
||||
#endif
|
||||
#endif /* RPL */
|
||||
|
||||
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
#endif /* RF230BB */
|
||||
|
||||
/* ************************************************************************** */
|
||||
//#pragma mark Other Settings
|
||||
/* ************************************************************************** */
|
||||
|
||||
/* Route-Under-MAC uses 16-bit short addresses */
|
||||
#if UIP_CONF_USE_RUM
|
||||
#undef UIP_CONF_LL_802154
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "usb_descriptors.h"
|
||||
#include "usb_specific_request.h"
|
||||
#include <util/delay.h>
|
||||
#include "bootloader.h"
|
||||
|
||||
uint8_t checkForFinger(void);
|
||||
|
||||
|
@ -54,6 +55,8 @@ init_lowlevel(void)
|
|||
Leds_off();
|
||||
|
||||
if (checkForFinger()) {
|
||||
if(bootloader_is_present())
|
||||
Jump_To_Bootloader();
|
||||
#ifdef WINXPSP2
|
||||
usb_mode = mass_storage;
|
||||
#else
|
||||
|
|
|
@ -35,36 +35,64 @@
|
|||
#include "contiki-raven.h"
|
||||
#if !RF230BB
|
||||
#include "zmac.h"
|
||||
#else
|
||||
extern uint64_t macLongAddr;
|
||||
#endif
|
||||
#include "sicslowpan.h"
|
||||
extern uint64_t rndis_ethernet_addr;
|
||||
#include "sicslow_ethernet.h"
|
||||
#include "rndis/rndis_task.h"
|
||||
|
||||
void byte_reverse(uint8_t * bytes, uint8_t num)
|
||||
{
|
||||
uint8_t tempbyte;
|
||||
|
||||
uint8_t i, j;
|
||||
|
||||
i = 0;
|
||||
j = num - 1;
|
||||
|
||||
while(i < j) {
|
||||
tempbyte = bytes[i];
|
||||
bytes[i] = bytes[j];
|
||||
bytes[j] = tempbyte;
|
||||
|
||||
j--;
|
||||
i++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
init_net(void)
|
||||
{
|
||||
extern uint64_t macLongAddr;
|
||||
uint64_t usb_ethernet_addr;
|
||||
|
||||
// Because all of the logic below is done using little-endian
|
||||
// 64-bit integers, we need to reverse the byte order before
|
||||
// we can continue;
|
||||
byte_reverse((uint8_t*)&macLongAddr,8);
|
||||
|
||||
|
||||
|
||||
/* Set local bit, Clear translate bit, Clear Multicast bit */
|
||||
macLongAddr &= ~(0x0700000000000000ULL);
|
||||
macLongAddr |= 0x0200000000000000ULL;
|
||||
|
||||
/* Set local bit, Clear translate bit, Clear Multicast bit */
|
||||
macLongAddr &= ~(0x0700000000000000ULL);
|
||||
macLongAddr |= 0x0200000000000000ULL;
|
||||
|
||||
/* Set the Ethernet address to the 15.4 MAC address */
|
||||
rndis_ethernet_addr = macLongAddr;
|
||||
|
||||
/* Remove the middle two bytes... */
|
||||
rndis_ethernet_addr = (rndis_ethernet_addr & 0xffffffUL) | ((rndis_ethernet_addr & 0xffffff0000000000ULL) >> 16);
|
||||
/* Set the Ethernet address to the 15.4 MAC address */
|
||||
usb_ethernet_addr = macLongAddr;
|
||||
|
||||
/* Change ieee802.15.4 address to correspond with what the ethernet's
|
||||
IPv6 address will be. This will have ff:fe in the middle. */
|
||||
macLongAddr = (macLongAddr & 0xffffff0000ffffffULL) | (0x000000fffe000000ULL);
|
||||
/* Remove the middle two bytes... */
|
||||
usb_ethernet_addr = (usb_ethernet_addr & 0xffffffUL) | ((usb_ethernet_addr & 0xffffff0000000000ULL) >> 16);
|
||||
|
||||
/* Change ieee802.15.4 address to correspond with what the ethernet's
|
||||
IPv6 address will be. This will have ff:fe in the middle. */
|
||||
macLongAddr = (macLongAddr & 0xffffff0000ffffffULL) | (0x000000fffe000000ULL);
|
||||
|
||||
#if !RF230BB
|
||||
ieee15_4ManagerAddress.set_long_addr(macLongAddr);
|
||||
ieee15_4ManagerAddress.set_long_addr(macLongAddr);
|
||||
#endif
|
||||
|
||||
byte_reverse((uint8_t*)&macLongAddr,8);
|
||||
byte_reverse((uint8_t*)&usb_ethernet_addr,6);
|
||||
|
||||
usb_eth_set_mac_address((uint8_t*)&usb_ethernet_addr);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include <avr/pgmspace.h>
|
||||
#include <avr/fuse.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <util/delay.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -68,7 +69,7 @@
|
|||
|
||||
#include "usb_task.h"
|
||||
#if USB_CONF_CDC
|
||||
#include "serial/cdc_task.h"
|
||||
#include "cdc_task.h"
|
||||
#elif USB_CONF_RS232
|
||||
#include "dev/rs232.h"
|
||||
#endif
|
||||
|
@ -78,13 +79,21 @@
|
|||
#include "storage/storage_task.h"
|
||||
#endif
|
||||
|
||||
#include "dev/watchdog.h"
|
||||
#include "dev/usb/usb_drv.h"
|
||||
|
||||
#if JACKDAW_CONF_USE_SETTINGS
|
||||
#include "settings.h"
|
||||
#endif
|
||||
|
||||
#if RF230BB //radio driver using contiki core mac
|
||||
#include "radio/rf230bb/rf230bb.h"
|
||||
#include "net/mac/frame802154.h"
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
extern int rf230_interrupt_flag;
|
||||
extern uint8_t rf230processflag;
|
||||
rimeaddr_t addr,macLongAddr;
|
||||
rimeaddr_t macLongAddr;
|
||||
#define tmp_addr macLongAddr
|
||||
#else //legacy radio driver using Atmel/Cisco 802.15.4'ish MAC
|
||||
#include <stdbool.h>
|
||||
#include "mac.h"
|
||||
|
@ -194,20 +203,101 @@ SIGNATURE = {
|
|||
FUSES ={.low = 0xde, .high = 0x99, .extended = 0xff,};
|
||||
|
||||
/* Put default MAC address in EEPROM */
|
||||
#if !JACKDAW_CONF_USE_SETTINGS
|
||||
uint8_t mac_address[8] EEMEM = {0x02, 0x12, 0x13, 0xff, 0xfe, 0x14, 0x15, 0x16};
|
||||
//uint8_t EEMEM mac_address[8]; //The raven webserver uses this EEMEM allocation
|
||||
//uint8_t EEMEM server_name[16];
|
||||
//uint8_t EEMEM domain_name[30];
|
||||
#endif
|
||||
|
||||
static uint8_t get_channel_from_eeprom() {
|
||||
#if JACKDAW_CONF_USE_SETTINGS
|
||||
uint8_t chan = settings_get_uint8(SETTINGS_KEY_CHANNEL, 0);
|
||||
if(!chan)
|
||||
chan = RF_CHANNEL;
|
||||
return chan;
|
||||
#else
|
||||
uint8_t eeprom_channel;
|
||||
uint8_t eeprom_check;
|
||||
|
||||
eeprom_channel = eeprom_read_byte((uint8_t *)9);
|
||||
eeprom_check = eeprom_read_byte((uint8_t *)10);
|
||||
|
||||
if(eeprom_channel==~eeprom_check)
|
||||
return eeprom_channel;
|
||||
return 26;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static bool
|
||||
get_eui64_from_eeprom(uint8_t macptr[8]) {
|
||||
#if JACKDAW_CONF_USE_SETTINGS
|
||||
size_t size = 8;
|
||||
|
||||
if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char*)macptr, &size)==SETTINGS_STATUS_OK)
|
||||
return true;
|
||||
|
||||
// Fallback to reading the traditional mac address
|
||||
eeprom_read_block ((void *)macptr, 0, 8);
|
||||
#else
|
||||
eeprom_read_block ((void *)macptr, &mac_address, 8);
|
||||
#endif
|
||||
return macptr[0]!=0xFF;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_eui64_to_eeprom(const uint8_t macptr[8]) {
|
||||
#if JACKDAW_CONF_USE_SETTINGS
|
||||
return settings_set(SETTINGS_KEY_EUI64, macptr, 8)==SETTINGS_STATUS_OK;
|
||||
#else
|
||||
eeprom_write_block((void *)macptr, &mac_address, 8);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
generate_new_eui64(uint8_t eui64[8]) {
|
||||
eui64[0] = 0x02;
|
||||
eui64[1] = rng_get_uint8();
|
||||
eui64[2] = rng_get_uint8();
|
||||
eui64[3] = 0xFF;
|
||||
eui64[4] = 0xFE;
|
||||
eui64[5] = rng_get_uint8();
|
||||
eui64[6] = rng_get_uint8();
|
||||
eui64[7] = rng_get_uint8();
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
get_panid_from_eeprom(void) {
|
||||
#if JACKDAW_CONF_USE_SETTINGS
|
||||
uint16_t x = settings_get_uint16(SETTINGS_KEY_PAN_ID, 0);
|
||||
if(!x)
|
||||
x = IEEE802154_PANID;
|
||||
return x;
|
||||
#else
|
||||
// TODO: Writeme!
|
||||
return IEEE802154_PANID;
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
get_panaddr_from_eeprom(void) {
|
||||
#if JACKDAW_CONF_USE_SETTINGS
|
||||
return settings_get_uint16(SETTINGS_KEY_PAN_ADDR, 0);
|
||||
#else
|
||||
// TODO: Writeme!
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/*-----------------------------Low level initialization--------------------*/
|
||||
static void initialize(void) {
|
||||
watchdog_init();
|
||||
watchdog_start();
|
||||
|
||||
/* Initialize hardware */
|
||||
// Currently only used for finger detection for mass storage mode
|
||||
#if USB_CONF_STORAGE
|
||||
// Checks for "finger", jumps to DFU if present.
|
||||
init_lowlevel();
|
||||
#endif
|
||||
|
||||
/* Clock */
|
||||
clock_init();
|
||||
|
@ -221,7 +311,9 @@ static void initialize(void) {
|
|||
printf_P(PSTR("\n\n\n********BOOTING CONTIKI*********\n"));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
Leds_init();
|
||||
|
||||
/* rtimer init needed for low power protocols */
|
||||
rtimer_init();
|
||||
|
||||
|
@ -239,26 +331,52 @@ static void initialize(void) {
|
|||
|
||||
/* Set addresses BEFORE starting tcpip process */
|
||||
|
||||
memset(&addr, 0, sizeof(rimeaddr_t));
|
||||
AVR_ENTER_CRITICAL_REGION();
|
||||
eeprom_read_block ((void *)&addr.u8, &mac_address, 8);
|
||||
AVR_LEAVE_CRITICAL_REGION();
|
||||
//RNDIS needs the mac address in reverse byte order
|
||||
macLongAddr.u8[0]=addr.u8[7];
|
||||
macLongAddr.u8[1]=addr.u8[6];
|
||||
macLongAddr.u8[2]=addr.u8[5];
|
||||
macLongAddr.u8[3]=addr.u8[4];
|
||||
macLongAddr.u8[4]=addr.u8[3];
|
||||
macLongAddr.u8[5]=addr.u8[2];
|
||||
macLongAddr.u8[6]=addr.u8[1];
|
||||
macLongAddr.u8[7]=addr.u8[0];
|
||||
|
||||
memcpy(&uip_lladdr.addr, &addr.u8, 8);
|
||||
rf230_set_pan_addr(IEEE802154_PANID, 0, (uint8_t *)&addr.u8);
|
||||
rf230_set_channel(26);
|
||||
memset(&tmp_addr, 0, sizeof(rimeaddr_t));
|
||||
if(!get_eui64_from_eeprom(tmp_addr.u8)) {
|
||||
#if JACKDAW_CONF_RANDOM_MAC
|
||||
// It doesn't look like we have a valid EUI-64 address
|
||||
// so let's try to make a new one from scratch.
|
||||
Leds_off();
|
||||
Led2_on();
|
||||
generate_new_eui64(tmp_addr.u8);
|
||||
if(!set_eui64_to_eeprom(tmp_addr.u8)) {
|
||||
watchdog_periodic();
|
||||
int i;
|
||||
for(i=0;i<20;i++) {
|
||||
Led1_toggle();
|
||||
_delay_ms(100);
|
||||
}
|
||||
Led1_off();
|
||||
}
|
||||
Led2_off();
|
||||
#else
|
||||
tmp_addr.u8[0]=0x02;
|
||||
tmp_addr.u8[1]=0x12;
|
||||
tmp_addr.u8[2]=0x13;
|
||||
tmp_addr.u8[3]=0xff;
|
||||
tmp_addr.u8[4]=0xfe;
|
||||
tmp_addr.u8[5]=0x14;
|
||||
tmp_addr.u8[6]=0x15;
|
||||
tmp_addr.u8[7]=0x16;
|
||||
#endif /* JACKDAW_CONF_RANDOM_MAC */
|
||||
}
|
||||
|
||||
|
||||
rimeaddr_set_node_addr(&addr);
|
||||
// set_rime_addr();
|
||||
//Fix MAC address
|
||||
init_net();
|
||||
|
||||
memcpy(&uip_lladdr.addr, &tmp_addr.u8, 8);
|
||||
rf230_set_pan_addr(
|
||||
get_panid_from_eeprom(),
|
||||
get_panaddr_from_eeprom(),
|
||||
(uint8_t *)&tmp_addr.u8
|
||||
);
|
||||
|
||||
#if JACKDAW_CONF_USE_SETTINGS
|
||||
rf230_set_txpower(settings_get_uint8(SETTINGS_KEY_TXPOWER,0));
|
||||
#endif
|
||||
|
||||
rimeaddr_set_node_addr(&tmp_addr);
|
||||
|
||||
/* Initialize stack protocols */
|
||||
queuebuf_init();
|
||||
|
@ -266,8 +384,10 @@ static void initialize(void) {
|
|||
NETSTACK_MAC.init();
|
||||
NETSTACK_NETWORK.init();
|
||||
|
||||
rf230_set_channel(get_channel_from_eeprom());
|
||||
|
||||
#if ANNOUNCE && USB_CONF_RS232
|
||||
printf_P(PSTR("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n"),addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]);
|
||||
printf_P(PSTR("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n\r"),tmp_addr.u8[0],tmp_addr.u8[1],tmp_addr.u8[2],tmp_addr.u8[3],tmp_addr.u8[4],tmp_addr.u8[5],tmp_addr.u8[6],tmp_addr.u8[7]);
|
||||
printf_P(PSTR("%s %s, channel %u"),NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
|
||||
if (NETSTACK_RDC.channel_check_interval) {
|
||||
unsigned short tmp;
|
||||
|
@ -305,13 +425,10 @@ static void initialize(void) {
|
|||
#if USB_CONF_CDC
|
||||
process_start(&cdc_process, NULL);
|
||||
#endif
|
||||
process_start(&rndis_process, NULL);
|
||||
process_start(&usb_eth_process, NULL);
|
||||
#if USB_CONF_STORAGE
|
||||
process_start(&storage_process, NULL);
|
||||
#endif
|
||||
|
||||
//Fix MAC address
|
||||
init_net();
|
||||
|
||||
#if ANNOUNCE
|
||||
#if USB_CONF_CDC
|
||||
|
@ -320,7 +437,7 @@ static void initialize(void) {
|
|||
/* Allow USB CDC to keep up with printfs */
|
||||
for (i=0;i<8000;i++) process_run();
|
||||
#if RF230BB
|
||||
printf_P(PSTR("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n\r"),addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]);
|
||||
printf_P(PSTR("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n\r"),tmp_addr.u8[0],tmp_addr.u8[1],tmp_addr.u8[2],tmp_addr.u8[3],tmp_addr.u8[4],tmp_addr.u8[5],tmp_addr.u8[6],tmp_addr.u8[7]);
|
||||
for (i=0;i<8000;i++) process_run();
|
||||
printf_P(PSTR("%s %s, channel %u"),NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
|
||||
if (NETSTACK_RDC.channel_check_interval) {
|
||||
|
@ -359,6 +476,8 @@ main(void)
|
|||
while(1) {
|
||||
process_run();
|
||||
|
||||
watchdog_periodic();
|
||||
|
||||
#if TESTRTIMER
|
||||
if (rtimerflag) { //8 seconds is maximum interval, my jackdaw 4% slow
|
||||
rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
|
||||
|
|
|
@ -45,8 +45,6 @@
|
|||
|
||||
// LED's for Raven USB
|
||||
#define Leds_init() (DDRD |= 0xA0, DDRE |= 0xC0)
|
||||
#define Leds_on() (PORTD |= 0x80, PORTD &= ~0x40, PORTE &= ~0xC0)
|
||||
#define Leds_off() (PORTD &= ~0x80, PORTD |= 0x20, PORTE |= 0xC0)
|
||||
#define Led0_on() (PORTD |= 0x80)
|
||||
#define Led1_on() (PORTD &= ~0x20)
|
||||
#define Led2_on() (PORTE &= ~0x80)
|
||||
|
@ -59,6 +57,8 @@
|
|||
#define Led1_toggle() (PIND |= 0x20)
|
||||
#define Led2_toggle() (PINE |= 0x80)
|
||||
#define Led3_toggle() (PINE |= 0x40)
|
||||
#define Leds_on() (Led0_on(),Led1_on(),Led2_on(),Led3_on())
|
||||
#define Leds_off() (Led0_off(),Led1_off(),Led2_off(),Led3_off())
|
||||
|
||||
|
||||
void init_lowlevel(void);
|
||||
|
|
|
@ -1,129 +0,0 @@
|
|||
|
||||
/* Various stub functions and uIP variables other code might need to
|
||||
* compile. Allows you to save needing to compile all of uIP in just
|
||||
* to get a few things */
|
||||
|
||||
|
||||
#include "uip.h"
|
||||
#include <string.h>
|
||||
|
||||
#if CONTIKI_NO_NET
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
uip_buf_t uip_aligned_buf;
|
||||
|
||||
u16_t uip_len;
|
||||
|
||||
struct uip_stats uip_stat;
|
||||
|
||||
uip_lladdr_t uip_lladdr;
|
||||
|
||||
static u8_t (* output)(uip_lladdr_t *);
|
||||
|
||||
u8_t tcpip_output(uip_lladdr_t * lladdr){
|
||||
if(output != NULL) {
|
||||
return output(lladdr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void tcpip_set_outputfunc(u8_t (* f)(uip_lladdr_t *)) {
|
||||
output = f;
|
||||
}
|
||||
|
||||
u16_t htons(u16_t val) { return HTONS(val);}
|
||||
|
||||
|
||||
#if THEOLDWAY
|
||||
/********** UIP_NETIF.c **********/
|
||||
void
|
||||
uip_netif_addr_autoconf_set(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr)
|
||||
#else
|
||||
/********** uip-ds6.c ************/
|
||||
void
|
||||
uip_ds6_set_addr_iid(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr)
|
||||
#endif /* THEOLDWAY */
|
||||
{
|
||||
/* We consider only links with IEEE EUI-64 identifier or
|
||||
IEEE 48-bit MAC addresses */
|
||||
#if (UIP_LLADDR_LEN == 8)
|
||||
memcpy(ipaddr->u8 + 8, lladdr, UIP_LLADDR_LEN);
|
||||
ipaddr->u8[8] ^= 0x02;
|
||||
#elif (UIP_LLADDR_LEN == 6)
|
||||
memcpy(ipaddr->u8 + 8, lladdr, 3);
|
||||
ipaddr->u8[11] = 0xff;
|
||||
ipaddr->u8[12] = 0xfe;
|
||||
memcpy(ipaddr->u8 + 13, lladdr + 3, 3);
|
||||
ipaddr->u8[8] ^= 0x02;
|
||||
#else
|
||||
#error cannot build interface address when UIP_LLADDR_LEN is not 6 or 8
|
||||
/*
|
||||
UIP_LOG("CAN NOT BUIL INTERFACE IDENTIFIER");
|
||||
UIP_LOG("THE STACK IS GOING TO SHUT DOWN");
|
||||
UIP_LOG("THE HOST WILL BE UNREACHABLE");
|
||||
exit(-1);
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
/********** UIP.c ****************/
|
||||
|
||||
static u16_t
|
||||
chksum(u16_t sum, const u8_t *data, u16_t len)
|
||||
{
|
||||
u16_t t;
|
||||
const u8_t *dataptr;
|
||||
const u8_t *last_byte;
|
||||
|
||||
dataptr = data;
|
||||
last_byte = data + len - 1;
|
||||
|
||||
while(dataptr < last_byte) { /* At least two more bytes */
|
||||
t = (dataptr[0] << 8) + dataptr[1];
|
||||
sum += t;
|
||||
if(sum < t) {
|
||||
sum++; /* carry */
|
||||
}
|
||||
dataptr += 2;
|
||||
}
|
||||
|
||||
if(dataptr == last_byte) {
|
||||
t = (dataptr[0] << 8) + 0;
|
||||
sum += t;
|
||||
if(sum < t) {
|
||||
sum++; /* carry */
|
||||
}
|
||||
}
|
||||
|
||||
/* Return sum in host byte order. */
|
||||
return sum;
|
||||
}
|
||||
|
||||
static u16_t
|
||||
upper_layer_chksum(u8_t proto)
|
||||
{
|
||||
u16_t upper_layer_len;
|
||||
u16_t sum;
|
||||
|
||||
upper_layer_len = (((u16_t)(UIP_IP_BUF->len[0]) << 8) + UIP_IP_BUF->len[1]) ;
|
||||
|
||||
/* First sum pseudoheader. */
|
||||
/* IP protocol and length fields. This addition cannot carry. */
|
||||
sum = upper_layer_len + proto;
|
||||
/* Sum IP source and destination addresses. */
|
||||
sum = chksum(sum, (u8_t *)&UIP_IP_BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t));
|
||||
|
||||
/* Sum TCP header and data. */
|
||||
sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],
|
||||
upper_layer_len);
|
||||
|
||||
return (sum == 0) ? 0xffff : htons(sum);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
u16_t
|
||||
uip_icmp6chksum(void)
|
||||
{
|
||||
return upper_layer_chksum(UIP_PROTO_ICMP6);
|
||||
}
|
||||
#endif /* CONTIKI_NO_NET */
|
218
platform/avr-ravenusb/rng.c
Normal file
218
platform/avr-ravenusb/rng.c
Normal file
|
@ -0,0 +1,218 @@
|
|||
// ADC-based strong RNG
|
||||
// Very slow, but who cares---if you need fast random numbers, use a PRNG.
|
||||
|
||||
#include "rng.h"
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include "contiki.h"
|
||||
|
||||
#ifndef RNG_CONF_USE_ADC
|
||||
#define RNG_CONF_USE_ADC (!RNG_CONF_USE_RADIO_CLOCK && defined(ADMUX) && defined(ADCSRA) && defined(ADCSRB) && defined(ADSC) && defined(ADEN))
|
||||
#endif
|
||||
|
||||
#ifndef RNG_CONF_USE_RADIO_CLOCK
|
||||
#define RNG_CONF_USE_RADIO_CLOCK ((!RNG_CONF_USE_ADC) && RF230BB)
|
||||
#endif
|
||||
|
||||
|
||||
#define TEMPORAL_AGITATION() do { static uint8_t agitator; agitator*=97; agitator+=101; _delay_us(agitator>>1); } while (0);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
#if RNG_CONF_USE_ADC
|
||||
/* The hope is that there is enough noise in the LSB when pointing the
|
||||
** ADC at the internal band-gap input and using the internal 2.56v
|
||||
** AREF.
|
||||
**
|
||||
** TODO: Run some randomness tests on the output of this RNG!
|
||||
*/
|
||||
|
||||
#define BITS_TO_SHIFT 9
|
||||
|
||||
#define ADC_CHAN_ADC1 ((0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(1<<MUX0))
|
||||
#define ADC_CHAN_BAND_GAP ((1<<MUX4)|(1<<MUX3)|(1<<MUX2)|(1<<MUX1)|(0<<MUX0))
|
||||
#define ADC_REF_AREF ((0<<REFS1)|(0<<REFS0))
|
||||
#define ADC_REF_AVCC ((0<<REFS1)|(1<<REFS0))
|
||||
#define ADC_REF_INT ((1<<REFS1)|(1<<REFS0))
|
||||
#define ADC_TRIG_FREE_RUN ((0<<ADTS2)|(0<<ADTS1)|(0<<ADTS0))
|
||||
#define ADC_PS_128 ((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0))
|
||||
#define ADC_PS_2 ((0<<ADPS2)|(0<<ADPS1)|(1<<ADPS0))
|
||||
|
||||
#ifndef CONTIKI_CONF_RNG_ADC_CHANNEL
|
||||
#define CONTIKI_CONF_RNG_ADC_CHANNEL ADC_CHAN_BAND_GAP
|
||||
#endif
|
||||
|
||||
#ifndef CONTIKI_CONF_RNG_ADC_REF
|
||||
#define CONTIKI_CONF_RNG_ADC_REF ADC_REF_INT
|
||||
#endif
|
||||
|
||||
static uint8_t
|
||||
extract_random_bit_() {
|
||||
uint8_t ret = 0;
|
||||
|
||||
// Store the state so that we can restore it when we are done.
|
||||
uint8_t sreg = SREG;
|
||||
uint8_t adcsra = ADCSRA;
|
||||
uint8_t admux = ADMUX;
|
||||
uint8_t adcsrb = ADCSRB;
|
||||
#ifdef PRR
|
||||
uint8_t prr = PRR;
|
||||
#endif
|
||||
|
||||
// Disable interrupts
|
||||
cli();
|
||||
|
||||
#ifdef PRR
|
||||
// Enable ADC module
|
||||
PRR &= ~(1 << PRADC);
|
||||
#endif
|
||||
|
||||
// Wait for any ADC conversion which
|
||||
// might currently be happening to finish.
|
||||
while(ADCSRA & (1<<ADSC));
|
||||
|
||||
// Configure the ADC module
|
||||
ADCSRA = (1<<ADEN)|ADC_PS_128;
|
||||
ADMUX = (uint8_t)CONTIKI_CONF_RNG_ADC_REF|(uint8_t)CONTIKI_CONF_RNG_ADC_CHANNEL;
|
||||
ADCSRB = ADC_TRIG_FREE_RUN;
|
||||
|
||||
// This loop is where we try to come up with our
|
||||
// random bit. Unfortunately, the time it takes
|
||||
// for this to happen is non-deterministic, but
|
||||
// the result should be non-biased random bit.
|
||||
do {
|
||||
// Start conversion for first bit
|
||||
ADCSRA |= (1<<ADSC);
|
||||
// Wait for conversion to complete.
|
||||
while(ADCSRA & (1<<ADSC));
|
||||
ret = (ADC&1);
|
||||
ret <<= 1;
|
||||
|
||||
// Start conversion for second bit
|
||||
ADCSRA |= (1<<ADSC);
|
||||
// Wait for conversion to complete.
|
||||
while(ADCSRA & (1<<ADSC));
|
||||
ret |= (ADC&1);
|
||||
|
||||
// Toggling the reference voltage
|
||||
// seems to help introduce noise.
|
||||
ADMUX^=(1<<REFS1);
|
||||
|
||||
// We only want to exit the loop if the first
|
||||
// and second sampled bits are different.
|
||||
// This is preliminary conditioning.
|
||||
} while((ret==0)||(ret==3));
|
||||
|
||||
// Toss out the other bit, we only care about one of them.
|
||||
ret &= 1;
|
||||
|
||||
ADCSRA=0;
|
||||
|
||||
// Restore the state
|
||||
ADCSRB = adcsrb;
|
||||
ADMUX = admux;
|
||||
ADCSRA = adcsra;
|
||||
#ifdef PRR
|
||||
PRR = prr;
|
||||
#endif
|
||||
SREG = sreg;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
#elif RNG_CONF_USE_RADIO_CLOCK
|
||||
/* Here we are hoping to find some noise in the clock skew
|
||||
** of two different oscilating crystals. On the RZUSBstick,
|
||||
** there are two such crystals: An 8MHz crystal for the
|
||||
** microcontroller, and a 16MHz crystal and for the radio.
|
||||
** The MCLK pin of the RF230 chip is conveniently connected
|
||||
** to pin 6 of port D. First we need to have the radio
|
||||
** output the 16MHz signal (it defaults to 1MHz), and then
|
||||
** we can try to find some noise by sampling pin 6 of port D.
|
||||
**
|
||||
** The suitability of this method as a real random number
|
||||
** generator has yet to be determined. It is entirely possible
|
||||
** that the perceived randomness of the output is due to
|
||||
** the temporal agitator mechanism that I have employed.
|
||||
** Use with caution!
|
||||
**
|
||||
** TODO: Run some randomness tests on the output of this RNG!
|
||||
*/
|
||||
|
||||
#define BITS_TO_SHIFT 8
|
||||
|
||||
#include "radio/rf230bb/hal.h"
|
||||
#include "radio/rf230bb/at86rf230_registermap.h"
|
||||
|
||||
#ifndef TRX_CTRL_0
|
||||
#define TRX_CTRL_0 0x03
|
||||
#endif
|
||||
|
||||
static uint8_t
|
||||
extract_random_bit_() {
|
||||
uint8_t ret;
|
||||
uint8_t trx_ctrl_0 = hal_register_read(TRX_CTRL_0);
|
||||
|
||||
// Set radio clock output to 8MHz
|
||||
hal_register_write(TRX_CTRL_0,0x8|5);
|
||||
|
||||
do {
|
||||
TEMPORAL_AGITATION(); // WARNING: This step may hide lack of entropy!
|
||||
|
||||
ret = !!(PIND&(1<<6));
|
||||
ret <<= 1;
|
||||
ret |= !!(PIND&(1<<6));
|
||||
} while((ret==0)||(ret==3));
|
||||
|
||||
// Toss out the other bit, we only care about one of them.
|
||||
ret &= 1;
|
||||
|
||||
// Restore the clkm state
|
||||
hal_register_write(TRX_CTRL_0,trx_ctrl_0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
static uint8_t
|
||||
extract_random_bit() {
|
||||
uint8_t ret;
|
||||
|
||||
// These next two lines attempt to sync ourselves to
|
||||
// any pattern that might happen to be present in the
|
||||
// raw random source stream. After this, we use the
|
||||
// bias removal mechanism below to filter out the first
|
||||
// sign of noise.
|
||||
while(extract_random_bit_()==1);
|
||||
while(extract_random_bit_()==0);
|
||||
|
||||
do {
|
||||
ret = extract_random_bit_();
|
||||
ret <<= 1;
|
||||
ret |= extract_random_bit_();
|
||||
} while((ret==0)||(ret==3));
|
||||
|
||||
// Toss out the other bit, we only care about one of them.
|
||||
ret &= 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
rng_get_uint8() {
|
||||
uint8_t ret = 0, i;
|
||||
for(i=0;i<BITS_TO_SHIFT;i++) {
|
||||
// Leftshift.
|
||||
ret <<= 1;
|
||||
|
||||
// Add a random bit.
|
||||
ret |= extract_random_bit();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
13
platform/avr-ravenusb/rng.h
Normal file
13
platform/avr-ravenusb/rng.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef __AVR_RNG_H__
|
||||
#define __AVR_RNG_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
//! Returns a byte with eight random bits.
|
||||
/*! This function is very slow, and should only
|
||||
** be used when true random entropy is required.
|
||||
** The time it will take to complete is non-deterministic.
|
||||
*/
|
||||
extern uint8_t rng_get_uint8();
|
||||
|
||||
#endif
|
|
@ -53,12 +53,14 @@
|
|||
|
||||
//TODO: Should be able to always use this SIMPLE mode, hence can remove the 'complex' mode permanently
|
||||
//TODO: RF230BB !SIMPLE works on XP, Ubuntu. SIMPLE works on Vista, W7. Find out why!
|
||||
#if RF230BB
|
||||
#define UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 1
|
||||
#else
|
||||
#define UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 1
|
||||
#endif
|
||||
|
||||
#ifndef UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||
#define UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS 0
|
||||
#endif // ifndef UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||
|
||||
#ifndef UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR
|
||||
#define UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR 1
|
||||
#endif // ifndef UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR
|
||||
|
||||
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||
/**
|
||||
|
@ -255,12 +257,10 @@
|
|||
#define MSB(u16) (((uint8_t *)&(u16))[1]) //!< Most significant byte of \a u16.
|
||||
#endif
|
||||
|
||||
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||
#define rndis_ethernet_addr local_ethernet_addr
|
||||
static uint64_t local_ethernet_addr = 0x3A3B3C3D3E3FULL;
|
||||
#else
|
||||
extern uint64_t rndis_ethernet_addr;
|
||||
#endif
|
||||
static const uint64_t simple_trans_ethernet_addr = 0x3E3D3C3B3AF2ULL;
|
||||
extern uint64_t usb_ethernet_addr;
|
||||
|
||||
extern uint64_t macLongAddr;
|
||||
|
||||
#if !RF230BB
|
||||
extern void (*pinput)(const struct mac_driver *r);
|
||||
|
@ -272,7 +272,6 @@ usbstick_mode_t usbstick_mode;
|
|||
uint8_t mac_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan);
|
||||
uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan);
|
||||
uint8_t mac_createDefaultEthernetAddr(uint8_t * ethernet);
|
||||
uint8_t memcmp_reverse(uint8_t * a, uint8_t * b, uint8_t num);
|
||||
void mac_ethhijack_nondata(const struct mac_driver *r);
|
||||
void mac_ethhijack(const struct mac_driver *r);
|
||||
|
||||
|
@ -294,18 +293,6 @@ uint8_t prefixBuffer[PREFIX_BUFFER_SIZE][3];
|
|||
/* 6lowpan max size + ethernet header size + 1 */
|
||||
uint8_t raw_buf[127+ UIP_LLH_LEN +1];
|
||||
|
||||
/* RPL uses some core tcpip routines which includes another tcpip_input */
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
#warning ---------------------------------------------------------------
|
||||
#warning For RPL comment out the tcpip_input routine in core/net/tcpip.c
|
||||
#warning ---------------------------------------------------------------
|
||||
#endif
|
||||
void tcpip_input( void )
|
||||
{
|
||||
// printf("tcpip_input");
|
||||
mac_LowpanToEthernet();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Perform any setup needed
|
||||
*/
|
||||
|
@ -340,26 +327,27 @@ void mac_ethernetToLowpan(uint8_t * ethHeader)
|
|||
uip_lladdr_t destAddr;
|
||||
uip_lladdr_t *destAddrPtr = NULL;
|
||||
|
||||
PRINTF("Packet type: %x\n\r", ((struct uip_eth_hdr *) ethHeader)->type);
|
||||
PRINTF("Packet type: 0x%04x\n\r", ntohs(((struct uip_eth_hdr *) ethHeader)->type));
|
||||
|
||||
//RUM doesn't support sending data
|
||||
#if UIP_CONF_USE_RUM
|
||||
return;
|
||||
#endif
|
||||
|
||||
//If not IPv6 we don't do anything
|
||||
if (((struct uip_eth_hdr *) ethHeader)->type != HTONS(UIP_ETHTYPE_IPV6)) {
|
||||
PRINTF("eth2low: Packet is not IPv6, dropping\n\r");
|
||||
// printf("!ipv6");
|
||||
#if !RF230BB
|
||||
rndis_stat.txbad++;
|
||||
#endif
|
||||
// In sniffer mode we don't ever send anything
|
||||
if (usbstick_mode.sendToRf == 0) {
|
||||
uip_len = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// In sniffer mode we don't ever send anything
|
||||
if (usbstick_mode.sendToRf == 0) {
|
||||
|
||||
//If not IPv6 we don't do anything
|
||||
if (((struct uip_eth_hdr *) ethHeader)->type != HTONS(UIP_ETHTYPE_IPV6)) {
|
||||
PRINTF("eth2low: Dropping packet w/type=0x%04x\n",ntohs(((struct uip_eth_hdr *) ethHeader)->type));
|
||||
// printf("!ipv6");
|
||||
#if !RF230BB
|
||||
usb_eth_stat.txbad++;
|
||||
#endif
|
||||
uip_len = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -377,21 +365,16 @@ void mac_ethernetToLowpan(uint8_t * ethHeader)
|
|||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[4] == 0xFF) &&
|
||||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[5] == 0xFF) ) {
|
||||
/* IPv6 does not use broadcast addresses, hence this should not happen */
|
||||
PRINTF("eth2low: Ethernet broadcast address received, should not happen?\n\r");
|
||||
PRINTF("eth2low: Dropping broadcast packet\n\r");
|
||||
#if !RF230BB
|
||||
rndis_stat.txbad++;
|
||||
usb_eth_stat.txbad++;
|
||||
#endif
|
||||
uip_len = 0;
|
||||
return;
|
||||
} else {
|
||||
|
||||
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||
/* Simple Address Translation */
|
||||
#if RF230BB
|
||||
if(memcmp((uint8_t *)&rndis_ethernet_addr, &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), 6) == 0) {
|
||||
#else
|
||||
if(memcmp_reverse((uint8_t *)&rndis_ethernet_addr, &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), 6) == 0) {
|
||||
#endif
|
||||
/* Simple Address Translation */
|
||||
if(memcmp((uint8_t *)&simple_trans_ethernet_addr, &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), 6) == 0) {
|
||||
//Addressed to us: make 802.15.4 address from IPv6 Address
|
||||
destAddr.addr[0] = UIP_IP_BUF->destipaddr.u8[8] ^ 0x02;
|
||||
destAddr.addr[1] = UIP_IP_BUF->destipaddr.u8[9];
|
||||
|
@ -403,20 +386,22 @@ void mac_ethernetToLowpan(uint8_t * ethHeader)
|
|||
destAddr.addr[7] = UIP_IP_BUF->destipaddr.u8[15];
|
||||
|
||||
destAddrPtr = &destAddr;
|
||||
} else {
|
||||
}
|
||||
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||
else {
|
||||
//Not addressed to us
|
||||
uip_len = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
/* Complex Address Translation */
|
||||
#else
|
||||
PRINTF("eth2low: Addressed packet received... ");
|
||||
//Check this returns OK
|
||||
if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) {
|
||||
PRINTF(" translation failed\n\r");
|
||||
#if !RF230BB
|
||||
rndis_stat.txbad++;
|
||||
usb_eth_stat.txbad++;
|
||||
#endif
|
||||
uip_len = 0;
|
||||
return;
|
||||
|
@ -441,13 +426,11 @@ void mac_ethernetToLowpan(uint8_t * ethHeader)
|
|||
#endif
|
||||
}
|
||||
|
||||
if (usbstick_mode.sendToRf){
|
||||
tcpip_output(destAddrPtr);
|
||||
tcpip_output(destAddrPtr);
|
||||
#if !RF230BB
|
||||
rndis_stat.txok++;
|
||||
usb_eth_stat.txok++;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
uip_len = 0;
|
||||
|
||||
}
|
||||
|
@ -488,13 +471,16 @@ void mac_LowpanToEthernet(void)
|
|||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||
}
|
||||
|
||||
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||
mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]));
|
||||
#else
|
||||
#if !UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||
//Source ethernet depends on node
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
if(!mac_createEthernetAddr(
|
||||
(uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)
|
||||
))
|
||||
#endif
|
||||
{
|
||||
mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]));
|
||||
}
|
||||
|
||||
//We only do address translation in network mode!
|
||||
if (usbstick_mode.translate) {
|
||||
|
@ -508,7 +494,7 @@ void mac_LowpanToEthernet(void)
|
|||
|
||||
usb_eth_send(uip_buf, uip_len, 1);
|
||||
#if !RF230BB
|
||||
rndis_stat.rxok++;
|
||||
usb_eth_stat.rxok++;
|
||||
#endif
|
||||
uip_len = 0;
|
||||
}
|
||||
|
@ -653,13 +639,10 @@ int8_t mac_translateIcmpLinkLayer(lltype_t target)
|
|||
// printf("createsicslowpanlongaddr");
|
||||
mac_createSicslowpanLongAddr(llbuf, (uip_lladdr_t *)UIP_ICMP_OPTS(icmp_opt_offset)->data);
|
||||
} else {
|
||||
if (UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS) {
|
||||
//Simple address translation always sets this as default
|
||||
#if !UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||
if(!mac_createEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data, (uip_lladdr_t *)llbuf))
|
||||
#endif
|
||||
mac_createDefaultEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data);
|
||||
} else {
|
||||
//Complex address translation sets this as something special
|
||||
mac_createEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data, (uip_lladdr_t *)llbuf);
|
||||
}
|
||||
}
|
||||
|
||||
//Adjust the length
|
||||
|
@ -715,6 +698,15 @@ int8_t mac_translateIcmpLinkLayer(lltype_t target)
|
|||
*/
|
||||
uint8_t mac_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
|
||||
{
|
||||
#if UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR
|
||||
//Special case - if the address is our address, we just copy over what we know to be
|
||||
//our 802.15.4 address
|
||||
if (memcmp((uint8_t *)&usb_ethernet_addr, ethernet, 6) == 0)
|
||||
{
|
||||
memcpy((uint8_t *)lowpan, &macLongAddr, UIP_LLADDR_LEN);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||
|
||||
|
@ -733,56 +725,36 @@ uint8_t mac_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
|
|||
uint8_t index;
|
||||
|
||||
#if UIP_LLADDR_LEN == 8
|
||||
//Special case - if the address is our address, we just copy over what we know to be
|
||||
//our 802.15.4 address
|
||||
#if RF230BB
|
||||
if (memcmp((uint8_t *)&uip_lladdr.addr[2], ethernet, 6) == 0) {
|
||||
// printf("here1");
|
||||
memcpy((uint8_t *)lowpan, uip_lladdr.addr, 8);
|
||||
#else
|
||||
if (memcmp_reverse((uint8_t *)&rndis_ethernet_addr, ethernet, 6) == 0) {
|
||||
memcpy((uint8_t *)lowpan, &macLongAddr, 8);
|
||||
byte_reverse((uint8_t *)lowpan, 8);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Check if translate bit is set, hence we have to look up the prefix
|
||||
if (ethernet[0] & TRANSLATE_BIT_MASK) {
|
||||
|
||||
if((ethernet[0]&(TRANSLATE_BIT_MASK|MULTICAST_BIT_MASK|LOCAL_BIT_MASK)) == (TRANSLATE_BIT_MASK|LOCAL_BIT_MASK)) {
|
||||
//Get top bits
|
||||
index = ethernet[0] >> 3;
|
||||
|
||||
//Check this is plausible...
|
||||
if (index >= prefixCounter) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Copy over prefix
|
||||
lowpan->addr[0] = prefixBuffer[index][0];
|
||||
lowpan->addr[3] = prefixBuffer[index][1];
|
||||
lowpan->addr[4] = prefixBuffer[index][2];
|
||||
|
||||
//Bit is clear
|
||||
//so we copy all six
|
||||
lowpan->addr[1] = prefixBuffer[index][1];
|
||||
lowpan->addr[2] = prefixBuffer[index][2];
|
||||
lowpan->addr[3] = ethernet[1];
|
||||
lowpan->addr[4] = ethernet[2];
|
||||
|
||||
//Check this is plausible...
|
||||
if (index >= prefixCounter)
|
||||
return 0;
|
||||
} else {
|
||||
// printf("here3");
|
||||
lowpan->addr[0] = ethernet[0];
|
||||
lowpan->addr[1] = ethernet[1];
|
||||
lowpan->addr[2] = ethernet[2];
|
||||
lowpan->addr[3] = 0xff;
|
||||
lowpan->addr[4] = 0xfe;
|
||||
}
|
||||
|
||||
//Copy over reamining five bytes
|
||||
lowpan->addr[1] = ethernet[1];
|
||||
lowpan->addr[2] = ethernet[2];
|
||||
lowpan->addr[5] = ethernet[3];
|
||||
lowpan->addr[6] = ethernet[4];
|
||||
lowpan->addr[7] = ethernet[5];
|
||||
lowpan->addr[5] = ethernet[3];
|
||||
lowpan->addr[6] = ethernet[4];
|
||||
lowpan->addr[7] = ethernet[5];
|
||||
|
||||
#else //UIP_LLADDR != 8
|
||||
// Not sure when we would ever hit this case...
|
||||
uint8_t i;
|
||||
// printf("here4");
|
||||
for(i = 0; i < UIP_LLADDR_LEN; i++) {
|
||||
lowpan->addr[i] = ethernet[i];
|
||||
}
|
||||
|
@ -801,6 +773,14 @@ uint8_t mac_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
|
|||
*/
|
||||
uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
|
||||
{
|
||||
#if UIP_CONF_AUTO_SUBSTITUTE_LOCAL_MAC_ADDR
|
||||
//Special case - if the address is our address, we just copy over what we know to be
|
||||
//our 802.3 address
|
||||
if (memcmp((uint8_t *)&macLongAddr, (uint8_t *)lowpan, UIP_LLADDR_LEN) == 0) {
|
||||
usb_eth_get_mac_address(ethernet);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||
|
||||
|
@ -819,26 +799,11 @@ uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
|
|||
|
||||
#if UIP_LLADDR_LEN == 8
|
||||
|
||||
//Special case - if the address is our address, we just copy over what we know to be
|
||||
//our 802.3 address
|
||||
#if RF230BB
|
||||
if (memcmp(uip_lladdr.addr, (uint8_t *)lowpan, 8) == 0) {
|
||||
memcpy(ethernet, &uip_lladdr.addr[2], 6);
|
||||
#else
|
||||
if (memcmp_reverse((uint8_t *)&macLongAddr, (uint8_t *)lowpan, 8) == 0) {
|
||||
memcpy(ethernet, &rndis_ethernet_addr, 6);
|
||||
byte_reverse(ethernet, 6);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//Check if we need to do anything:
|
||||
if ((lowpan->addr[3] == 0xff) && (lowpan->addr[4] == 0xfe) &&
|
||||
((lowpan->addr[0] & TRANSLATE_BIT_MASK) == 0) &&
|
||||
((lowpan->addr[0] & MULTICAST_BIT_MASK) == 0) &&
|
||||
(lowpan->addr[0] & LOCAL_BIT_MASK)) {
|
||||
//Check if we need to do anything:
|
||||
if ((lowpan->addr[3] == 0xff) && (lowpan->addr[4] == 0xfe) &&
|
||||
((lowpan->addr[0] & TRANSLATE_BIT_MASK) == 0) &&
|
||||
((lowpan->addr[0] & MULTICAST_BIT_MASK) == 0) &&
|
||||
(lowpan->addr[0] & LOCAL_BIT_MASK)) {
|
||||
|
||||
/** Nope: just copy over 6 bytes **/
|
||||
ethernet[0] = lowpan->addr[0];
|
||||
|
@ -854,48 +819,45 @@ uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
|
|||
/** Yes: need to store prefix **/
|
||||
for (i = 0; i < prefixCounter; i++) {
|
||||
//Check the current prefix - if it fails, check next one
|
||||
|
||||
|
||||
|
||||
if ((lowpan->addr[0] == prefixBuffer[i][0]) &&
|
||||
(lowpan->addr[3] == prefixBuffer[i][1]) &&
|
||||
(lowpan->addr[4] == prefixBuffer[i][2])) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ((lowpan->addr[0] == prefixBuffer[i][0]) &&
|
||||
(lowpan->addr[1] == prefixBuffer[i][1]) &&
|
||||
(lowpan->addr[2] == prefixBuffer[i][2])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
index = i;
|
||||
|
||||
//Deal with overflow, iron-fist style
|
||||
if (index >= PREFIX_BUFFER_SIZE) {
|
||||
index = 0;
|
||||
prefixCounter = PREFIX_BUFFER_SIZE;
|
||||
} else {
|
||||
//Are we making a new one?
|
||||
if (index == prefixCounter) {
|
||||
prefixCounter++;
|
||||
}
|
||||
}
|
||||
if (index >= PREFIX_BUFFER_SIZE) {
|
||||
// Overflow. Fall back to simple translation.
|
||||
// TODO: Implement me!
|
||||
ethernet[0] = lowpan->addr[0];
|
||||
ethernet[1] = lowpan->addr[1];
|
||||
ethernet[2] = lowpan->addr[2];
|
||||
ethernet[3] = lowpan->addr[5];
|
||||
ethernet[4] = lowpan->addr[6];
|
||||
ethernet[5] = lowpan->addr[7];
|
||||
return 0;
|
||||
} else {
|
||||
//Are we making a new one?
|
||||
if (index == prefixCounter) {
|
||||
prefixCounter++;
|
||||
prefixBuffer[index][0] = lowpan->addr[0];
|
||||
prefixBuffer[index][1] = lowpan->addr[1];
|
||||
prefixBuffer[index][2] = lowpan->addr[2];
|
||||
}
|
||||
|
||||
//Copy the prefix over, no matter if we have a new or old one
|
||||
prefixBuffer[index][0] = lowpan->addr[0];
|
||||
prefixBuffer[index][1] = lowpan->addr[3];
|
||||
prefixBuffer[index][2] = lowpan->addr[4];
|
||||
|
||||
//Create ethernet MAC address now
|
||||
ethernet[1] = lowpan->addr[1];
|
||||
ethernet[2] = lowpan->addr[2];
|
||||
ethernet[3] = lowpan->addr[5];
|
||||
ethernet[4] = lowpan->addr[6];
|
||||
ethernet[5] = lowpan->addr[7];
|
||||
|
||||
|
||||
ethernet[0] = TRANSLATE_BIT_MASK | LOCAL_BIT_MASK | (index << 3);
|
||||
}
|
||||
//Create ethernet MAC address now
|
||||
ethernet[0] = TRANSLATE_BIT_MASK | LOCAL_BIT_MASK | (index << 3);
|
||||
ethernet[1] = lowpan->addr[3];
|
||||
ethernet[2] = lowpan->addr[4];
|
||||
ethernet[3] = lowpan->addr[5];
|
||||
ethernet[4] = lowpan->addr[6];
|
||||
ethernet[5] = lowpan->addr[7];
|
||||
}
|
||||
}
|
||||
|
||||
#else //UIP_LLADDR_LEN != 8
|
||||
|
||||
// Not sure when we would ever hit this case...
|
||||
//Create ethernet MAC address now
|
||||
for(i = 0; i < UIP_LLADDR_LEN; i++) {
|
||||
ethernet[i] = lowpan->addr[i];
|
||||
|
@ -906,20 +868,15 @@ uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
|
|||
|
||||
return 1;
|
||||
}
|
||||
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||
/**
|
||||
* \brief Create a 802.3 address (default)
|
||||
* \param ethernet Pointer to ethernet address
|
||||
*/
|
||||
uint8_t mac_createDefaultEthernetAddr(uint8_t * ethernet)
|
||||
{
|
||||
memcpy(ethernet, &rndis_ethernet_addr, 6);
|
||||
#if !RF230BB
|
||||
byte_reverse(ethernet, 6);
|
||||
#endif
|
||||
memcpy(ethernet, &simple_trans_ethernet_addr, 6);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* \brief Slide the pointed to memory up a certain amount,
|
||||
* growing/shrinking a buffer
|
||||
|
@ -952,6 +909,104 @@ void slide(uint8_t * data, uint8_t length, int16_t slide)
|
|||
}
|
||||
}
|
||||
|
||||
//#define ETHBUF(x) ((struct uip_eth_hdr *)x)
|
||||
//#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
void
|
||||
mac_log_802_15_4_tx(const uint8_t* buffer, size_t total_len) {
|
||||
if (usbstick_mode.raw != 0) {
|
||||
uint8_t sendlen;
|
||||
|
||||
static uint8_t raw_buf[127+ UIP_LLH_LEN +1];
|
||||
|
||||
/* Get the raw frame */
|
||||
memcpy(&raw_buf[UIP_LLH_LEN], buffer, total_len);
|
||||
sendlen = total_len;
|
||||
|
||||
/* Setup generic ethernet stuff */
|
||||
ETHBUF(raw_buf)->type = htons(0x809A); //UIP_ETHTYPE_802154 0x809A
|
||||
|
||||
/* Check for broadcast message */
|
||||
if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) {
|
||||
ETHBUF(raw_buf)->dest.addr[0] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[1] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[2] = 0x00;
|
||||
ETHBUF(raw_buf)->dest.addr[3] = 0x00;
|
||||
ETHBUF(raw_buf)->dest.addr[4] = 0x80;
|
||||
ETHBUF(raw_buf)->dest.addr[5] = 0x9A;
|
||||
|
||||
/*
|
||||
ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
|
||||
ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
|
||||
ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
|
||||
ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
|
||||
*/
|
||||
} else {
|
||||
/* Otherwise we have a real address */
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||
}
|
||||
|
||||
// mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),(uip_lladdr_t *)&uip_lladdr.addr);
|
||||
mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]));
|
||||
|
||||
sendlen += UIP_LLH_LEN;
|
||||
usb_eth_send(raw_buf, sendlen, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mac_log_802_15_4_rx(const uint8_t* buf, size_t len) {
|
||||
if (usbstick_mode.raw != 0) {
|
||||
uint8_t sendlen;
|
||||
|
||||
/* Get the raw frame */
|
||||
memcpy(&raw_buf[UIP_LLH_LEN], buf, len);
|
||||
sendlen = len;
|
||||
|
||||
/* Setup generic ethernet stuff */
|
||||
ETHBUF(raw_buf)->type = htons(0x809A); //UIP_ETHTYPE_802154 0x809A
|
||||
|
||||
/* Check for broadcast message */
|
||||
if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) {
|
||||
ETHBUF(raw_buf)->dest.addr[0] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[1] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[2] = 0x00;
|
||||
ETHBUF(raw_buf)->dest.addr[3] = 0x00;
|
||||
ETHBUF(raw_buf)->dest.addr[4] = 0x80;
|
||||
ETHBUF(raw_buf)->dest.addr[5] = 0x9A;
|
||||
/*
|
||||
ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
|
||||
ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
|
||||
ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
|
||||
ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
|
||||
*/
|
||||
} else {
|
||||
/* Otherwise we have a real address */
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||
}
|
||||
|
||||
// mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),(uip_lladdr_t *)&uip_lladdr.addr);
|
||||
mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]));
|
||||
|
||||
sendlen += UIP_LLH_LEN;
|
||||
usb_eth_send(raw_buf, sendlen, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
mac_is_send_enabled(void) {
|
||||
return usbstick_mode.sendToRf;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#if !RF230BB
|
||||
/*--------------------------------------------------------------------*/
|
||||
/** \brief Process a received 6lowpan packet. Hijack function.
|
||||
|
@ -997,58 +1052,7 @@ void mac_ethhijack_nondata(const struct mac_driver *r)
|
|||
*/
|
||||
void mac_logTXtoEthernet(frame_create_params_t *p,frame_result_t *frame_result)
|
||||
{
|
||||
uint8_t sendlen;
|
||||
|
||||
/* Make sure we are supposed to do this */
|
||||
if (usbstick_mode.raw == 0) return;
|
||||
|
||||
/* Get the raw frame */
|
||||
memcpy(&raw_buf[UIP_LLH_LEN], frame_result->frame, frame_result->length);
|
||||
sendlen = frame_result->length;
|
||||
|
||||
//Setup generic ethernet stuff
|
||||
ETHBUF(raw_buf)->type = htons(UIP_ETHTYPE_802154);
|
||||
|
||||
uint64_t tempaddr;
|
||||
|
||||
|
||||
//Check for broadcast message
|
||||
//if(rimeaddr_cmp((const rimeaddr_t *)destAddr, &rimeaddr_null)) {
|
||||
if( ( p->fcf.destAddrMode == SHORTADDRMODE) &&
|
||||
( p->dest_addr.addr16 == 0xffff) ) {
|
||||
ETHBUF(raw_buf)->dest.addr[0] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[1] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
|
||||
ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
|
||||
ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
|
||||
ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
|
||||
} else {
|
||||
|
||||
tempaddr = p->dest_addr.addr64;
|
||||
|
||||
byte_reverse((uint8_t *)&tempaddr, 8);
|
||||
|
||||
//Otherwise we have a real address
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]),
|
||||
(uip_lladdr_t *)&tempaddr);
|
||||
|
||||
}
|
||||
|
||||
tempaddr = p->src_addr.addr64;
|
||||
|
||||
byte_reverse((uint8_t *)&tempaddr, 8);
|
||||
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),
|
||||
(uip_lladdr_t *)&tempaddr);
|
||||
|
||||
PRINTF("Low2Eth: Sending 802.15.4 packet to ethernet\n\r");
|
||||
|
||||
sendlen += UIP_LLH_LEN;
|
||||
|
||||
usb_eth_send(raw_buf, sendlen, 0);
|
||||
rndis_stat.rxok++;
|
||||
|
||||
return;
|
||||
mac_log_802_15_4_tx(frame_result->frame, frame_result->length);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1059,67 +1063,11 @@ void mac_logTXtoEthernet(frame_create_params_t *p,frame_result_t *frame_result)
|
|||
* The 6lowpan packet is put in packetbuf by the MAC. This routine passes
|
||||
* it directly to the ethernet layer without decompressing.
|
||||
*/
|
||||
void mac_802154raw(const struct mac_driver *r)
|
||||
{
|
||||
uint8_t sendlen;
|
||||
|
||||
parsed_frame = sicslowmac_get_frame();
|
||||
|
||||
/* Get the raw frame */
|
||||
memcpy(&raw_buf[UIP_LLH_LEN], radio_frame_data(), radio_frame_length());
|
||||
sendlen = radio_frame_length();
|
||||
|
||||
//Setup generic ethernet stuff
|
||||
ETHBUF(raw_buf)->type = htons(UIP_ETHTYPE_802154);
|
||||
|
||||
|
||||
//Check for broadcast message
|
||||
//if(rimeaddr_cmp((const rimeaddr_t *)destAddr, &rimeaddr_null)) {
|
||||
if( ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) &&
|
||||
( parsed_frame->dest_addr->addr16 == 0xffff) ) {
|
||||
ETHBUF(raw_buf)->dest.addr[0] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[1] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
|
||||
ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
|
||||
ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
|
||||
ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
|
||||
} else {
|
||||
|
||||
//Otherwise we have a real address
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||
|
||||
}
|
||||
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
|
||||
PRINTF("Low2Eth: Sending 802.15.4 packet to ethernet\n\r");
|
||||
|
||||
sendlen += UIP_LLH_LEN;
|
||||
|
||||
usb_eth_send(raw_buf, sendlen, 1);
|
||||
rndis_stat.rxok++;
|
||||
|
||||
return;
|
||||
void mac_802154raw(const struct mac_driver *r) {
|
||||
mac_log_802_15_4_tx(radio_frame_data(), radio_frame_length());
|
||||
}
|
||||
|
||||
|
||||
uint8_t memcmp_reverse(uint8_t * a, uint8_t * b, uint8_t num)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
while(num) {
|
||||
num--;
|
||||
if (a[i] != b[num]) return 1;
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !RF230BB */
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
/** @} */
|
||||
|
|
Loading…
Reference in a new issue