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
|
### 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
|
### These directories will be searched for the specified source files
|
||||||
### TARGETLIBS are platform-specific routines in the contiki library path
|
### TARGETLIBS are platform-specific routines in the contiki library path
|
||||||
CONTIKI_CPU_DIRS = . dev
|
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
|
ELFLOADER = elfloader.c elfloader-avr.c symtab-avr.c
|
||||||
TARGETLIBS = random.c leds.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 **/
|
/** 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 NB_ENDPOINTS 7 //! number of endpoints in the application including control endpoint
|
||||||
#define VCP_RX_EP 0x06
|
#define VCP_RX_EP 0x06
|
||||||
#define VCP_TX_EP 0x05
|
#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 ____________________________________________________
|
//_____ I N C L U D E S ____________________________________________________
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include "radio.h"
|
#include "radio.h"
|
||||||
#include "contiki.h"
|
#include "contiki.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -65,12 +66,18 @@ RNDIS Status Information:
|
||||||
#include "usb_descriptors.h"
|
#include "usb_descriptors.h"
|
||||||
#include "usb_specific_request.h"
|
#include "usb_specific_request.h"
|
||||||
#include "rndis/rndis_protocol.h"
|
#include "rndis/rndis_protocol.h"
|
||||||
|
#include "rndis/rndis_task.h"
|
||||||
#include "uip.h"
|
#include "uip.h"
|
||||||
#include "serial/uart_usb_lib.h"
|
#include "serial/uart_usb_lib.h"
|
||||||
#include "sicslow_ethernet.h"
|
#include "sicslow_ethernet.h"
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
|
||||||
//_____ M A C R O S ________________________________________________________
|
//_____ M A C R O S ________________________________________________________
|
||||||
|
|
||||||
//_____ D E F I N I T I O N ________________________________________________
|
//_____ D E F I N I T I O N ________________________________________________
|
||||||
|
@ -80,14 +87,10 @@ RNDIS Status Information:
|
||||||
extern PGM_VOID_P pbuffer;
|
extern PGM_VOID_P pbuffer;
|
||||||
extern U8 data_to_transfer;
|
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
|
* \brief List of supported RNDIS OID's
|
||||||
*/
|
*/
|
||||||
prog_uint32_t OIDSupportedList[OID_LIST_LENGTH] = {
|
prog_uint32_t OIDSupportedList[] = {
|
||||||
/* Required General */
|
/* Required General */
|
||||||
OID_GEN_SUPPORTED_LIST ,
|
OID_GEN_SUPPORTED_LIST ,
|
||||||
OID_GEN_HARDWARE_STATUS ,
|
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
|
/*802.11 OID's not fully implemented yet. Hence do not say we
|
||||||
support them */
|
support them */
|
||||||
#ifdef DONOTEVERDEFINETHISORBADSTUFFHAPPENS
|
#if USB_ETH_EMULATE_WIFI
|
||||||
/* 802.11 OIDs */
|
/* 802.11 OIDs */
|
||||||
OID_802_11_BSSID ,
|
OID_802_11_BSSID ,
|
||||||
OID_802_11_SSID ,
|
OID_802_11_SSID ,
|
||||||
|
@ -156,18 +159,17 @@ prog_uint32_t OIDSupportedList[OID_LIST_LENGTH] = {
|
||||||
OID_PNP_ENABLE_WAKE_UP ,
|
OID_PNP_ENABLE_WAKE_UP ,
|
||||||
OID_PNP_ADD_WAKE_UP_PATTERN ,
|
OID_PNP_ADD_WAKE_UP_PATTERN ,
|
||||||
OID_PNP_REMOVE_WAKE_UP_PATTERN
|
OID_PNP_REMOVE_WAKE_UP_PATTERN
|
||||||
|
};
|
||||||
|
|
||||||
};
|
#define OID_LIST_LENGTH sizeof(OIDSupportedList)/sizeof(*OIDSupportedList)
|
||||||
|
|
||||||
|
|
||||||
rndis_state_t rndis_state;
|
rndis_state_t rndis_state;
|
||||||
|
|
||||||
rndis_stat_t rndis_stat;
|
usb_eth_stat_t usb_eth_stat;
|
||||||
|
|
||||||
uint8_t schedule_interrupt = 0;
|
uint8_t schedule_interrupt = 0;
|
||||||
|
|
||||||
uint64_t rndis_ethernet_addr = 0x203478928323ULL;
|
|
||||||
|
|
||||||
//_____ D E C L A R A T I O N ______________________________________________
|
//_____ 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.
|
* \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;
|
U8 i = 0;
|
||||||
|
|
||||||
|
@ -200,12 +202,6 @@ uint8_t send_encapsulated_command(uint16_t wLength)
|
||||||
if (wLength > ENC_BUF_SIZE)
|
if (wLength > ENC_BUF_SIZE)
|
||||||
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...
|
//Read in all the bytes...
|
||||||
|
|
||||||
uint8_t nb_counter;
|
uint8_t nb_counter;
|
||||||
|
@ -256,9 +252,13 @@ uint8_t send_encapsulated_command(uint16_t wLength)
|
||||||
m->MinorVersion = RNDIS_MAJOR_VERSION;
|
m->MinorVersion = RNDIS_MAJOR_VERSION;
|
||||||
m->Status = RNDIS_STATUS_SUCCESS;
|
m->Status = RNDIS_STATUS_SUCCESS;
|
||||||
m->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
|
m->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
|
||||||
|
#if USB_ETH_EMULATE_WIFI
|
||||||
|
m->Medium = NDIS_MEDIUM_WIRELESS_LAN;
|
||||||
|
#else
|
||||||
m->Medium = RNDIS_MEDIUM_802_3;
|
m->Medium = RNDIS_MEDIUM_802_3;
|
||||||
|
#endif // USB_ETH_EMULATE_WIFI
|
||||||
m->MaxPacketsPerTransfer = 1;
|
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 */
|
RNDIS messages */
|
||||||
m->PacketAlignmentFactor = 3;
|
m->PacketAlignmentFactor = 3;
|
||||||
m->AfListOffset = 0;
|
m->AfListOffset = 0;
|
||||||
|
@ -353,7 +353,9 @@ void rndis_send_interrupt(void)
|
||||||
|
|
||||||
uint32_t oid_packet_filter = 0x0000000;
|
uint32_t oid_packet_filter = 0x0000000;
|
||||||
|
|
||||||
|
#if USB_ETH_EMULATE_WIFI
|
||||||
uint16_t panid = 0xbaad;
|
uint16_t panid = 0xbaad;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Function to handle a RNDIS "QUERY" command in the encapsulated_buffer
|
* \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_SUPPORTED:
|
||||||
case OID_GEN_MEDIA_IN_USE:
|
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;
|
break;
|
||||||
|
|
||||||
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
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;
|
break;
|
||||||
|
|
||||||
case OID_GEN_LINK_SPEED:
|
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;
|
break;
|
||||||
|
|
||||||
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
||||||
|
@ -422,57 +429,35 @@ void rndis_query_process(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
||||||
*INFBUF = (uint32_t) 1300; //127;
|
*INFBUF = (uint32_t) USB_ETH_MTU; //127;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_MEDIA_CONNECT_STATUS:
|
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;
|
break;
|
||||||
|
|
||||||
case OID_GEN_VENDOR_DRIVER_VERSION:
|
case OID_GEN_VENDOR_DRIVER_VERSION:
|
||||||
*INFBUF = 0x00001000;
|
*INFBUF = 0x00001000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_PHYSICAL_MEDIUM:
|
|
||||||
*INFBUF = NDIS_MEDIUM_802_3; /*NDIS_MEDIUM_WIRELESS_LAN;*/
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OID_GEN_CURRENT_LOOKAHEAD:
|
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) *******/
|
/******* 802.3 (Ethernet) *******/
|
||||||
|
|
||||||
/*The address of the NIC encoded in the hardware.*/
|
/*The address of the NIC encoded in the hardware.*/
|
||||||
case OID_802_3_PERMANENT_ADDRESS:
|
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:
|
case OID_802_3_CURRENT_ADDRESS:
|
||||||
|
|
||||||
//Clear unused bytes
|
//Clear unused bytes
|
||||||
*(INFBUF + 1) = 0;
|
*(INFBUF + 1) = 0;
|
||||||
|
|
||||||
//Set address
|
//get address
|
||||||
*((uint8_t *)INFBUF + 0) = *(((uint8_t * ) &rndis_ethernet_addr) + 5);
|
usb_eth_get_mac_address((uint8_t*)INFBUF);
|
||||||
*((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 */
|
/*4+2 = 6 Bytes of eth address */
|
||||||
c->InformationBufferLength += 2;
|
c->InformationBufferLength += 2;
|
||||||
|
@ -495,20 +480,14 @@ void rndis_query_process(void)
|
||||||
|
|
||||||
/* Frames received with alignment error */
|
/* Frames received with alignment error */
|
||||||
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
||||||
*INFBUF = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Frames transmitted with one collision */
|
/* Frames transmitted with one collision */
|
||||||
case OID_802_3_XMIT_ONE_COLLISION:
|
case OID_802_3_XMIT_ONE_COLLISION:
|
||||||
*INFBUF = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Frames transmitted with more than one collision */
|
/* Frames transmitted with more than one collision */
|
||||||
case OID_802_3_XMIT_MORE_COLLISIONS:
|
case OID_802_3_XMIT_MORE_COLLISIONS:
|
||||||
*INFBUF = 0;
|
*INFBUF = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if USB_ETH_EMULATE_WIFI
|
||||||
/*** 802.11 OIDs ***/
|
/*** 802.11 OIDs ***/
|
||||||
case OID_802_11_BSSID:
|
case OID_802_11_BSSID:
|
||||||
*INFBUF = (uint32_t)panid;
|
*INFBUF = (uint32_t)panid;
|
||||||
|
@ -543,27 +522,28 @@ void rndis_query_process(void)
|
||||||
case OID_802_11_WEP_STATUS:
|
case OID_802_11_WEP_STATUS:
|
||||||
case OID_802_11_AUTHENTICATION_MODE:
|
case OID_802_11_AUTHENTICATION_MODE:
|
||||||
break;
|
break;
|
||||||
|
#endif //USB_ETH_EMULATE_WIFI
|
||||||
|
|
||||||
/*** Statistical ***/
|
/*** Statistical ***/
|
||||||
|
|
||||||
/* Frames transmitted without errors */
|
/* Frames transmitted without errors */
|
||||||
case OID_GEN_XMIT_OK:
|
case OID_GEN_XMIT_OK:
|
||||||
*INFBUF = rndis_stat.txok;
|
*INFBUF = usb_eth_stat.txok;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Frames received without errors */
|
/* Frames received without errors */
|
||||||
case OID_GEN_RCV_OK:
|
case OID_GEN_RCV_OK:
|
||||||
*INFBUF = rndis_stat.rxok;
|
*INFBUF = usb_eth_stat.rxok;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Frames received with errors */
|
/* Frames received with errors */
|
||||||
case OID_GEN_RCV_ERROR:
|
case OID_GEN_RCV_ERROR:
|
||||||
*INFBUF = rndis_stat.rxbad;
|
*INFBUF = usb_eth_stat.rxbad;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Frames transmitted with errors */
|
/* Frames transmitted with errors */
|
||||||
case OID_GEN_XMIT_ERROR:
|
case OID_GEN_XMIT_ERROR:
|
||||||
*INFBUF = rndis_stat.txbad;
|
*INFBUF = usb_eth_stat.txbad;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Frames dropped due to lack of buffer space */
|
/* 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 CFGBUF ((rndis_config_parameter_t *) INFBUF)
|
||||||
#define PARMNAME ((uint8_t *)CFGBUF + CFGBUF->ParameterNameOffset)
|
#define PARMNAME ((uint8_t *)CFGBUF + CFGBUF->ParameterNameOffset)
|
||||||
#define PARMVALUE ((uint8_t *)CFGBUF + CFGBUF->ParameterValueOffset)
|
#define PARMVALUE ((uint8_t *)CFGBUF + CFGBUF->ParameterValueOffset)
|
||||||
|
#define PARMVALUELENGTH CFGBUF->ParameterValueLength
|
||||||
#define PARM_NAME_LENGTH 25 /* Maximum parameter name length */
|
#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
|
* \brief Function to deal with a RNDIS "SET" command present in the
|
||||||
* encapsulated_buffer
|
* encapsulated_buffer
|
||||||
|
@ -664,13 +656,7 @@ void rndis_set_process(void)
|
||||||
Parameter type: single octet
|
Parameter type: single octet
|
||||||
Parameter values: '0' = disabled, '1' = enabled
|
Parameter values: '0' = disabled, '1' = enabled
|
||||||
*/
|
*/
|
||||||
if (strncmp_P(parmname, PSTR("rawmode"), 7) == 0) {
|
rndis_handle_config_parm(parmname,PARMVALUE,PARMVALUELENGTH);
|
||||||
if (*PARMVALUE == '0') {
|
|
||||||
usbstick_mode.raw = 0;
|
|
||||||
} else {
|
|
||||||
usbstick_mode.raw = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -700,6 +686,7 @@ void rndis_set_process(void)
|
||||||
case OID_802_3_MULTICAST_LIST:
|
case OID_802_3_MULTICAST_LIST:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if USB_ETH_EMULATE_WIFI
|
||||||
/* Mandatory 802.11 OIDs */
|
/* Mandatory 802.11 OIDs */
|
||||||
case OID_802_11_BSSID:
|
case OID_802_11_BSSID:
|
||||||
panid = *INFBUF;
|
panid = *INFBUF;
|
||||||
|
@ -708,6 +695,7 @@ void rndis_set_process(void)
|
||||||
case OID_802_11_SSID:
|
case OID_802_11_SSID:
|
||||||
break;
|
break;
|
||||||
//TODO: rest of 802.11
|
//TODO: rest of 802.11
|
||||||
|
#endif // USB_ETH_EMULATE_WIFI
|
||||||
|
|
||||||
/* Power Managment: fails for now */
|
/* Power Managment: fails for now */
|
||||||
case OID_PNP_ADD_WAKE_UP_PATTERN:
|
case OID_PNP_ADD_WAKE_UP_PATTERN:
|
||||||
|
@ -743,7 +731,7 @@ void rndis_set_process(void)
|
||||||
* the "SEND ENCAPSULATED COMMAND" message, which will trigger
|
* the "SEND ENCAPSULATED COMMAND" message, which will trigger
|
||||||
* and interrupt on the host so it knows data is ready.
|
* 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;
|
U8 nb_byte, zlp, i;
|
||||||
|
|
||||||
|
@ -828,6 +816,261 @@ uint8_t rndis_send_status(rndis_Status_t stat)
|
||||||
return 0;
|
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 ****************/
|
/****************** Radio Interface ****************/
|
||||||
|
|
||||||
|
@ -837,15 +1080,11 @@ uint8_t rndis_send_status(rndis_Status_t stat)
|
||||||
*/
|
*/
|
||||||
void rndis_packetFilter(uint32_t newfilter)
|
void rndis_packetFilter(uint32_t newfilter)
|
||||||
{
|
{
|
||||||
#if !RF230BB
|
|
||||||
if (newfilter & NDIS_PACKET_TYPE_PROMISCUOUS) {
|
if (newfilter & NDIS_PACKET_TYPE_PROMISCUOUS) {
|
||||||
rxMode = RX_ON;
|
USB_ETH_HOOK_SET_PROMISCIOUS_MODE(true);
|
||||||
radio_set_trx_state(RX_ON);
|
|
||||||
} else {
|
} else {
|
||||||
rxMode = RX_AACK_ON;
|
USB_ETH_HOOK_SET_PROMISCIOUS_MODE(false);
|
||||||
radio_set_trx_state(RX_AACK_ON);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -303,22 +303,23 @@ typedef struct{
|
||||||
uint32_t rxok;
|
uint32_t rxok;
|
||||||
uint32_t txbad;
|
uint32_t txbad;
|
||||||
uint32_t rxbad;
|
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 rndis_state_t rndis_state;
|
||||||
|
|
||||||
extern uint8_t schedule_interrupt;
|
extern uint8_t schedule_interrupt;
|
||||||
|
|
||||||
extern uint64_t rndis_ethernet_addr;
|
uint8_t rndis_send_encapsulated_command(uint16_t wLength);
|
||||||
|
uint8_t rndis_get_encapsulated_command(void);
|
||||||
uint8_t send_encapsulated_command(uint16_t wLength);
|
|
||||||
uint8_t get_encapsulated_command(void);
|
|
||||||
void rndis_send_interrupt(void);
|
void rndis_send_interrupt(void);
|
||||||
void rndis_query_process(void);
|
void rndis_query_process(void);
|
||||||
void rndis_set_process(void);
|
void rndis_set_process(void);
|
||||||
uint8_t rndis_send_status(rndis_Status_t stat);
|
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
|
#endif //_RNDIS_H
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,9 @@
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include <util/delay.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 BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||||
#define PRINTF printf
|
#define PRINTF printf
|
||||||
#define PRINTF_P printf_P
|
#define PRINTF_P printf_P
|
||||||
|
@ -66,12 +69,6 @@
|
||||||
//_____ M A C R O S ________________________________________________________
|
//_____ 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_DETACH 900
|
||||||
#define RNDIS_TIMEOUT_ATTACH 1000
|
#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 ____________________________________________
|
//_____ 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
|
//! Timers for LEDs
|
||||||
uint8_t led1_timer, led2_timer;
|
uint8_t led1_timer, led2_timer;
|
||||||
|
|
||||||
//! Temp data buffer when adding RNDIS headers
|
uint8_t usb_eth_is_active = 1;
|
||||||
uint8_t data_buffer[64];
|
|
||||||
|
|
||||||
//! Usb is busy with RNDIS
|
|
||||||
char usb_busy = 0;
|
|
||||||
|
|
||||||
|
|
||||||
static struct etimer et;
|
uint8_t usb_eth_packet_is_available() {
|
||||||
static struct timer flood_timer;
|
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
|
* \brief RNDIS Process
|
||||||
*
|
*
|
||||||
* This is the link between USB and the "good stuff". In this routine data
|
* 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();
|
PROCESS_BEGIN();
|
||||||
uint8_t bytecounter, headercounter;
|
|
||||||
uint16_t i, dataoffset;
|
|
||||||
clock_time_t timediff;
|
|
||||||
clock_time_t thetime;
|
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
|
rxtx_led_update();
|
||||||
|
|
||||||
// turn off LED's if necessary
|
#if USB_ETH_CONF_MASS_STORAGE_FALLBACK
|
||||||
if (led1_timer) led1_timer--;
|
usb_eth_setup_timeout_fallback_check();
|
||||||
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
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
switch(usb_configuration_nb) {
|
||||||
if(rndis_state == rndis_data_initialized) //Enumeration processs OK ?
|
case USB_CONFIG_RNDIS_DEBUG:
|
||||||
{
|
case USB_CONFIG_RNDIS:
|
||||||
if (doInit) {
|
if(Is_device_enumerated()) {
|
||||||
//start flood timer
|
if(rndis_process()) {
|
||||||
timer_set(&flood_timer, CLOCK_SECOND / 5);
|
etimer_set(&et, CLOCK_SECOND/80);
|
||||||
|
} else {
|
||||||
mac_ethernetSetup();
|
Led0_toggle();
|
||||||
doInit = 0;
|
etimer_set(&et, CLOCK_SECOND/8);
|
||||||
}
|
|
||||||
|
|
||||||
//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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
//Ack final data packet
|
case USB_CONFIG_EEM:
|
||||||
Usb_ack_receive_out();
|
if(Is_device_enumerated())
|
||||||
|
cdc_eem_process();
|
||||||
//Packet has CRC, nobody wants that garbage
|
etimer_set(&et, CLOCK_SECOND/80);
|
||||||
datalength -= 4;
|
break;
|
||||||
|
case USB_CONFIG_ECM:
|
||||||
//Send data over RF or to local stack
|
case USB_CONFIG_ECM_DEBUG:
|
||||||
uip_len = datalength; //uip_len includes LLH_LEN
|
if(Is_device_enumerated()) {
|
||||||
mac_ethernetToLowpan(uip_buf);
|
if(cdc_ecm_process()) {
|
||||||
|
etimer_set(&et, CLOCK_SECOND/80);
|
||||||
} //if (datalength)
|
} else {
|
||||||
} //if(Is_usb_receive_out() && (uip_len == 0))
|
Led0_toggle();
|
||||||
} // if (Is_device_enumerated())
|
etimer_set(&et, CLOCK_SECOND/8);
|
||||||
|
}
|
||||||
if ((usb_mode == rndis_only) || (usb_mode == rndis_debug) || (usb_mode == eem)) {
|
}
|
||||||
etimer_set(&et, CLOCK_SECOND/80);
|
break;
|
||||||
} else {
|
default:
|
||||||
etimer_set(&et, CLOCK_SECOND);
|
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)
|
} // while(1)
|
||||||
|
|
||||||
PROCESS_END();
|
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)
|
uint8_t usb_eth_send(uint8_t * senddata, uint16_t sendlen, uint8_t led)
|
||||||
{
|
{
|
||||||
if (usb_mode == eem)
|
uint8_t ret = 0;
|
||||||
return eem_send(senddata, sendlen, led);
|
|
||||||
|
if(!usb_eth_is_active) {
|
||||||
|
USB_ETH_HOOK_TX_ERROR("Inactive");
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
if ((usb_mode == rndis_only) || (usb_mode == rndis_debug))
|
//Check device is set up
|
||||||
return rndis_send(senddata, sendlen, led);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void
|
||||||
\brief Send a single ethernet frame using EEM
|
usb_eth_get_mac_address(uint8_t dest[6]) {
|
||||||
*/
|
memcpy(dest,&usb_ethernet_addr,6);
|
||||||
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
|
||||||
\brief Send data over RNDIS interface, data is in uipbuf and length is uiplen
|
usb_eth_set_mac_address(const uint8_t src[6]) {
|
||||||
*/
|
memcpy(&usb_ethernet_addr,src,6);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
@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 "config.h"
|
||||||
|
#include "../conf_usb.h"
|
||||||
|
|
||||||
//_____ M A C R O S ________________________________________________________
|
//_____ 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 ____________________________________________
|
//_____ 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_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 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 "config.h"
|
||||||
#include "usb_drv.h"
|
#include "usb_drv.h"
|
||||||
#include "usb_descriptors.h"
|
#include "usb_descriptors.h"
|
||||||
#include "serial/cdc_task.h"
|
|
||||||
#include "serial/uart_usb_lib.h"
|
#include "serial/uart_usb_lib.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
@ -56,6 +55,26 @@
|
||||||
|
|
||||||
/*_____ M A C R O S ________________________________________________________*/
|
/*_____ 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 ________________________________________________*/
|
/*_____ D E F I N I T I O N ________________________________________________*/
|
||||||
|
|
||||||
Uchar tx_counter;
|
Uchar tx_counter;
|
||||||
|
@ -64,22 +83,65 @@ S_line_coding line_coding;
|
||||||
|
|
||||||
/*_____ D E C L A R A T I O N ______________________________________________*/
|
/*_____ 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)
|
int usb_stdout_putchar(char c, FILE *stream)
|
||||||
{
|
{
|
||||||
// send to USB port
|
// Preserve the currently selected endpoint
|
||||||
// don't send anything if USB can't accept chars
|
uint8_t uenum = UENUM;
|
||||||
Usb_select_endpoint(TX_EP);
|
|
||||||
if (!uart_usb_tx_ready())
|
// send to USB port
|
||||||
return 0;
|
// don't send anything if USB can't accept chars
|
||||||
|
Usb_select_endpoint(VCP_TX_EP);
|
||||||
// turn on LED
|
|
||||||
vcptx_end_led();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE usb_stdout = FDEV_SETUP_STREAM(usb_stdout_putchar,
|
static FILE usb_stdout = FDEV_SETUP_STREAM(usb_stdout_putchar,
|
||||||
NULL,
|
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
|
* @brief This function checks if the USB emission buffer is ready to accept at
|
||||||
* at least 1 byte
|
* at least 1 byte
|
||||||
|
@ -109,6 +185,7 @@ void uart_usb_set_stdout(void)
|
||||||
*/
|
*/
|
||||||
bit uart_usb_tx_ready(void)
|
bit uart_usb_tx_ready(void)
|
||||||
{
|
{
|
||||||
|
Usb_select_endpoint(VCP_TX_EP);
|
||||||
if (!Is_usb_write_enabled())
|
if (!Is_usb_write_enabled())
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -127,16 +204,31 @@ bit uart_usb_tx_ready(void)
|
||||||
*/
|
*/
|
||||||
int uart_usb_putchar(int data_to_send)
|
int uart_usb_putchar(int data_to_send)
|
||||||
{
|
{
|
||||||
Usb_select_endpoint(VCP_TX_EP);
|
// Preserve the currently selected endpoint
|
||||||
|
uint8_t uenum = UENUM;
|
||||||
if(!uart_usb_tx_ready()) return -1;
|
|
||||||
|
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);
|
Usb_write_byte(data_to_send);
|
||||||
tx_counter++;
|
tx_counter++;
|
||||||
if(!Is_usb_write_enabled()) //If Endpoint full -> flush
|
|
||||||
{
|
//If Endpoint full -> flush
|
||||||
uart_usb_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;
|
return data_to_send;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,6 +241,8 @@ bit uart_usb_test_hit(void)
|
||||||
{
|
{
|
||||||
if (!rx_counter)
|
if (!rx_counter)
|
||||||
{
|
{
|
||||||
|
// Preserve the currently selected endpoint
|
||||||
|
uint8_t uenum = UENUM;
|
||||||
Usb_select_endpoint(VCP_RX_EP);
|
Usb_select_endpoint(VCP_RX_EP);
|
||||||
if (Is_usb_receive_out())
|
if (Is_usb_receive_out())
|
||||||
{
|
{
|
||||||
|
@ -158,6 +252,8 @@ bit uart_usb_test_hit(void)
|
||||||
Usb_ack_receive_out();
|
Usb_ack_receive_out();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Restore previously selected endpoint
|
||||||
|
UENUM = uenum;
|
||||||
}
|
}
|
||||||
return (rx_counter!=0);
|
return (rx_counter!=0);
|
||||||
}
|
}
|
||||||
|
@ -174,15 +270,23 @@ char uart_usb_getchar(void)
|
||||||
{
|
{
|
||||||
register Uchar data_rx;
|
register Uchar data_rx;
|
||||||
|
|
||||||
|
// Preserve the currently selected endpoint
|
||||||
|
uint8_t uenum = UENUM;
|
||||||
|
|
||||||
Usb_select_endpoint(VCP_RX_EP);
|
Usb_select_endpoint(VCP_RX_EP);
|
||||||
if (!rx_counter) while (!uart_usb_test_hit());
|
if (!rx_counter) while (!uart_usb_test_hit());
|
||||||
data_rx=Usb_read_byte();
|
data_rx=Usb_read_byte();
|
||||||
rx_counter--;
|
rx_counter--;
|
||||||
if (!rx_counter) Usb_ack_receive_out();
|
if (!rx_counter) Usb_ack_receive_out();
|
||||||
|
|
||||||
|
#if USB_CDC_ACM_CONF_LOCAL_ECHO
|
||||||
//Local echo
|
//Local echo
|
||||||
uart_usb_putchar(data_rx);
|
uart_usb_putchar(data_rx);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Restore previously selected endpoint
|
||||||
|
UENUM = uenum;
|
||||||
|
|
||||||
return data_rx;
|
return data_rx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,9 +297,16 @@ char uart_usb_getchar(void)
|
||||||
*/
|
*/
|
||||||
void uart_usb_flush (void)
|
void uart_usb_flush (void)
|
||||||
{
|
{
|
||||||
Usb_select_endpoint(VCP_TX_EP);
|
// Preserve the currently selected endpoint
|
||||||
Usb_send_in();
|
uint8_t uenum = UENUM;
|
||||||
|
|
||||||
|
Usb_select_endpoint(VCP_TX_EP);
|
||||||
|
Usb_send_in();
|
||||||
tx_counter = 0;
|
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);
|
bit uart_usb_test_hit(void);
|
||||||
char uart_usb_getchar(void);
|
char uart_usb_getchar(void);
|
||||||
void uart_usb_set_stdout(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_drv.h"
|
||||||
#include "usb_descriptors.h"
|
#include "usb_descriptors.h"
|
||||||
#include "usb_specific_request.h"
|
#include "usb_specific_request.h"
|
||||||
|
#include "rndis/rndis_task.h"
|
||||||
|
|
||||||
|
|
||||||
//_____ M A C R O S ________________________________________________________
|
//_____ 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 ________________________________________________
|
//_____ D E F I N I T I O N ________________________________________________
|
||||||
|
|
||||||
/************* COMPOSITE DEVICE DESCRIPTORS (using IAD) **********/
|
/************* 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
|
// usb_user_device_descriptor
|
||||||
FLASH S_usb_device_descriptor usb_dev_desc_composite =
|
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(VENDOR_ID)
|
||||||
, Usb_write_word_enum_struc(COMPOSITE_PRODUCT_ID)
|
, Usb_write_word_enum_struc(COMPOSITE_PRODUCT_ID)
|
||||||
, Usb_write_word_enum_struc(RELEASE_NUMBER)
|
, Usb_write_word_enum_struc(RELEASE_NUMBER)
|
||||||
, MAN_INDEX
|
, USB_STRING_MAN
|
||||||
, PROD_INDEX
|
, USB_STRING_PRODUCT
|
||||||
, SN_INDEX
|
, USB_STRING_SERIAL
|
||||||
, NB_CONFIGURATION
|
, (sizeof(usb_dev_config_order)/sizeof(*usb_dev_config_order))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// usb_user_configuration_descriptor FS
|
// usb_user_configuration_descriptor FS
|
||||||
FLASH S_usb_user_configuration_descriptor_composite usb_conf_desc_composite = {
|
FLASH S_usb_user_configuration_descriptor_composite usb_conf_desc_composite = {
|
||||||
{ sizeof(S_usb_configuration_descriptor)
|
USB_CONFIG_DESC(
|
||||||
, CONFIGURATION_DESCRIPTOR
|
sizeof(usb_conf_desc_composite),
|
||||||
, Usb_write_word_enum_struc(sizeof(S_usb_user_configuration_descriptor_composite))
|
COMPOSITE_NB_INTERFACE,
|
||||||
//, 0x0043 //TODO: Change to generic codewith sizeof
|
USB_CONFIG_RNDIS_DEBUG,
|
||||||
, COMPOSITE_NB_INTERFACE
|
USB_STRING_CONFIG_COMPOSITE,
|
||||||
, CONF_NB
|
CONF_ATTRIBUTES,
|
||||||
, CONF_INDEX
|
MAX_POWER
|
||||||
, CONF_ATTRIBUTES
|
),
|
||||||
, MAX_POWER
|
|
||||||
},//9
|
|
||||||
|
|
||||||
// --------------------------- IAD ----------------------------
|
USB_IAD(
|
||||||
{ // Interface Association Descriptor
|
0x00, // First interface
|
||||||
sizeof(S_usb_interface_association_descriptor), // bLength
|
0x02, // Interface count
|
||||||
DSC_TYPE_IAD, // bDescriptorType = 11
|
0x02, // Function Class
|
||||||
0x00, // bFirstInterface
|
0x02, // Function Subclass
|
||||||
0x02, // bInterfaceCount
|
0xFF, // Function Protocol
|
||||||
0x02, // bFunctionClass (Communication Class)
|
USB_STRING_INTERFACE_RNDIS
|
||||||
0x02, // bFunctionSubClass (Abstract Control Model)
|
),RNDIS_INTERFACES,
|
||||||
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(
|
||||||
|
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 **************************/
|
/****************** NETWORK-ONLY DEVICE DESCRIPTORS **************************/
|
||||||
|
|
||||||
|
/*
|
||||||
FLASH S_usb_device_descriptor usb_dev_desc_network =
|
FLASH S_usb_device_descriptor usb_dev_desc_network =
|
||||||
{
|
{
|
||||||
sizeof(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(VENDOR_ID)
|
||||||
, Usb_write_word_enum_struc(NETWORK_PRODUCT_ID)
|
, Usb_write_word_enum_struc(NETWORK_PRODUCT_ID)
|
||||||
, Usb_write_word_enum_struc(RELEASE_NUMBER)
|
, Usb_write_word_enum_struc(RELEASE_NUMBER)
|
||||||
, MAN_INDEX
|
, USB_STRING_MAN
|
||||||
, PROD_INDEX
|
, USB_STRING_PRODUCT
|
||||||
, SN_INDEX
|
, USB_STRING_SERIAL
|
||||||
, NB_CONFIGURATION
|
, NB_CONFIGURATION
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
// usb_user_configuration_descriptor FS
|
// usb_user_configuration_descriptor FS
|
||||||
FLASH S_usb_user_configuration_descriptor_network usb_conf_desc_network = {
|
FLASH S_usb_user_configuration_descriptor_network usb_conf_desc_network = {
|
||||||
{ sizeof(S_usb_configuration_descriptor)
|
USB_CONFIG_DESC(
|
||||||
, CONFIGURATION_DESCRIPTOR
|
sizeof(usb_conf_desc_network),
|
||||||
, Usb_write_word_enum_struc(sizeof(S_usb_user_configuration_descriptor_network))
|
NETWORK_NB_INTERFACE,
|
||||||
//, 0x0043 //TODO: Change to generic codewith sizeof
|
CONF_NB, // value
|
||||||
, NETWORK_NB_INTERFACE
|
USB_STRING_CONFIG_RNDIS,
|
||||||
, CONF_NB
|
CONF_ATTRIBUTES,
|
||||||
, CONF_INDEX
|
MAX_POWER
|
||||||
, CONF_ATTRIBUTES
|
),
|
||||||
, MAX_POWER
|
RNDIS_INTERFACES
|
||||||
},//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
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************* 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 **************************/
|
/****************** MASS-STORAGE DEVICE DESCRIPTORS **************************/
|
||||||
|
|
||||||
|
/*
|
||||||
FLASH S_usb_device_descriptor usb_dev_desc_mass =
|
FLASH S_usb_device_descriptor usb_dev_desc_mass =
|
||||||
{
|
{
|
||||||
sizeof(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(VENDOR_ID)
|
||||||
, Usb_write_word_enum_struc(MASS_PRODUCT_ID)
|
, Usb_write_word_enum_struc(MASS_PRODUCT_ID)
|
||||||
, Usb_write_word_enum_struc(RELEASE_NUMBER)
|
, Usb_write_word_enum_struc(RELEASE_NUMBER)
|
||||||
, MAN_INDEX
|
, USB_STRING_MAN
|
||||||
, PROD_INDEX
|
, USB_STRING_PRODUCT
|
||||||
, SN_INDEX
|
, USB_STRING_SERIAL
|
||||||
, NB_CONFIGURATION
|
, NB_CONFIGURATION
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
#if USB_CONF_STORAGE
|
||||||
|
|
||||||
// usb_user_configuration_descriptor FS
|
// usb_user_configuration_descriptor FS
|
||||||
FLASH S_usb_user_configuration_descriptor_mass usb_conf_desc_mass = {
|
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))
|
, Usb_write_word_enum_struc(sizeof(S_usb_user_configuration_descriptor_mass))
|
||||||
, MASS_NB_INTERFACE
|
, MASS_NB_INTERFACE
|
||||||
, CONF_NB
|
, CONF_NB
|
||||||
, CONF_INDEX
|
, USB_STRING_CONFIG_MS
|
||||||
, CONF_ATTRIBUTES
|
, CONF_ATTRIBUTES
|
||||||
, MAX_POWER
|
, MAX_POWER
|
||||||
},//9
|
},//9
|
||||||
|
@ -423,7 +516,7 @@ FLASH S_usb_user_configuration_descriptor_mass usb_conf_desc_mass = {
|
||||||
, MS_INTERFACE_CLASS
|
, MS_INTERFACE_CLASS
|
||||||
, MS_INTERFACE_SUB_CLASS
|
, MS_INTERFACE_SUB_CLASS
|
||||||
, MS_INTERFACE_PROTOCOL
|
, MS_INTERFACE_PROTOCOL
|
||||||
, MS_INTERFACE_INDEX
|
, USB_STRING_INTERFACE_MS
|
||||||
} //9
|
} //9
|
||||||
,
|
,
|
||||||
{ sizeof(S_usb_endpoint_descriptor)
|
{ sizeof(S_usb_endpoint_descriptor)
|
||||||
|
@ -443,96 +536,11 @@ FLASH S_usb_user_configuration_descriptor_mass usb_conf_desc_mass = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/************* EEM-ONLY ***************/
|
#endif
|
||||||
|
|
||||||
// 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
|
|
||||||
};
|
|
||||||
|
|
||||||
/************* COMMON *****************/
|
/************* 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
|
// 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)
|
PGM_VOID_P Usb_get_dev_desc_pointer(void)
|
||||||
{
|
{
|
||||||
|
return &(usb_dev_desc_composite.bLength);
|
||||||
|
/*
|
||||||
if (usb_mode == rndis_only)
|
if (usb_mode == rndis_only)
|
||||||
return &(usb_dev_desc_network.bLength);
|
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_eem.bLength);
|
||||||
|
|
||||||
return &(usb_dev_desc_mass.bLength);
|
return &(usb_dev_desc_mass.bLength);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
U8 Usb_get_dev_desc_length(void)
|
U8 Usb_get_dev_desc_length(void)
|
||||||
{
|
{
|
||||||
|
return sizeof(usb_dev_desc_composite);
|
||||||
|
/*
|
||||||
|
|
||||||
if (usb_mode == rndis_only)
|
if (usb_mode == rndis_only)
|
||||||
return sizeof(usb_dev_desc_network);
|
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_eem);
|
||||||
|
|
||||||
return sizeof(usb_dev_desc_mass);
|
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);
|
switch(pgm_read_byte_near(&usb_dev_config_order[index])) {
|
||||||
|
case USB_CONFIG_ECM:
|
||||||
if (usb_mode == rndis_debug)
|
return &(usb_conf_desc_ecm.cfg.bLength);
|
||||||
return &(usb_conf_desc_composite.cfg.bLength);
|
case USB_CONFIG_ECM_DEBUG:
|
||||||
|
return &(usb_conf_desc_ecm_debug.cfg.bLength);
|
||||||
if (usb_mode == eem)
|
case USB_CONFIG_RNDIS_DEBUG:
|
||||||
return &(usb_conf_desc_eem.cfg.bLength);
|
return &(usb_conf_desc_composite.cfg.bLength);
|
||||||
|
case USB_CONFIG_RNDIS:
|
||||||
return &(usb_conf_desc_mass.cfg.bLength);
|
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)
|
||||||
{
|
{
|
||||||
|
switch(pgm_read_byte_near(&usb_dev_config_order[index])) {
|
||||||
if (usb_mode == rndis_only)
|
case USB_CONFIG_ECM:
|
||||||
return sizeof (usb_conf_desc_network);
|
return sizeof(usb_conf_desc_ecm);
|
||||||
|
case USB_CONFIG_ECM_DEBUG:
|
||||||
if (usb_mode == rndis_debug)
|
return sizeof(usb_conf_desc_ecm_debug);
|
||||||
return sizeof(usb_conf_desc_composite);
|
case USB_CONFIG_RNDIS_DEBUG:
|
||||||
|
return sizeof(usb_conf_desc_composite);
|
||||||
if (usb_mode == eem)
|
case USB_CONFIG_RNDIS:
|
||||||
return sizeof(usb_conf_desc_eem);
|
return sizeof (usb_conf_desc_network);
|
||||||
|
case USB_CONFIG_EEM:
|
||||||
return sizeof(usb_conf_desc_mass);
|
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
|
// USB Device descriptor
|
||||||
#define USB_SPECIFICATION 0x0200
|
#define USB_SPECIFICATION 0x0200
|
||||||
|
|
||||||
#define COMPOSITE_DEVICE_CLASS 0xEF // Misc
|
#define COMPOSITE_DEVICE_CLASS 0x02 // Misc
|
||||||
#define COMPOSITE_DEVICE_SUB_CLASS 0x02 // Common
|
#define COMPOSITE_DEVICE_SUB_CLASS 0x00 // Common
|
||||||
#define COMPOSITE_DEVICE_PROTOCOL 0x01 // IAD
|
#define COMPOSITE_DEVICE_PROTOCOL 0x00 // IAD
|
||||||
|
|
||||||
#define NETWORK_DEVICE_CLASS 0x02 // CDC ACM
|
#define NETWORK_DEVICE_CLASS 0x02 // CDC ACM
|
||||||
#define NETWORK_DEVICE_SUB_CLASS 0x02 //
|
#define NETWORK_DEVICE_SUB_CLASS 0x02 //
|
||||||
|
@ -88,10 +88,49 @@
|
||||||
#define NETWORK_PRODUCT_ID 0x2019 //Product ID for just RNDIS device
|
#define NETWORK_PRODUCT_ID 0x2019 //Product ID for just RNDIS device
|
||||||
#define MASS_PRODUCT_ID 0x202F //Product ID for mass storage
|
#define MASS_PRODUCT_ID 0x202F //Product ID for mass storage
|
||||||
#define RELEASE_NUMBER 0x1000
|
#define RELEASE_NUMBER 0x1000
|
||||||
#define MAN_INDEX 0x01
|
|
||||||
#define PROD_INDEX 0x02
|
enum {
|
||||||
#define SN_INDEX 0x03
|
USB_STRING_NONE = 0,
|
||||||
#define NB_CONFIGURATION 1
|
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 NETWORK_NB_INTERFACE 2
|
||||||
#define COMPOSITE_NB_INTERFACE 4
|
#define COMPOSITE_NB_INTERFACE 4
|
||||||
|
@ -134,14 +173,14 @@
|
||||||
#define ENDPOINT_NB_2 0x80 | TX_EP
|
#define ENDPOINT_NB_2 0x80 | TX_EP
|
||||||
#define EP_ATTRIBUTES_2 0x02 // BULK = 0x02, INTERUPT = 0x03
|
#define EP_ATTRIBUTES_2 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||||
#define EP_SIZE_2 0x40 //64 byte max size
|
#define EP_SIZE_2 0x40 //64 byte max size
|
||||||
#define EP_INTERVAL_2 0x00
|
#define EP_INTERVAL_2 0x01
|
||||||
|
|
||||||
// USB Endpoint 2 descriptor
|
// USB Endpoint 2 descriptor
|
||||||
//Bulk OUT RX endpoint
|
//Bulk OUT RX endpoint
|
||||||
#define ENDPOINT_NB_3 RX_EP
|
#define ENDPOINT_NB_3 RX_EP
|
||||||
#define EP_ATTRIBUTES_3 0x02 // BULK = 0x02, INTERUPT = 0x03
|
#define EP_ATTRIBUTES_3 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||||
#define EP_SIZE_3 0x40 //64 byte max size
|
#define EP_SIZE_3 0x40 //64 byte max size
|
||||||
#define EP_INTERVAL_3 0x00
|
#define EP_INTERVAL_3 0x01
|
||||||
|
|
||||||
/*** CDC Virtual Serial Port ***/
|
/*** CDC Virtual Serial Port ***/
|
||||||
|
|
||||||
|
@ -176,14 +215,14 @@
|
||||||
#define ENDPOINT_NB_5 0x80 | VCP_TX_EP
|
#define ENDPOINT_NB_5 0x80 | VCP_TX_EP
|
||||||
#define EP_ATTRIBUTES_5 0x02 // BULK = 0x02, INTERUPT = 0x03
|
#define EP_ATTRIBUTES_5 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||||
#define EP_SIZE_5 0x20
|
#define EP_SIZE_5 0x20
|
||||||
#define EP_INTERVAL_5 0x00
|
#define EP_INTERVAL_5 0x01
|
||||||
|
|
||||||
// USB Endpoint 6 descriptor
|
// USB Endpoint 6 descriptor
|
||||||
// Bulk OUT
|
// Bulk OUT
|
||||||
#define ENDPOINT_NB_6 VCP_RX_EP
|
#define ENDPOINT_NB_6 VCP_RX_EP
|
||||||
#define EP_ATTRIBUTES_6 0x02 // BULK = 0x02, INTERUPT = 0x03
|
#define EP_ATTRIBUTES_6 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||||
#define EP_SIZE_6 0x20
|
#define EP_SIZE_6 0x20
|
||||||
#define EP_INTERVAL_6 0x00
|
#define EP_INTERVAL_6 0x01
|
||||||
|
|
||||||
|
|
||||||
/*** Mass Storage ***/
|
/*** Mass Storage ***/
|
||||||
|
@ -227,61 +266,34 @@
|
||||||
#define EEM_ENDPOINT_NB_1 0x80 | TX_EP
|
#define EEM_ENDPOINT_NB_1 0x80 | TX_EP
|
||||||
#define EEM_EP_ATTRIBUTES_1 0x02 // BULK = 0x02, INTERUPT = 0x03
|
#define EEM_EP_ATTRIBUTES_1 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||||
#define EEM_EP_SIZE_1 0x40 //64 byte max size
|
#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
|
// USB Endpoint 2 descriptor
|
||||||
// Bulk OUT
|
// Bulk OUT
|
||||||
#define EEM_ENDPOINT_NB_2 RX_EP
|
#define EEM_ENDPOINT_NB_2 RX_EP
|
||||||
#define EEM_EP_ATTRIBUTES_2 0x02 // BULK = 0x02, INTERUPT = 0x03
|
#define EEM_EP_ATTRIBUTES_2 0x02 // BULK = 0x02, INTERUPT = 0x03
|
||||||
#define EEM_EP_SIZE_2 0x40 //64 byte max size
|
#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 DEVICE_STATUS 0x00 // TBD
|
||||||
#define INTERFACE_STATUS 0x00 // TBD
|
#define INTERFACE_STATUS 0x00 // TBD
|
||||||
|
|
||||||
#define LANG_ID 0x00
|
#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
|
#define LANGUAGE_ID 0x0409
|
||||||
|
|
||||||
//! Usb Request
|
//! Usb Request
|
||||||
|
@ -373,39 +385,6 @@ typedef struct {
|
||||||
} S_usb_language_id;
|
} 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 _______________________________________________________*/
|
/*_____ U S B I A D _______________________________________________________*/
|
||||||
|
|
||||||
#define DSC_TYPE_IAD 11
|
#define DSC_TYPE_IAD 11
|
||||||
|
@ -460,6 +439,79 @@ typedef struct
|
||||||
|
|
||||||
} S_usb_user_configuration_descriptor_network;
|
} 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 */
|
/* Mass Storage */
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -471,20 +523,12 @@ typedef struct
|
||||||
|
|
||||||
} S_usb_user_configuration_descriptor_mass;
|
} 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);
|
PGM_VOID_P Usb_get_dev_desc_pointer(void);
|
||||||
U8 Usb_get_dev_desc_length(void);
|
U8 Usb_get_dev_desc_length(void);
|
||||||
PGM_VOID_P Usb_get_conf_desc_pointer(void) ;
|
PGM_VOID_P Usb_get_conf_desc_pointer(U8 index) ;
|
||||||
U8 Usb_get_conf_desc_length(void);
|
U8 Usb_get_conf_desc_length(U8 index);
|
||||||
|
|
||||||
#endif // _USB_USERCONFIG_H_
|
#endif // _USB_USERCONFIG_H_
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "conf_usb.h"
|
#include "conf_usb.h"
|
||||||
#include "usb_drv.h"
|
#include "usb_drv.h"
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
//_____ M A C R O S ________________________________________________________
|
//_____ M A C R O S ________________________________________________________
|
||||||
|
|
||||||
|
@ -61,6 +62,102 @@
|
||||||
|
|
||||||
#if (USB_DEVICE_FEATURE == ENABLED)
|
#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.
|
//! usb_configure_endpoint.
|
||||||
//!
|
//!
|
||||||
//! This function configures an endpoint with the selected type.
|
//! 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
|
//! @defgroup Endpoints_configuration Configuration macros for endpoints
|
||||||
//! List of the standard macro used to configure pipes and 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_build_ep_config1(size, bank ) ((size<<4) | (bank<<2) )
|
||||||
#define usb_configure_endpoint(num, type, dir, size, bank, nyet) \
|
#define usb_configure_endpoint(num, type, dir, size, bank, nyet) \
|
||||||
( Usb_select_endpoint(num), \
|
( Usb_select_endpoint(num), \
|
||||||
|
@ -929,6 +929,13 @@ U8 host_determine_pipe_size (U16);
|
||||||
void host_disable_all_pipe (void);
|
void host_disable_all_pipe (void);
|
||||||
U8 usb_get_nb_pipe_interrupt (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_
|
#endif // _USB_DRV_H_
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -50,10 +50,12 @@
|
||||||
#include "usb_descriptors.h"
|
#include "usb_descriptors.h"
|
||||||
#include "usb_specific_request.h"
|
#include "usb_specific_request.h"
|
||||||
#include "rndis/rndis_protocol.h"
|
#include "rndis/rndis_protocol.h"
|
||||||
|
#include "rndis/cdc_ecm.h"
|
||||||
#include "serial/uart_usb_lib.h"
|
#include "serial/uart_usb_lib.h"
|
||||||
#include "storage/ctrl_access.h"
|
#include "storage/ctrl_access.h"
|
||||||
#include "uip.h"
|
#include "uip.h"
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
|
#include <avr/eeprom.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
//_____ M A C R O S ________________________________________________________
|
//_____ M A C R O S ________________________________________________________
|
||||||
|
@ -85,30 +87,44 @@ Bool usb_user_read_request(U8 type, U8 request)
|
||||||
{
|
{
|
||||||
U16 wLength;
|
U16 wLength;
|
||||||
|
|
||||||
//Both protocols have two bytes we throw away
|
|
||||||
Usb_read_byte();
|
|
||||||
Usb_read_byte();
|
|
||||||
|
|
||||||
switch(request)
|
switch(request)
|
||||||
{
|
{
|
||||||
case SEND_ENCAPSULATED_COMMAND:
|
case SEND_ENCAPSULATED_COMMAND:
|
||||||
|
Usb_read_byte();
|
||||||
|
Usb_read_byte();
|
||||||
Usb_read_byte();//wIndex LSB
|
Usb_read_byte();//wIndex LSB
|
||||||
Usb_read_byte();//wIndex MSB
|
Usb_read_byte();//wIndex MSB
|
||||||
|
|
||||||
LSB(wLength) = Usb_read_byte();
|
LSB(wLength) = Usb_read_byte();
|
||||||
MSB(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;
|
break;
|
||||||
|
|
||||||
case GET_ENCAPSULATED_COMMAND:
|
case GET_ENCAPSULATED_COMMAND:
|
||||||
|
Usb_read_byte();
|
||||||
|
Usb_read_byte();
|
||||||
Usb_read_byte();//wIndex LSB
|
Usb_read_byte();//wIndex LSB
|
||||||
Usb_read_byte();//wIndex MSB
|
Usb_read_byte();//wIndex MSB
|
||||||
|
|
||||||
LSB(wLength) = Usb_read_byte();
|
LSB(wLength) = Usb_read_byte();
|
||||||
MSB(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;
|
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
|
#if USB_CONF_STORAGE
|
||||||
case MASS_STORAGE_RESET:
|
case MASS_STORAGE_RESET:
|
||||||
Usb_ack_receive_setup();
|
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
|
/* 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 */
|
advertise that we support nothing, so shouldn't get them anyway */
|
||||||
case GET_LINE_CODING:
|
case GET_LINE_CODING:
|
||||||
cdc_get_line_coding();
|
Usb_read_byte();
|
||||||
return TRUE;
|
Usb_read_byte();
|
||||||
|
if(USB_CONFIG_HAS_DEBUG_PORT(usb_configuration_nb)) {
|
||||||
|
cdc_get_line_coding();
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SET_LINE_CODING:
|
case SET_LINE_CODING:
|
||||||
cdc_set_line_coding();
|
Usb_read_byte();
|
||||||
return TRUE;
|
Usb_read_byte();
|
||||||
|
if(USB_CONFIG_HAS_DEBUG_PORT(usb_configuration_nb)) {
|
||||||
|
cdc_set_line_coding();
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SET_CONTROL_LINE_STATE:
|
case SET_CONTROL_LINE_STATE:
|
||||||
cdc_set_control_line_state();
|
if(USB_CONFIG_HAS_DEBUG_PORT(usb_configuration_nb)) {
|
||||||
return TRUE;
|
cdc_set_control_line_state();
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* USB_CONF_CDC */
|
#endif /* USB_CONF_CDC */
|
||||||
default:
|
default:
|
||||||
|
@ -174,21 +206,6 @@ Bool usb_user_get_descriptor(U8 type, U8 string)
|
||||||
pbuffer = &(usb_user_language_id.bLength);
|
pbuffer = &(usb_user_language_id.bLength);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
break;
|
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:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -198,6 +215,94 @@ Bool usb_user_get_descriptor(U8 type, U8 string)
|
||||||
|
|
||||||
return FALSE;
|
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.
|
//! usb_user_endpoint_init.
|
||||||
//!
|
//!
|
||||||
|
@ -206,115 +311,54 @@ Bool usb_user_get_descriptor(U8 type, U8 string)
|
||||||
//! @param conf_nb Not used
|
//! @param conf_nb Not used
|
||||||
void usb_user_endpoint_init(U8 conf_nb)
|
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 */
|
switch(conf_nb) {
|
||||||
if ((usb_mode == rndis_only) || (usb_mode == rndis_debug)) {
|
case USB_CONFIG_ECM:
|
||||||
|
case USB_CONFIG_ECM_DEBUG:
|
||||||
|
cdc_ecm_configure_endpoints();
|
||||||
|
break;
|
||||||
|
|
||||||
usb_configure_endpoint(INT_EP, \
|
case USB_CONFIG_RNDIS_DEBUG:
|
||||||
TYPE_INTERRUPT, \
|
case USB_CONFIG_RNDIS:
|
||||||
DIRECTION_IN, \
|
rndis_configure_endpoints();
|
||||||
SIZE_64, \
|
break;
|
||||||
ONE_BANK, \
|
case USB_CONFIG_EEM:
|
||||||
NYET_ENABLED);
|
cdc_ecm_configure_endpoints();
|
||||||
|
|
||||||
usb_configure_endpoint(TX_EP, \
|
break;
|
||||||
TYPE_BULK, \
|
#if USB_CONF_STORAGE
|
||||||
DIRECTION_IN, \
|
case USB_CONFIG_MS:
|
||||||
SIZE_64, \
|
usb_configure_endpoint(VCP_INT_EP, \
|
||||||
TWO_BANKS, \
|
TYPE_INTERRUPT, \
|
||||||
NYET_ENABLED);
|
DIRECTION_IN, \
|
||||||
|
SIZE_32, \
|
||||||
|
ONE_BANK, \
|
||||||
|
NYET_ENABLED);
|
||||||
|
|
||||||
usb_configure_endpoint(RX_EP, \
|
usb_configure_endpoint(VCP_TX_EP, \
|
||||||
TYPE_BULK, \
|
TYPE_BULK, \
|
||||||
DIRECTION_OUT, \
|
DIRECTION_IN, \
|
||||||
SIZE_64, \
|
SIZE_32, \
|
||||||
TWO_BANKS, \
|
TWO_BANKS, \
|
||||||
NYET_ENABLED);
|
NYET_ENABLED);
|
||||||
|
|
||||||
}
|
usb_configure_endpoint(VCP_RX_EP, \
|
||||||
|
TYPE_BULK, \
|
||||||
/* If we use virtual comm port (VCP) endpoints */
|
DIRECTION_OUT, \
|
||||||
if (usb_mode == rndis_debug) {
|
SIZE_32, \
|
||||||
usb_configure_endpoint(VCP_INT_EP, \
|
TWO_BANKS, \
|
||||||
TYPE_INTERRUPT, \
|
NYET_ENABLED);
|
||||||
DIRECTION_IN, \
|
Usb_reset_endpoint(VCP_INT_EP);
|
||||||
SIZE_32, \
|
Usb_reset_endpoint(VCP_TX_EP);
|
||||||
ONE_BANK, \
|
Usb_reset_endpoint(VCP_RX_EP);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Led0_on();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USB_CONF_CDC
|
#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.bParityType);
|
||||||
Usb_write_byte(line_coding.bDataBits);
|
Usb_write_byte(line_coding.bDataBits);
|
||||||
|
|
||||||
Usb_send_control_in();
|
Usb_send_control_in();
|
||||||
while(!(Is_usb_read_control_enabled()));
|
|
||||||
//Usb_clear_tx_complete();
|
|
||||||
|
|
||||||
while(!Is_usb_receive_out());
|
|
||||||
Usb_ack_receive_out();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -352,19 +391,20 @@ void cdc_get_line_coding(void)
|
||||||
//!
|
//!
|
||||||
void cdc_set_line_coding (void)
|
void cdc_set_line_coding (void)
|
||||||
{
|
{
|
||||||
Usb_ack_receive_setup();
|
Usb_ack_receive_setup();
|
||||||
while (!(Is_usb_receive_out()));
|
if(usb_endpoint_wait_for_receive_out()==0) {
|
||||||
LSB0(line_coding.dwDTERate) = Usb_read_byte();
|
LSB0(line_coding.dwDTERate) = Usb_read_byte();
|
||||||
LSB1(line_coding.dwDTERate) = Usb_read_byte();
|
LSB1(line_coding.dwDTERate) = Usb_read_byte();
|
||||||
LSB2(line_coding.dwDTERate) = Usb_read_byte();
|
LSB2(line_coding.dwDTERate) = Usb_read_byte();
|
||||||
LSB3(line_coding.dwDTERate) = Usb_read_byte();
|
LSB3(line_coding.dwDTERate) = Usb_read_byte();
|
||||||
line_coding.bCharFormat = Usb_read_byte();
|
line_coding.bCharFormat = Usb_read_byte();
|
||||||
line_coding.bParityType = Usb_read_byte();
|
line_coding.bParityType = Usb_read_byte();
|
||||||
line_coding.bDataBits = Usb_read_byte();
|
line_coding.bDataBits = Usb_read_byte();
|
||||||
Usb_ack_receive_out();
|
Usb_ack_receive_out();
|
||||||
|
|
||||||
Usb_send_control_in(); // send a ZLP for STATUS phase
|
Usb_send_control_in(); // send a ZLP for STATUS phase
|
||||||
while(!(Is_usb_read_control_enabled()));
|
usb_endpoint_wait_for_read_control_enabled();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! cdc_set_control_line_state.
|
//! cdc_set_control_line_state.
|
||||||
|
@ -375,8 +415,27 @@ void cdc_set_line_coding (void)
|
||||||
//!
|
//!
|
||||||
void cdc_set_control_line_state (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_ack_receive_setup();
|
||||||
Usb_send_control_in();
|
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 */
|
#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_composite usb_conf_desc_composite;
|
||||||
extern FLASH S_usb_user_configuration_descriptor_network usb_conf_desc_network;
|
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_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;
|
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_read_request(U8, U8);
|
||||||
Bool usb_user_get_descriptor(U8 , U8);
|
Bool usb_user_get_descriptor(U8 , U8);
|
||||||
void usb_user_endpoint_init(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_get_line_coding();
|
||||||
void cdc_set_line_coding();
|
void cdc_set_line_coding();
|
||||||
|
|
|
@ -52,11 +52,14 @@
|
||||||
#include "usb_drv.h"
|
#include "usb_drv.h"
|
||||||
#include "usb_descriptors.h"
|
#include "usb_descriptors.h"
|
||||||
#include "usb_specific_request.h"
|
#include "usb_specific_request.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
//_____ M A C R O S ________________________________________________________
|
//_____ M A C R O S ________________________________________________________
|
||||||
|
|
||||||
|
|
||||||
//_____ D E F I N I T I O N ________________________________________________
|
//_____ 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 ______________________________
|
//_____ 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:
|
case GET_DESCRIPTOR:
|
||||||
if (0x80 == bmRequestType) { usb_get_descriptor(); }
|
if (0x80 == bmRequestType) { usb_get_descriptor(); }
|
||||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
else goto user_read;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GET_CONFIGURATION:
|
case GET_CONFIGURATION:
|
||||||
if (0x80 == bmRequestType) { usb_get_configuration(); }
|
if (0x80 == bmRequestType) { usb_get_configuration(); }
|
||||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
else goto user_read;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SET_ADDRESS:
|
case SET_ADDRESS:
|
||||||
if (0x00 == bmRequestType) { usb_set_address(); }
|
if (0x00 == bmRequestType) { usb_set_address(); }
|
||||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
else goto user_read;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SET_CONFIGURATION:
|
case SET_CONFIGURATION:
|
||||||
if (0x00 == bmRequestType) { usb_set_configuration(); }
|
if (0x00 == bmRequestType) { usb_set_configuration(); }
|
||||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
else goto user_read;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLEAR_FEATURE:
|
case CLEAR_FEATURE:
|
||||||
if (0x02 >= bmRequestType) { usb_clear_feature(); }
|
if (0x02 >= bmRequestType) { usb_clear_feature(); }
|
||||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
else goto user_read;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SET_FEATURE:
|
case SET_FEATURE:
|
||||||
if (0x02 >= bmRequestType) { usb_set_feature(); }
|
if (0x02 >= bmRequestType) { usb_set_feature(); }
|
||||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
else goto user_read;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GET_STATUS:
|
case GET_STATUS:
|
||||||
if ((0x7F < bmRequestType) & (0x82 >= bmRequestType))
|
if ((0x7F < bmRequestType) & (0x82 >= bmRequestType))
|
||||||
{ usb_get_status(); }
|
{ usb_get_status(); }
|
||||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
else goto user_read;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GET_INTERFACE:
|
case GET_INTERFACE:
|
||||||
if (bmRequestType == 0x81) { usb_get_interface(); }
|
if (bmRequestType == 0x81) { usb_get_interface(); }
|
||||||
else { usb_user_read_request(bmRequestType, bmRequest); }
|
else goto user_read;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,14 +173,23 @@ void usb_process_request(void)
|
||||||
case SET_DESCRIPTOR:
|
case SET_DESCRIPTOR:
|
||||||
case SYNCH_FRAME:
|
case SYNCH_FRAME:
|
||||||
default: //!< un-supported request => call to user read request
|
default: //!< un-supported request => call to user read request
|
||||||
if(usb_user_read_request(bmRequestType, bmRequest) == FALSE)
|
user_read:
|
||||||
{
|
usb_user_read_request(bmRequestType, bmRequest);
|
||||||
Usb_enable_stall_handshake();
|
|
||||||
Usb_ack_receive_setup();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
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.
|
//! usb_set_address.
|
||||||
|
@ -214,26 +226,205 @@ U8 configuration_number;
|
||||||
|
|
||||||
configuration_number = Usb_read_byte();
|
configuration_number = Usb_read_byte();
|
||||||
|
|
||||||
if (configuration_number <= NB_CONFIGURATION)
|
// TODO: Verify configuration_number!
|
||||||
{
|
Usb_ack_receive_setup();
|
||||||
Usb_ack_receive_setup();
|
usb_configuration_nb = configuration_number;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Usb_send_control_in(); //!< send a ZLP for STATUS phase
|
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_user_endpoint_init(usb_configuration_nb); //!< endpoint configuration
|
||||||
Usb_set_configuration_action();
|
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.
|
//! usb_get_descriptor.
|
||||||
//!
|
//!
|
||||||
//! This function manages the GET DESCRIPTOR request. The device descriptor,
|
//! This function manages the GET DESCRIPTOR request. The device descriptor,
|
||||||
|
@ -246,91 +437,93 @@ U8 configuration_number;
|
||||||
//!
|
//!
|
||||||
void usb_get_descriptor(void)
|
void usb_get_descriptor(void)
|
||||||
{
|
{
|
||||||
U8 LSBwLength, MSBwLength;
|
U8 LSBwLength, MSBwLength;
|
||||||
U8 descriptor_type ;
|
U8 descriptor_type ;
|
||||||
U8 string_type ;
|
U8 string_type ;
|
||||||
U8 dummy;
|
U8 dummy;
|
||||||
U8 nb_byte;
|
|
||||||
|
|
||||||
zlp = FALSE; /* no zero length packet */
|
zlp = FALSE; /* no zero length packet */
|
||||||
string_type = Usb_read_byte(); /* read LSB of wValue */
|
string_type = Usb_read_byte(); /* read LSB of wValue */
|
||||||
descriptor_type = Usb_read_byte(); /* read MSB of wValue */
|
descriptor_type = Usb_read_byte(); /* read MSB of wValue */
|
||||||
|
|
||||||
dummy = Usb_read_byte(); //!< don't care of wIndex field
|
switch (descriptor_type)
|
||||||
dummy = Usb_read_byte();
|
{
|
||||||
LSBwLength = Usb_read_byte(); //!< read wLength
|
case DEVICE_DESCRIPTOR:
|
||||||
MSBwLength = Usb_read_byte();
|
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)
|
dummy = Usb_read_byte(); //!< don't care of wIndex field
|
||||||
{
|
dummy = Usb_read_byte();
|
||||||
case DEVICE_DESCRIPTOR:
|
LSBwLength = Usb_read_byte(); //!< read wLength
|
||||||
data_to_transfer = Usb_get_dev_desc_length(); //!< sizeof (usb_user_device_descriptor);
|
MSBwLength = Usb_read_byte();
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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))
|
LSBwLength = data_to_transfer;
|
||||||
{
|
MSBwLength = 0x00;
|
||||||
if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; }
|
} else {
|
||||||
else { zlp = FALSE; } //!< no need of zero length packet
|
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;
|
//! Send data until necessary
|
||||||
MSBwLength = 0x00;
|
while(data_to_transfer != 0) {
|
||||||
}
|
// if(Is_usb_write_enabled()) //!< Check endpoint 0 size
|
||||||
else
|
if(nb_byte++==EP_CONTROL_LENGTH) //!< Check endpoint 0 size
|
||||||
{
|
break;
|
||||||
data_to_transfer = LSBwLength; //!< send only requested number of data
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Usb_write_byte(pgm_read_byte_near((unsigned int)pbuffer++));
|
||||||
|
data_to_transfer --;
|
||||||
|
|
||||||
while((data_to_transfer != 0) && (!Is_usb_receive_out()))
|
}
|
||||||
{
|
Usb_send_control_in();
|
||||||
while(!Is_usb_read_control_enabled());
|
}
|
||||||
|
|
||||||
nb_byte=0;
|
if(Is_usb_receive_out()) {
|
||||||
while(data_to_transfer != 0) //!< Send data until necessary
|
//! abort from Host
|
||||||
{
|
Usb_ack_receive_out();
|
||||||
if(nb_byte++==EP_CONTROL_LENGTH) //!< Check endpoint 0 size
|
return;
|
||||||
{
|
}
|
||||||
break;
|
|
||||||
}
|
if(zlp == TRUE) {
|
||||||
|
if(usb_endpoint_wait_for_read_control_enabled()!=0) {
|
||||||
|
Usb_enable_stall_handshake();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Usb_send_control_in();
|
||||||
|
}
|
||||||
|
|
||||||
//#ifndef AVRGCC
|
usb_endpoint_wait_for_receive_out();
|
||||||
// Usb_write_byte(*pbuffer++);
|
Usb_ack_receive_out();
|
||||||
//#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_get_configuration.
|
//! usb_get_configuration.
|
||||||
|
@ -345,9 +538,9 @@ void usb_get_configuration(void)
|
||||||
Usb_ack_receive_setup();
|
Usb_ack_receive_setup();
|
||||||
|
|
||||||
Usb_write_byte(usb_configuration_nb);
|
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();
|
Usb_ack_receive_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,7 +583,7 @@ U8 dummy;
|
||||||
Usb_write_byte(0x00);
|
Usb_write_byte(0x00);
|
||||||
Usb_send_control_in();
|
Usb_send_control_in();
|
||||||
|
|
||||||
while( !Is_usb_receive_out() );
|
usb_endpoint_wait_for_receive_out();
|
||||||
Usb_ack_receive_out();
|
Usb_ack_receive_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,10 +602,6 @@ U8 dummy;
|
||||||
|
|
||||||
if (bmRequestType == INTERFACE_TYPE)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
else if (bmRequestType == ENDPOINT_TYPE)
|
else if (bmRequestType == ENDPOINT_TYPE)
|
||||||
|
@ -426,8 +615,6 @@ U8 dummy;
|
||||||
|
|
||||||
if (wIndex == EP_CONTROL)
|
if (wIndex == EP_CONTROL)
|
||||||
{
|
{
|
||||||
Usb_enable_stall_handshake();
|
|
||||||
Usb_ack_receive_setup();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,15 +630,11 @@ U8 dummy;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Usb_select_endpoint(EP_CONTROL);
|
Usb_select_endpoint(EP_CONTROL);
|
||||||
Usb_enable_stall_handshake();
|
|
||||||
Usb_ack_receive_setup();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Usb_enable_stall_handshake();
|
|
||||||
Usb_ack_receive_setup();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -471,18 +654,10 @@ U8 dummy;
|
||||||
|
|
||||||
if (bmRequestType == ZERO_TYPE)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
else if (bmRequestType == INTERFACE_TYPE)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
else if (bmRequestType == ENDPOINT_TYPE)
|
else if (bmRequestType == ENDPOINT_TYPE)
|
||||||
|
@ -507,19 +682,15 @@ U8 dummy;
|
||||||
endpoint_status[wIndex] = 0x00;
|
endpoint_status[wIndex] = 0x00;
|
||||||
Usb_ack_receive_setup();
|
Usb_ack_receive_setup();
|
||||||
Usb_send_control_in();
|
Usb_send_control_in();
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Usb_select_endpoint(EP_CONTROL);
|
|
||||||
Usb_enable_stall_handshake();
|
|
||||||
Usb_ack_receive_setup();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Usb_enable_stall_handshake();
|
|
||||||
Usb_ack_receive_setup();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -533,8 +704,7 @@ U8 dummy;
|
||||||
//!
|
//!
|
||||||
void usb_get_interface (void)
|
void usb_get_interface (void)
|
||||||
{
|
{
|
||||||
Usb_enable_stall_handshake();
|
// Not yet implemented.
|
||||||
Usb_ack_receive_setup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! usb_set_interface.
|
//! usb_set_interface.
|
||||||
|
@ -545,7 +715,21 @@ void usb_get_interface (void)
|
||||||
//!
|
//!
|
||||||
void usb_set_interface (void)
|
void usb_set_interface (void)
|
||||||
{
|
{
|
||||||
Usb_ack_receive_setup();
|
U8 alt_setting;
|
||||||
Usb_send_control_in(); //!< send a ZLP for STATUS phase
|
U8 dummy;
|
||||||
while(!Is_usb_in_ready());
|
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)
|
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
|
//Linux is a bunch of lies, and won't read
|
||||||
//and screw up the data transfers
|
//the interrupt endpoint. Hence if this isn't ready just exit
|
||||||
if (!usb_busy) {
|
//while(!Is_usb_write_enabled());
|
||||||
|
|
||||||
/* Check for setup packets */
|
if (Is_usb_write_enabled()) {
|
||||||
Usb_select_endpoint(EP_CONTROL);
|
|
||||||
if (Is_usb_receive_setup()) {
|
// Only valid interrupt is:
|
||||||
usb_process_request();
|
// 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
|
/* Continue polling */
|
||||||
out something to the RNDIS interrupt endpoint */
|
process_poll(&usb_process);
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of the Contiki operating system.
|
* 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.
|
* This code is almost device independent and should be easy to port.
|
||||||
|
@ -56,20 +56,6 @@
|
||||||
#include "net/rime/rimestats.h"
|
#include "net/rime/rimestats.h"
|
||||||
#include "net/netstack.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"
|
#include "sys/timetable.h"
|
||||||
|
|
||||||
#define WITH_SEND_CCA 0
|
#define WITH_SEND_CCA 0
|
||||||
|
@ -91,17 +77,19 @@ extern rimeaddr_t macLongAddr;
|
||||||
#define RF230_CONF_AUTOACK 1
|
#define RF230_CONF_AUTOACK 1
|
||||||
#endif /* RF230_CONF_AUTOACK */
|
#endif /* RF230_CONF_AUTOACK */
|
||||||
|
|
||||||
|
#if RF230_CONF_AUTOACK
|
||||||
|
static bool is_promiscuous;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef RF230_CONF_AUTORETRIES
|
#ifndef RF230_CONF_AUTORETRIES
|
||||||
#define RF230_CONF_AUTORETRIES 2
|
#define RF230_CONF_AUTORETRIES 2
|
||||||
#endif /* RF230_CONF_AUTOACK */
|
#endif /* RF230_CONF_AUTOACK */
|
||||||
|
|
||||||
//Automatic and manual CRC both append 2 bytes to packets
|
//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"
|
#include "lib/crc16.h"
|
||||||
#define CHECKSUM_LEN 2
|
|
||||||
#else
|
|
||||||
#define CHECKSUM_LEN 2
|
|
||||||
#endif /* RF230_CONF_CHECKSUM */
|
#endif /* RF230_CONF_CHECKSUM */
|
||||||
|
#define CHECKSUM_LEN 2
|
||||||
|
|
||||||
#define AUX_LEN (CHECKSUM_LEN + TIMESTAMP_LEN + FOOTER_LEN)
|
#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;
|
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 */
|
/* Received frames are buffered to rxframe in the interrupt routine in hal.c */
|
||||||
hal_rx_frame_t rxframe;
|
hal_rx_frame_t rxframe;
|
||||||
|
@ -424,6 +412,33 @@ radio_set_trx_state(uint8_t new_state)
|
||||||
return set_state_status;
|
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
|
static void
|
||||||
flushrx(void)
|
flushrx(void)
|
||||||
{
|
{
|
||||||
|
@ -436,20 +451,9 @@ static void
|
||||||
on(void)
|
on(void)
|
||||||
{
|
{
|
||||||
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
|
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
|
||||||
#if JACKDAW
|
|
||||||
//blue=0 red=1 green=2 yellow=3
|
#ifdef RF230BB_HOOK_RADIO_ON
|
||||||
#define Led0_on() (PORTD |= 0x80)
|
RF230BB_HOOK_RADIO_ON();
|
||||||
#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");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (RF230_sleeping) {
|
if (RF230_sleeping) {
|
||||||
|
@ -461,7 +465,7 @@ on(void)
|
||||||
rf230_waitidle();
|
rf230_waitidle();
|
||||||
|
|
||||||
#if RF230_CONF_AUTOACK
|
#if RF230_CONF_AUTOACK
|
||||||
radio_set_trx_state(RX_AACK_ON);
|
radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON);
|
||||||
#else
|
#else
|
||||||
radio_set_trx_state(RX_ON);
|
radio_set_trx_state(RX_ON);
|
||||||
#endif
|
#endif
|
||||||
|
@ -475,10 +479,8 @@ off(void)
|
||||||
// rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
|
// rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
|
||||||
RF230_receive_on = 0;
|
RF230_receive_on = 0;
|
||||||
|
|
||||||
#if JACKDAW
|
#ifdef RF230BB_HOOK_RADIO_OFF
|
||||||
Led1_off();
|
RF230BB_HOOK_RADIO_OFF();
|
||||||
#else
|
|
||||||
// PRINTSHORT("f");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// DEBUGFLOW('F');
|
// DEBUGFLOW('F');
|
||||||
|
@ -581,7 +583,7 @@ rf230_init(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static uint8_t buffer[RF230_MAX_TX_FRAME_LENGTH];
|
static uint8_t buffer[RF230_MAX_TX_FRAME_LENGTH+AUX_LEN];
|
||||||
static int
|
static int
|
||||||
rf230_transmit(unsigned short payload_len)
|
rf230_transmit(unsigned short payload_len)
|
||||||
{
|
{
|
||||||
|
@ -711,6 +713,7 @@ rf230_transmit(unsigned short payload_len)
|
||||||
static int
|
static int
|
||||||
rf230_prepare(const void *payload, unsigned short payload_len)
|
rf230_prepare(const void *payload, unsigned short payload_len)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
uint8_t total_len,*pbuf;
|
uint8_t total_len,*pbuf;
|
||||||
#if RF230_CONF_TIMESTAMPS
|
#if RF230_CONF_TIMESTAMPS
|
||||||
struct timestamp timestamp;
|
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 (total_len > RF230_MAX_TX_FRAME_LENGTH){
|
||||||
#if RADIOSTATS
|
#if RADIOSTATS
|
||||||
RF230_sendfail++;
|
RF230_sendfail++;
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
#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];
|
pbuf=&buffer[0];
|
||||||
memcpy(pbuf,payload,payload_len);
|
memcpy(pbuf,payload,payload_len);
|
||||||
|
@ -755,66 +762,46 @@ rf230_prepare(const void *payload, unsigned short payload_len)
|
||||||
pbuf+=TIMESTAMP_LEN;
|
pbuf+=TIMESTAMP_LEN;
|
||||||
#endif /* RF230_CONF_TIMESTAMPS */
|
#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 */
|
#ifdef RF230BB_HOOK_TX_PACKET
|
||||||
memcpy(&raw_buf[UIP_LLH_LEN], buffer, total_len);
|
#if !RF230_CONF_CHECKSUM
|
||||||
sendlen = total_len;
|
{ // Add a checksum before we log the packet out
|
||||||
|
uint16_t checksum;
|
||||||
/* Setup generic ethernet stuff */
|
checksum = crc16_data(payload, payload_len, 0);
|
||||||
ETHBUF(raw_buf)->type = htons(0x809A); //UIP_ETHTYPE_802154 0x809A
|
memcpy(buffer+total_len-CHECKSUM_LEN,&checksum,CHECKSUM_LEN);
|
||||||
|
|
||||||
// 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++;
|
|
||||||
}
|
}
|
||||||
#endif /* JACKDAW */
|
#endif /* RF230_CONF_CHECKSUM */
|
||||||
|
RF230BB_HOOK_TX_PACKET(buffer,total_len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bail:
|
||||||
RELEASE_LOCK();
|
RELEASE_LOCK();
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
static int
|
||||||
rf230_send(const void *payload, unsigned short payload_len)
|
rf230_send(const void *payload, unsigned short payload_len)
|
||||||
{
|
{
|
||||||
rf230_prepare(payload, payload_len);
|
int ret = 0;
|
||||||
#if JACKDAW
|
|
||||||
// In sniffer mode we don't ever send anything
|
#ifdef RF230BB_HOOK_IS_SEND_ENABLED
|
||||||
if (usbstick_mode.sendToRf == 0) {
|
if(!RF230BB_HOOK_IS_SEND_ENABLED()) {
|
||||||
uip_len = 0;
|
goto bail;
|
||||||
return 0;
|
}
|
||||||
}
|
#endif
|
||||||
#endif /* JACKDAW */
|
|
||||||
return rf230_transmit(payload_len);
|
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
|
int
|
||||||
|
@ -862,7 +849,7 @@ rf230_on(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
uint8_t
|
||||||
rf230_get_channel(void)
|
rf230_get_channel(void)
|
||||||
{
|
{
|
||||||
//jackdaw reads zero channel, raven reads correct channel?
|
//jackdaw reads zero channel, raven reads correct channel?
|
||||||
|
@ -871,7 +858,7 @@ rf230_get_channel(void)
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rf230_set_channel(int c)
|
rf230_set_channel(uint8_t c)
|
||||||
{
|
{
|
||||||
/* Wait for any transmission to end. */
|
/* Wait for any transmission to end. */
|
||||||
// PRINTF("rf230: Set Channel %u\n",c);
|
// PRINTF("rf230: Set Channel %u\n",c);
|
||||||
|
@ -883,7 +870,7 @@ rf230_set_channel(int c)
|
||||||
void
|
void
|
||||||
rf230_set_pan_addr(unsigned pan,
|
rf230_set_pan_addr(unsigned pan,
|
||||||
unsigned addr,
|
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)
|
//rf230_set_pan_addr(uint16_t pan,uint16_t addr,uint8_t *ieee_addr)
|
||||||
{
|
{
|
||||||
PRINTF("rf230: PAN=%x Short Addr=%x\n",pan,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 */
|
/* Transfer the frame, stripping the footer */
|
||||||
framep=&(rxframe.data[0]);
|
framep=&(rxframe.data[0]);
|
||||||
memcpy(buf,framep,len-AUX_LEN);
|
memcpy(buf,framep,len-AUX_LEN+CHECKSUM_LEN);
|
||||||
framep+=len-AUX_LEN;
|
framep+=len-AUX_LEN;
|
||||||
/* Clear the length field to allow buffering of the next packet */
|
/* Clear the length field to allow buffering of the next packet */
|
||||||
rxframe.length=0;
|
rxframe.length=0;
|
||||||
|
|
||||||
#if RF230_CONF_CHECKSUM
|
#if RF230_CONF_CHECKSUM
|
||||||
memcpy(&checksum,framep,CHECKSUM_LEN);
|
memcpy(&checksum,framep,CHECKSUM_LEN);
|
||||||
framep+=CHECKSUM_LEN;
|
|
||||||
#endif /* RF230_CONF_CHECKSUM */
|
#endif /* RF230_CONF_CHECKSUM */
|
||||||
|
framep+=CHECKSUM_LEN;
|
||||||
#if RF230_CONF_TIMESTAMPS
|
#if RF230_CONF_TIMESTAMPS
|
||||||
memcpy(&t,framep,TIMESTAMP_LEN);
|
memcpy(&t,framep,TIMESTAMP_LEN);
|
||||||
framep+=TIMESTAMP_LEN;
|
|
||||||
#endif /* RF230_CONF_TIMESTAMPS */
|
#endif /* RF230_CONF_TIMESTAMPS */
|
||||||
|
framep+=TIMESTAMP_LEN;
|
||||||
#if FOOTER_LEN
|
#if FOOTER_LEN
|
||||||
memcpy(footer,framep,FOOTER_LEN);
|
memcpy(footer,framep,FOOTER_LEN);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1152,52 +1139,11 @@ if (RF230_receive_on) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// RELEASE_LOCK();
|
// 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 */
|
#ifdef RF230BB_HOOK_RX_PACKET
|
||||||
memcpy(&raw_buf[UIP_LLH_LEN], buf, len);
|
RF230BB_HOOK_RX_PACKET(buf,len);
|
||||||
sendlen = 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;
|
return len - AUX_LEN;
|
||||||
|
|
||||||
|
@ -1217,30 +1163,23 @@ rf230_set_txpower(uint8_t power)
|
||||||
RELEASE_LOCK();
|
RELEASE_LOCK();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
uint8_t
|
||||||
rf230_get_txpower(void)
|
rf230_get_txpower(void)
|
||||||
{
|
{
|
||||||
uint8_t power;
|
uint8_t power = TX_PWR_UNDEFINED;
|
||||||
if (radio_is_sleeping() ==true) {
|
if (radio_is_sleeping()) {
|
||||||
PRINTF("rf230_get_txpower:Sleeping");
|
PRINTF("rf230_get_txpower:Sleeping");
|
||||||
return 0;
|
} else {
|
||||||
} else {
|
power = hal_subregister_read(SR_TX_PWR);
|
||||||
// return hal_subregister_read(SR_TX_PWR);
|
}
|
||||||
power=hal_subregister_read(SR_TX_PWR);
|
return power;
|
||||||
if (power==0) {
|
|
||||||
PRINTSHORT("PZ");
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return power;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
uint8_t
|
||||||
rf230_rssi(void)
|
rf230_get_raw_rssi(void)
|
||||||
{
|
{
|
||||||
int rssi;
|
uint8_t rssi;
|
||||||
int radio_was_off = 0;
|
bool radio_was_off = 0;
|
||||||
|
|
||||||
/*The RSSI measurement should only be done in RX_ON or BUSY_RX.*/
|
/*The RSSI measurement should only be done in RX_ON or BUSY_RX.*/
|
||||||
if(!RF230_receive_on) {
|
if(!RF230_receive_on) {
|
||||||
|
@ -1249,11 +1188,6 @@ rf230_rssi(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
rssi = (int)((signed char)hal_subregister_read(SR_RSSI));
|
rssi = (int)((signed char)hal_subregister_read(SR_RSSI));
|
||||||
if (rssi==0) {
|
|
||||||
DEBUGFLOW('r');
|
|
||||||
PRINTF("RSZ");
|
|
||||||
rssi=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(radio_was_off) {
|
if(radio_was_off) {
|
||||||
rf230_off();
|
rf230_off();
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
* \file
|
* \file
|
||||||
* \brief This file contains radio driver code.
|
* \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
|
#ifndef RADIO_H
|
||||||
|
@ -73,6 +73,11 @@
|
||||||
#define TX_PWR_3DBM ( 0 )
|
#define TX_PWR_3DBM ( 0 )
|
||||||
#define TX_PWR_17_2DBM ( 15 )
|
#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_HIGHEST_VOLTAGE ( 15 )
|
||||||
#define BATTERY_MONITOR_VOLTAGE_UNDER_THRESHOLD ( 0 )
|
#define BATTERY_MONITOR_VOLTAGE_UNDER_THRESHOLD ( 0 )
|
||||||
#define BATTERY_MONITOR_HIGH_VOLTAGE ( 1 )
|
#define BATTERY_MONITOR_HIGH_VOLTAGE ( 1 )
|
||||||
|
@ -168,89 +173,44 @@ typedef enum{
|
||||||
}radio_clkm_speed_t;
|
}radio_clkm_speed_t;
|
||||||
|
|
||||||
typedef void (*radio_rx_callback) (uint16_t data);
|
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 ====================================*/
|
/*============================ PROTOTYPES ====================================*/
|
||||||
|
|
||||||
const struct radio_driver rf230_driver;
|
const struct radio_driver rf230_driver;
|
||||||
|
|
||||||
int rf230_init(void);
|
int rf230_init(void);
|
||||||
//int rf230_on(void);
|
//int rf230_on(void);
|
||||||
//int rf230_off(void);
|
//int rf230_off(void);
|
||||||
void rf230_set_channel(int channel);
|
void rf230_set_channel(uint8_t channel);
|
||||||
int rf230_get_channel(void);
|
uint8_t rf230_get_channel(void);
|
||||||
void rf230_set_pan_addr(unsigned pan,unsigned addr,const uint8_t *ieee_addr);
|
void rf230_set_pan_addr(unsigned pan,unsigned addr,const uint8_t ieee_addr[8]);
|
||||||
//void rf230_set_pan_addr(uint16_t pan,uint16_t addr,uint8_t *ieee_addr);
|
void rf230_set_txpower(uint8_t power);
|
||||||
//void rf230_set_txpower(uint8_t power);
|
uint8_t rf230_get_txpower(void);
|
||||||
int rf230_get_txpower(void);
|
|
||||||
|
|
||||||
//extern signed char rf230_last_rssi;
|
void rf230_set_promiscuous_mode(bool isPromiscuous);
|
||||||
//extern uint8_t rf230_last_correlation;
|
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 ) ) )
|
#define delay_us( us ) ( _delay_loop_2( ( F_CPU / 4000000UL ) * ( us ) ) )
|
||||||
|
|
||||||
#endif
|
#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.
|
* 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 */
|
/* Dummy watchdog routines for the Raven 1284p */
|
||||||
#include "dev/watchdog.h"
|
#include "dev/watchdog.h"
|
||||||
|
#include <avr/wdt.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
static int stopped = 0;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
watchdog_init(void)
|
watchdog_init(void)
|
||||||
{
|
{
|
||||||
|
MCUSR&=~(1<<WDRF);
|
||||||
|
stopped = 0;
|
||||||
|
watchdog_stop();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
watchdog_start(void)
|
watchdog_start(void)
|
||||||
{
|
{
|
||||||
|
stopped--;
|
||||||
|
if(!stopped)
|
||||||
|
wdt_enable(WDTO_2S);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
watchdog_periodic(void)
|
watchdog_periodic(void)
|
||||||
{
|
{
|
||||||
|
if(!stopped)
|
||||||
|
wdt_reset();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
watchdog_stop(void)
|
watchdog_stop(void)
|
||||||
{
|
{
|
||||||
|
stopped++;
|
||||||
|
wdt_disable();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
watchdog_reboot(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};
|
uint8_t mac_address[8] EEMEM = {0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x55};
|
||||||
#endif
|
#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------------------------*/
|
/*-------------------------Low level initialization------------------------*/
|
||||||
/*------Done in a subroutine to keep main routine stack usage small--------*/
|
/*------Done in a subroutine to keep main routine stack usage small--------*/
|
||||||
void initialize(void)
|
void initialize(void)
|
||||||
{
|
{
|
||||||
//calibrate_rc_osc_32k(); //CO: Had to comment this out
|
//calibrate_rc_osc_32k(); //CO: Had to comment this out
|
||||||
|
watchdog_init();
|
||||||
|
watchdog_start();
|
||||||
|
|
||||||
#ifdef RAVEN_LCD_INTERFACE
|
#ifdef RAVEN_LCD_INTERFACE
|
||||||
/* First rs232 port for Raven 3290 port */
|
/* 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);
|
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;
|
rimeaddr_t addr;
|
||||||
memset(&addr, 0, sizeof(rimeaddr_t));
|
memset(&addr, 0, sizeof(rimeaddr_t));
|
||||||
AVR_ENTER_CRITICAL_REGION();
|
get_mac_from_eeprom(addr.u8);
|
||||||
eeprom_read_block ((void *)&addr.u8, &mac_address, 8);
|
|
||||||
AVR_LEAVE_CRITICAL_REGION();
|
|
||||||
|
|
||||||
memcpy(&uip_lladdr.addr, &addr.u8, 8);
|
memcpy(&uip_lladdr.addr, &addr.u8, 8);
|
||||||
rf230_set_pan_addr(IEEE802154_PANID, 0, (uint8_t *)&addr.u8);
|
rf230_set_pan_addr(
|
||||||
rf230_set_channel(26);
|
get_panid_from_eeprom(),
|
||||||
|
get_panaddr_from_eeprom(),
|
||||||
|
(uint8_t *)&addr.u8
|
||||||
|
);
|
||||||
|
rf230_set_channel(get_channel_from_eeprom());
|
||||||
|
|
||||||
rimeaddr_set_node_addr(&addr);
|
rimeaddr_set_node_addr(&addr);
|
||||||
|
|
||||||
|
@ -312,7 +345,7 @@ main(void)
|
||||||
// len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE);
|
// len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE);
|
||||||
// packetbuf_set_datalen(42);
|
// packetbuf_set_datalen(42);
|
||||||
// NETSTACK_RDC.input();
|
// NETSTACK_RDC.input();
|
||||||
|
watchdog_periodic();
|
||||||
#if TESTRTIMER
|
#if TESTRTIMER
|
||||||
if (rtimerflag) { //8 seconds is maximum interval, my raven 6% slow
|
if (rtimerflag) { //8 seconds is maximum interval, my raven 6% slow
|
||||||
rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
|
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 \
|
cdc_task.c \
|
||||||
rndis_task.c \
|
rndis_task.c \
|
||||||
rndis.c \
|
rndis.c \
|
||||||
|
cdc_eem.c \
|
||||||
|
cdc_ecm.c \
|
||||||
usb_descriptors.c \
|
usb_descriptors.c \
|
||||||
usb_drv.c \
|
usb_drv.c \
|
||||||
usb_specific_request.c \
|
usb_specific_request.c \
|
||||||
usb_standard_request.c \
|
usb_standard_request.c \
|
||||||
usb_task.c \
|
usb_task.c
|
||||||
scsi_decoder.c \
|
|
||||||
ctrl_access.c \
|
#Files needed for USB Mass storage device enumeration
|
||||||
storage_task.c \
|
USB += scsi_decoder.c ctrl_access.c storage_task.c avr_flash.c
|
||||||
avr_flash.c
|
|
||||||
|
|
||||||
#As of September 2010 the following are needed for rpl. They need explicit inclusion if CONTIKI_NO_NET=1
|
#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
|
#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 \
|
CONTIKI_TARGET_SOURCEFILES += cfs-eeprom.c eeprom.c random.c \
|
||||||
mmem.c contiki-raven-default-init-lowlevel.c \
|
mmem.c contiki-raven-default-init-lowlevel.c \
|
||||||
contiki-raven-default-init-net.c contiki-raven-main.c httpd-simple-avr.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) \
|
$(RPL) \
|
||||||
$(USB)
|
$(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__
|
#ifndef __CONTIKI_CONF_H__
|
||||||
#define __CONTIKI_CONF_H__
|
#define __CONTIKI_CONF_H__
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* ************************************************************************** */
|
||||||
|
//#pragma mark Basic Configuration
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
/* MCU and clock rate */
|
/* MCU and clock rate */
|
||||||
#define MCU_MHZ 8
|
#define MCU_MHZ 8
|
||||||
#define PLATFORM PLATFORM_AVR
|
#define PLATFORM PLATFORM_AVR
|
||||||
|
@ -51,6 +59,14 @@
|
||||||
/* Clock ticks per second */
|
/* Clock ticks per second */
|
||||||
#define CLOCK_CONF_SECOND 125
|
#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 */
|
/* 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*/
|
#define RIME_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME CLOCK_CONF_SECOND * 524UL /*Default uses 600*/
|
||||||
|
|
||||||
|
@ -74,13 +90,71 @@
|
||||||
#define CCIF
|
#define CCIF
|
||||||
#define CLIF
|
#define CLIF
|
||||||
|
|
||||||
#define RIMEADDR_CONF_SIZE 8
|
/* ************************************************************************** */
|
||||||
|
//#pragma mark USB Ethernet Hooks
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06
|
#ifndef USB_ETH_HOOK_IS_READY_FOR_INBOUND_PACKET
|
||||||
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2
|
#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_LL_802154 1
|
||||||
#define UIP_CONF_LLH_LEN 14
|
#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_CONNECTIONS 4
|
||||||
#define UIP_CONF_MAX_LISTENPORTS 4
|
#define UIP_CONF_MAX_LISTENPORTS 4
|
||||||
|
@ -104,15 +178,38 @@
|
||||||
#define UIP_CONF_TCP_SPLIT 1
|
#define UIP_CONF_TCP_SPLIT 1
|
||||||
|
|
||||||
#define UIP_CONF_STATISTICS 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
|
#ifdef RF230BB
|
||||||
#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 //for barebones driver, sicslowpan calls radio->read function
|
#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 //for barebones driver, sicslowpan calls radio->read function
|
||||||
|
|
||||||
|
/* ************************************************************************** */
|
||||||
|
//#pragma mark NETSTACK Settings
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#if 1 /* Network setup */
|
#if 1 /* Network setup */
|
||||||
/* No radio cycling */
|
/* No radio cycling */
|
||||||
#define NETSTACK_CONF_NETWORK sicslowpan_driver
|
#define NETSTACK_CONF_NETWORK sicslowpan_driver
|
||||||
|
@ -158,12 +255,19 @@
|
||||||
#error Network configuration not specified!
|
#error Network configuration not specified!
|
||||||
#endif /* Network setup */
|
#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 */
|
/* 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,
|
/* 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 */
|
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 UIP_CONF_ROUTER 1
|
||||||
#define RPL_CONF_STATS 0
|
#define RPL_CONF_STATS 0
|
||||||
#define PROCESS_CONF_NO_PROCESS_NAMES 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_PINGADDRCONF 0
|
||||||
#define UIP_CONF_LOGGING 0
|
#define UIP_CONF_LOGGING 0
|
||||||
#endif
|
#endif
|
||||||
#endif /* RPL */
|
#endif /* UIP_CONF_IPV6_RPL */
|
||||||
|
|
||||||
|
|
||||||
#endif /* RF230BB */
|
#endif /* RF230BB */
|
||||||
|
|
||||||
|
/* ************************************************************************** */
|
||||||
|
//#pragma mark Other Settings
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
/* Route-Under-MAC uses 16-bit short addresses */
|
/* Route-Under-MAC uses 16-bit short addresses */
|
||||||
#if UIP_CONF_USE_RUM
|
#if UIP_CONF_USE_RUM
|
||||||
#undef UIP_CONF_LL_802154
|
#undef UIP_CONF_LL_802154
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "usb_descriptors.h"
|
#include "usb_descriptors.h"
|
||||||
#include "usb_specific_request.h"
|
#include "usb_specific_request.h"
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
|
#include "bootloader.h"
|
||||||
|
|
||||||
uint8_t checkForFinger(void);
|
uint8_t checkForFinger(void);
|
||||||
|
|
||||||
|
@ -54,6 +55,8 @@ init_lowlevel(void)
|
||||||
Leds_off();
|
Leds_off();
|
||||||
|
|
||||||
if (checkForFinger()) {
|
if (checkForFinger()) {
|
||||||
|
if(bootloader_is_present())
|
||||||
|
Jump_To_Bootloader();
|
||||||
#ifdef WINXPSP2
|
#ifdef WINXPSP2
|
||||||
usb_mode = mass_storage;
|
usb_mode = mass_storage;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -35,36 +35,64 @@
|
||||||
#include "contiki-raven.h"
|
#include "contiki-raven.h"
|
||||||
#if !RF230BB
|
#if !RF230BB
|
||||||
#include "zmac.h"
|
#include "zmac.h"
|
||||||
#else
|
|
||||||
extern uint64_t macLongAddr;
|
|
||||||
#endif
|
#endif
|
||||||
#include "sicslowpan.h"
|
#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
|
void
|
||||||
init_net(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);
|
||||||
/* Set local bit, Clear translate bit, Clear Multicast bit */
|
macLongAddr |= 0x0200000000000000ULL;
|
||||||
macLongAddr &= ~(0x0700000000000000ULL);
|
|
||||||
macLongAddr |= 0x0200000000000000ULL;
|
|
||||||
|
|
||||||
|
|
||||||
/* Set the Ethernet address to the 15.4 MAC address */
|
/* Set the Ethernet address to the 15.4 MAC address */
|
||||||
rndis_ethernet_addr = macLongAddr;
|
usb_ethernet_addr = macLongAddr;
|
||||||
|
|
||||||
/* Remove the middle two bytes... */
|
|
||||||
rndis_ethernet_addr = (rndis_ethernet_addr & 0xffffffUL) | ((rndis_ethernet_addr & 0xffffff0000000000ULL) >> 16);
|
|
||||||
|
|
||||||
/* Change ieee802.15.4 address to correspond with what the ethernet's
|
/* Remove the middle two bytes... */
|
||||||
IPv6 address will be. This will have ff:fe in the middle. */
|
usb_ethernet_addr = (usb_ethernet_addr & 0xffffffUL) | ((usb_ethernet_addr & 0xffffff0000000000ULL) >> 16);
|
||||||
macLongAddr = (macLongAddr & 0xffffff0000ffffffULL) | (0x000000fffe000000ULL);
|
|
||||||
|
/* 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
|
#if !RF230BB
|
||||||
ieee15_4ManagerAddress.set_long_addr(macLongAddr);
|
ieee15_4ManagerAddress.set_long_addr(macLongAddr);
|
||||||
#endif
|
#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/pgmspace.h>
|
||||||
#include <avr/fuse.h>
|
#include <avr/fuse.h>
|
||||||
#include <avr/eeprom.h>
|
#include <avr/eeprom.h>
|
||||||
|
#include <avr/wdt.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -68,7 +69,7 @@
|
||||||
|
|
||||||
#include "usb_task.h"
|
#include "usb_task.h"
|
||||||
#if USB_CONF_CDC
|
#if USB_CONF_CDC
|
||||||
#include "serial/cdc_task.h"
|
#include "cdc_task.h"
|
||||||
#elif USB_CONF_RS232
|
#elif USB_CONF_RS232
|
||||||
#include "dev/rs232.h"
|
#include "dev/rs232.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -78,13 +79,21 @@
|
||||||
#include "storage/storage_task.h"
|
#include "storage/storage_task.h"
|
||||||
#endif
|
#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
|
#if RF230BB //radio driver using contiki core mac
|
||||||
#include "radio/rf230bb/rf230bb.h"
|
#include "radio/rf230bb/rf230bb.h"
|
||||||
#include "net/mac/frame802154.h"
|
#include "net/mac/frame802154.h"
|
||||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||||
extern int rf230_interrupt_flag;
|
extern int rf230_interrupt_flag;
|
||||||
extern uint8_t rf230processflag;
|
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
|
#else //legacy radio driver using Atmel/Cisco 802.15.4'ish MAC
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "mac.h"
|
#include "mac.h"
|
||||||
|
@ -194,20 +203,101 @@ SIGNATURE = {
|
||||||
FUSES ={.low = 0xde, .high = 0x99, .extended = 0xff,};
|
FUSES ={.low = 0xde, .high = 0x99, .extended = 0xff,};
|
||||||
|
|
||||||
/* Put default MAC address in EEPROM */
|
/* 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 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
|
#endif
|
||||||
//uint8_t EEMEM server_name[16];
|
|
||||||
//uint8_t EEMEM domain_name[30];
|
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--------------------*/
|
/*-----------------------------Low level initialization--------------------*/
|
||||||
static void initialize(void) {
|
static void initialize(void) {
|
||||||
|
watchdog_init();
|
||||||
|
watchdog_start();
|
||||||
|
|
||||||
/* Initialize hardware */
|
/* Initialize hardware */
|
||||||
// Currently only used for finger detection for mass storage mode
|
// Checks for "finger", jumps to DFU if present.
|
||||||
#if USB_CONF_STORAGE
|
|
||||||
init_lowlevel();
|
init_lowlevel();
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Clock */
|
/* Clock */
|
||||||
clock_init();
|
clock_init();
|
||||||
|
@ -221,7 +311,9 @@ static void initialize(void) {
|
||||||
printf_P(PSTR("\n\n\n********BOOTING CONTIKI*********\n"));
|
printf_P(PSTR("\n\n\n********BOOTING CONTIKI*********\n"));
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Leds_init();
|
||||||
|
|
||||||
/* rtimer init needed for low power protocols */
|
/* rtimer init needed for low power protocols */
|
||||||
rtimer_init();
|
rtimer_init();
|
||||||
|
|
||||||
|
@ -239,26 +331,52 @@ static void initialize(void) {
|
||||||
|
|
||||||
/* Set addresses BEFORE starting tcpip process */
|
/* Set addresses BEFORE starting tcpip process */
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(rimeaddr_t));
|
memset(&tmp_addr, 0, sizeof(rimeaddr_t));
|
||||||
AVR_ENTER_CRITICAL_REGION();
|
if(!get_eui64_from_eeprom(tmp_addr.u8)) {
|
||||||
eeprom_read_block ((void *)&addr.u8, &mac_address, 8);
|
#if JACKDAW_CONF_RANDOM_MAC
|
||||||
AVR_LEAVE_CRITICAL_REGION();
|
// It doesn't look like we have a valid EUI-64 address
|
||||||
//RNDIS needs the mac address in reverse byte order
|
// so let's try to make a new one from scratch.
|
||||||
macLongAddr.u8[0]=addr.u8[7];
|
Leds_off();
|
||||||
macLongAddr.u8[1]=addr.u8[6];
|
Led2_on();
|
||||||
macLongAddr.u8[2]=addr.u8[5];
|
generate_new_eui64(tmp_addr.u8);
|
||||||
macLongAddr.u8[3]=addr.u8[4];
|
if(!set_eui64_to_eeprom(tmp_addr.u8)) {
|
||||||
macLongAddr.u8[4]=addr.u8[3];
|
watchdog_periodic();
|
||||||
macLongAddr.u8[5]=addr.u8[2];
|
int i;
|
||||||
macLongAddr.u8[6]=addr.u8[1];
|
for(i=0;i<20;i++) {
|
||||||
macLongAddr.u8[7]=addr.u8[0];
|
Led1_toggle();
|
||||||
|
_delay_ms(100);
|
||||||
memcpy(&uip_lladdr.addr, &addr.u8, 8);
|
}
|
||||||
rf230_set_pan_addr(IEEE802154_PANID, 0, (uint8_t *)&addr.u8);
|
Led1_off();
|
||||||
rf230_set_channel(26);
|
}
|
||||||
|
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);
|
//Fix MAC address
|
||||||
// set_rime_addr();
|
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 */
|
/* Initialize stack protocols */
|
||||||
queuebuf_init();
|
queuebuf_init();
|
||||||
|
@ -266,8 +384,10 @@ static void initialize(void) {
|
||||||
NETSTACK_MAC.init();
|
NETSTACK_MAC.init();
|
||||||
NETSTACK_NETWORK.init();
|
NETSTACK_NETWORK.init();
|
||||||
|
|
||||||
|
rf230_set_channel(get_channel_from_eeprom());
|
||||||
|
|
||||||
#if ANNOUNCE && USB_CONF_RS232
|
#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());
|
printf_P(PSTR("%s %s, channel %u"),NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
|
||||||
if (NETSTACK_RDC.channel_check_interval) {
|
if (NETSTACK_RDC.channel_check_interval) {
|
||||||
unsigned short tmp;
|
unsigned short tmp;
|
||||||
|
@ -305,13 +425,10 @@ static void initialize(void) {
|
||||||
#if USB_CONF_CDC
|
#if USB_CONF_CDC
|
||||||
process_start(&cdc_process, NULL);
|
process_start(&cdc_process, NULL);
|
||||||
#endif
|
#endif
|
||||||
process_start(&rndis_process, NULL);
|
process_start(&usb_eth_process, NULL);
|
||||||
#if USB_CONF_STORAGE
|
#if USB_CONF_STORAGE
|
||||||
process_start(&storage_process, NULL);
|
process_start(&storage_process, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Fix MAC address
|
|
||||||
init_net();
|
|
||||||
|
|
||||||
#if ANNOUNCE
|
#if ANNOUNCE
|
||||||
#if USB_CONF_CDC
|
#if USB_CONF_CDC
|
||||||
|
@ -320,7 +437,7 @@ static void initialize(void) {
|
||||||
/* Allow USB CDC to keep up with printfs */
|
/* Allow USB CDC to keep up with printfs */
|
||||||
for (i=0;i<8000;i++) process_run();
|
for (i=0;i<8000;i++) process_run();
|
||||||
#if RF230BB
|
#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();
|
for (i=0;i<8000;i++) process_run();
|
||||||
printf_P(PSTR("%s %s, channel %u"),NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
|
printf_P(PSTR("%s %s, channel %u"),NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
|
||||||
if (NETSTACK_RDC.channel_check_interval) {
|
if (NETSTACK_RDC.channel_check_interval) {
|
||||||
|
@ -359,6 +476,8 @@ main(void)
|
||||||
while(1) {
|
while(1) {
|
||||||
process_run();
|
process_run();
|
||||||
|
|
||||||
|
watchdog_periodic();
|
||||||
|
|
||||||
#if TESTRTIMER
|
#if TESTRTIMER
|
||||||
if (rtimerflag) { //8 seconds is maximum interval, my jackdaw 4% slow
|
if (rtimerflag) { //8 seconds is maximum interval, my jackdaw 4% slow
|
||||||
rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
|
rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
|
||||||
|
|
|
@ -45,8 +45,6 @@
|
||||||
|
|
||||||
// LED's for Raven USB
|
// LED's for Raven USB
|
||||||
#define Leds_init() (DDRD |= 0xA0, DDRE |= 0xC0)
|
#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 Led0_on() (PORTD |= 0x80)
|
||||||
#define Led1_on() (PORTD &= ~0x20)
|
#define Led1_on() (PORTD &= ~0x20)
|
||||||
#define Led2_on() (PORTE &= ~0x80)
|
#define Led2_on() (PORTE &= ~0x80)
|
||||||
|
@ -59,6 +57,8 @@
|
||||||
#define Led1_toggle() (PIND |= 0x20)
|
#define Led1_toggle() (PIND |= 0x20)
|
||||||
#define Led2_toggle() (PINE |= 0x80)
|
#define Led2_toggle() (PINE |= 0x80)
|
||||||
#define Led3_toggle() (PINE |= 0x40)
|
#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);
|
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: 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!
|
//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
|
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||||
/**
|
/**
|
||||||
|
@ -255,12 +257,10 @@
|
||||||
#define MSB(u16) (((uint8_t *)&(u16))[1]) //!< Most significant byte of \a u16.
|
#define MSB(u16) (((uint8_t *)&(u16))[1]) //!< Most significant byte of \a u16.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
static const uint64_t simple_trans_ethernet_addr = 0x3E3D3C3B3AF2ULL;
|
||||||
#define rndis_ethernet_addr local_ethernet_addr
|
extern uint64_t usb_ethernet_addr;
|
||||||
static uint64_t local_ethernet_addr = 0x3A3B3C3D3E3FULL;
|
|
||||||
#else
|
extern uint64_t macLongAddr;
|
||||||
extern uint64_t rndis_ethernet_addr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !RF230BB
|
#if !RF230BB
|
||||||
extern void (*pinput)(const struct mac_driver *r);
|
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_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan);
|
||||||
uint8_t mac_createEthernetAddr(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 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_nondata(const struct mac_driver *r);
|
||||||
void mac_ethhijack(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 */
|
/* 6lowpan max size + ethernet header size + 1 */
|
||||||
uint8_t raw_buf[127+ UIP_LLH_LEN +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
|
* \brief Perform any setup needed
|
||||||
*/
|
*/
|
||||||
|
@ -340,26 +327,27 @@ void mac_ethernetToLowpan(uint8_t * ethHeader)
|
||||||
uip_lladdr_t destAddr;
|
uip_lladdr_t destAddr;
|
||||||
uip_lladdr_t *destAddrPtr = NULL;
|
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
|
//RUM doesn't support sending data
|
||||||
#if UIP_CONF_USE_RUM
|
#if UIP_CONF_USE_RUM
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//If not IPv6 we don't do anything
|
// In sniffer mode we don't ever send anything
|
||||||
if (((struct uip_eth_hdr *) ethHeader)->type != HTONS(UIP_ETHTYPE_IPV6)) {
|
if (usbstick_mode.sendToRf == 0) {
|
||||||
PRINTF("eth2low: Packet is not IPv6, dropping\n\r");
|
|
||||||
// printf("!ipv6");
|
|
||||||
#if !RF230BB
|
|
||||||
rndis_stat.txbad++;
|
|
||||||
#endif
|
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
return;
|
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;
|
uip_len = 0;
|
||||||
return;
|
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[4] == 0xFF) &&
|
||||||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[5] == 0xFF) ) {
|
(((struct uip_eth_hdr *) ethHeader)->dest.addr[5] == 0xFF) ) {
|
||||||
/* IPv6 does not use broadcast addresses, hence this should not happen */
|
/* 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
|
#if !RF230BB
|
||||||
rndis_stat.txbad++;
|
usb_eth_stat.txbad++;
|
||||||
#endif
|
#endif
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
/* Simple Address Translation */
|
||||||
/* Simple Address Translation */
|
if(memcmp((uint8_t *)&simple_trans_ethernet_addr, &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), 6) == 0) {
|
||||||
#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
|
|
||||||
//Addressed to us: make 802.15.4 address from IPv6 Address
|
//Addressed to us: make 802.15.4 address from IPv6 Address
|
||||||
destAddr.addr[0] = UIP_IP_BUF->destipaddr.u8[8] ^ 0x02;
|
destAddr.addr[0] = UIP_IP_BUF->destipaddr.u8[8] ^ 0x02;
|
||||||
destAddr.addr[1] = UIP_IP_BUF->destipaddr.u8[9];
|
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];
|
destAddr.addr[7] = UIP_IP_BUF->destipaddr.u8[15];
|
||||||
|
|
||||||
destAddrPtr = &destAddr;
|
destAddrPtr = &destAddr;
|
||||||
} else {
|
}
|
||||||
|
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||||
|
else {
|
||||||
//Not addressed to us
|
//Not addressed to us
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
/* Complex Address Translation */
|
/* Complex Address Translation */
|
||||||
#else
|
|
||||||
PRINTF("eth2low: Addressed packet received... ");
|
PRINTF("eth2low: Addressed packet received... ");
|
||||||
//Check this returns OK
|
//Check this returns OK
|
||||||
if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) {
|
if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) {
|
||||||
PRINTF(" translation failed\n\r");
|
PRINTF(" translation failed\n\r");
|
||||||
#if !RF230BB
|
#if !RF230BB
|
||||||
rndis_stat.txbad++;
|
usb_eth_stat.txbad++;
|
||||||
#endif
|
#endif
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
return;
|
return;
|
||||||
|
@ -441,13 +426,11 @@ void mac_ethernetToLowpan(uint8_t * ethHeader)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usbstick_mode.sendToRf){
|
tcpip_output(destAddrPtr);
|
||||||
tcpip_output(destAddrPtr);
|
|
||||||
#if !RF230BB
|
#if !RF230BB
|
||||||
rndis_stat.txok++;
|
usb_eth_stat.txok++;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -488,13 +471,16 @@ void mac_LowpanToEthernet(void)
|
||||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
#if !UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||||
mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]));
|
|
||||||
#else
|
|
||||||
//Source ethernet depends on node
|
//Source ethernet depends on node
|
||||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]),
|
if(!mac_createEthernetAddr(
|
||||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
(uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]),
|
||||||
|
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)
|
||||||
|
))
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]));
|
||||||
|
}
|
||||||
|
|
||||||
//We only do address translation in network mode!
|
//We only do address translation in network mode!
|
||||||
if (usbstick_mode.translate) {
|
if (usbstick_mode.translate) {
|
||||||
|
@ -508,7 +494,7 @@ void mac_LowpanToEthernet(void)
|
||||||
|
|
||||||
usb_eth_send(uip_buf, uip_len, 1);
|
usb_eth_send(uip_buf, uip_len, 1);
|
||||||
#if !RF230BB
|
#if !RF230BB
|
||||||
rndis_stat.rxok++;
|
usb_eth_stat.rxok++;
|
||||||
#endif
|
#endif
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
}
|
}
|
||||||
|
@ -653,13 +639,10 @@ int8_t mac_translateIcmpLinkLayer(lltype_t target)
|
||||||
// printf("createsicslowpanlongaddr");
|
// printf("createsicslowpanlongaddr");
|
||||||
mac_createSicslowpanLongAddr(llbuf, (uip_lladdr_t *)UIP_ICMP_OPTS(icmp_opt_offset)->data);
|
mac_createSicslowpanLongAddr(llbuf, (uip_lladdr_t *)UIP_ICMP_OPTS(icmp_opt_offset)->data);
|
||||||
} else {
|
} else {
|
||||||
if (UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS) {
|
#if !UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
||||||
//Simple address translation always sets this as default
|
if(!mac_createEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data, (uip_lladdr_t *)llbuf))
|
||||||
|
#endif
|
||||||
mac_createDefaultEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data);
|
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
|
//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)
|
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
|
#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;
|
uint8_t index;
|
||||||
|
|
||||||
#if UIP_LLADDR_LEN == 8
|
#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
|
//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
|
//Get top bits
|
||||||
index = ethernet[0] >> 3;
|
index = ethernet[0] >> 3;
|
||||||
|
|
||||||
//Check this is plausible...
|
|
||||||
if (index >= prefixCounter) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Copy over prefix
|
//Copy over prefix
|
||||||
lowpan->addr[0] = prefixBuffer[index][0];
|
lowpan->addr[0] = prefixBuffer[index][0];
|
||||||
lowpan->addr[3] = prefixBuffer[index][1];
|
lowpan->addr[1] = prefixBuffer[index][1];
|
||||||
lowpan->addr[4] = prefixBuffer[index][2];
|
lowpan->addr[2] = prefixBuffer[index][2];
|
||||||
|
lowpan->addr[3] = ethernet[1];
|
||||||
//Bit is clear
|
lowpan->addr[4] = ethernet[2];
|
||||||
//so we copy all six
|
|
||||||
|
//Check this is plausible...
|
||||||
|
if (index >= prefixCounter)
|
||||||
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
// printf("here3");
|
|
||||||
lowpan->addr[0] = ethernet[0];
|
lowpan->addr[0] = ethernet[0];
|
||||||
|
lowpan->addr[1] = ethernet[1];
|
||||||
|
lowpan->addr[2] = ethernet[2];
|
||||||
lowpan->addr[3] = 0xff;
|
lowpan->addr[3] = 0xff;
|
||||||
lowpan->addr[4] = 0xfe;
|
lowpan->addr[4] = 0xfe;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Copy over reamining five bytes
|
lowpan->addr[5] = ethernet[3];
|
||||||
lowpan->addr[1] = ethernet[1];
|
lowpan->addr[6] = ethernet[4];
|
||||||
lowpan->addr[2] = ethernet[2];
|
lowpan->addr[7] = ethernet[5];
|
||||||
lowpan->addr[5] = ethernet[3];
|
|
||||||
lowpan->addr[6] = ethernet[4];
|
|
||||||
lowpan->addr[7] = ethernet[5];
|
|
||||||
|
|
||||||
#else //UIP_LLADDR != 8
|
#else //UIP_LLADDR != 8
|
||||||
|
// Not sure when we would ever hit this case...
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
// printf("here4");
|
|
||||||
for(i = 0; i < UIP_LLADDR_LEN; i++) {
|
for(i = 0; i < UIP_LLADDR_LEN; i++) {
|
||||||
lowpan->addr[i] = ethernet[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)
|
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
|
#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
|
#if UIP_LLADDR_LEN == 8
|
||||||
|
|
||||||
//Special case - if the address is our address, we just copy over what we know to be
|
//Check if we need to do anything:
|
||||||
//our 802.3 address
|
if ((lowpan->addr[3] == 0xff) && (lowpan->addr[4] == 0xfe) &&
|
||||||
#if RF230BB
|
((lowpan->addr[0] & TRANSLATE_BIT_MASK) == 0) &&
|
||||||
if (memcmp(uip_lladdr.addr, (uint8_t *)lowpan, 8) == 0) {
|
((lowpan->addr[0] & MULTICAST_BIT_MASK) == 0) &&
|
||||||
memcpy(ethernet, &uip_lladdr.addr[2], 6);
|
(lowpan->addr[0] & LOCAL_BIT_MASK)) {
|
||||||
#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)) {
|
|
||||||
|
|
||||||
/** Nope: just copy over 6 bytes **/
|
/** Nope: just copy over 6 bytes **/
|
||||||
ethernet[0] = lowpan->addr[0];
|
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 **/
|
/** Yes: need to store prefix **/
|
||||||
for (i = 0; i < prefixCounter; i++) {
|
for (i = 0; i < prefixCounter; i++) {
|
||||||
//Check the current prefix - if it fails, check next one
|
//Check the current prefix - if it fails, check next one
|
||||||
|
if ((lowpan->addr[0] == prefixBuffer[i][0]) &&
|
||||||
|
(lowpan->addr[1] == prefixBuffer[i][1]) &&
|
||||||
|
(lowpan->addr[2] == prefixBuffer[i][2])) {
|
||||||
if ((lowpan->addr[0] == prefixBuffer[i][0]) &&
|
break;
|
||||||
(lowpan->addr[3] == prefixBuffer[i][1]) &&
|
}
|
||||||
(lowpan->addr[4] == prefixBuffer[i][2])) {
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
index = i;
|
index = i;
|
||||||
|
|
||||||
//Deal with overflow, iron-fist style
|
if (index >= PREFIX_BUFFER_SIZE) {
|
||||||
if (index >= PREFIX_BUFFER_SIZE) {
|
// Overflow. Fall back to simple translation.
|
||||||
index = 0;
|
// TODO: Implement me!
|
||||||
prefixCounter = PREFIX_BUFFER_SIZE;
|
ethernet[0] = lowpan->addr[0];
|
||||||
} else {
|
ethernet[1] = lowpan->addr[1];
|
||||||
//Are we making a new one?
|
ethernet[2] = lowpan->addr[2];
|
||||||
if (index == prefixCounter) {
|
ethernet[3] = lowpan->addr[5];
|
||||||
prefixCounter++;
|
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
|
//Create ethernet MAC address now
|
||||||
prefixBuffer[index][0] = lowpan->addr[0];
|
ethernet[0] = TRANSLATE_BIT_MASK | LOCAL_BIT_MASK | (index << 3);
|
||||||
prefixBuffer[index][1] = lowpan->addr[3];
|
ethernet[1] = lowpan->addr[3];
|
||||||
prefixBuffer[index][2] = lowpan->addr[4];
|
ethernet[2] = lowpan->addr[4];
|
||||||
|
ethernet[3] = lowpan->addr[5];
|
||||||
//Create ethernet MAC address now
|
ethernet[4] = lowpan->addr[6];
|
||||||
ethernet[1] = lowpan->addr[1];
|
ethernet[5] = lowpan->addr[7];
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else //UIP_LLADDR_LEN != 8
|
#else //UIP_LLADDR_LEN != 8
|
||||||
|
// Not sure when we would ever hit this case...
|
||||||
//Create ethernet MAC address now
|
//Create ethernet MAC address now
|
||||||
for(i = 0; i < UIP_LLADDR_LEN; i++) {
|
for(i = 0; i < UIP_LLADDR_LEN; i++) {
|
||||||
ethernet[i] = lowpan->addr[i];
|
ethernet[i] = lowpan->addr[i];
|
||||||
|
@ -906,20 +868,15 @@ uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
|
|
||||||
/**
|
/**
|
||||||
* \brief Create a 802.3 address (default)
|
* \brief Create a 802.3 address (default)
|
||||||
* \param ethernet Pointer to ethernet address
|
* \param ethernet Pointer to ethernet address
|
||||||
*/
|
*/
|
||||||
uint8_t mac_createDefaultEthernetAddr(uint8_t * ethernet)
|
uint8_t mac_createDefaultEthernetAddr(uint8_t * ethernet)
|
||||||
{
|
{
|
||||||
memcpy(ethernet, &rndis_ethernet_addr, 6);
|
memcpy(ethernet, &simple_trans_ethernet_addr, 6);
|
||||||
#if !RF230BB
|
|
||||||
byte_reverse(ethernet, 6);
|
|
||||||
#endif
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
/**
|
/**
|
||||||
* \brief Slide the pointed to memory up a certain amount,
|
* \brief Slide the pointed to memory up a certain amount,
|
||||||
* growing/shrinking a buffer
|
* 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
|
#if !RF230BB
|
||||||
/*--------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------*/
|
||||||
/** \brief Process a received 6lowpan packet. Hijack function.
|
/** \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)
|
void mac_logTXtoEthernet(frame_create_params_t *p,frame_result_t *frame_result)
|
||||||
{
|
{
|
||||||
uint8_t sendlen;
|
mac_log_802_15_4_tx(frame_result->frame, frame_result->length);
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
* The 6lowpan packet is put in packetbuf by the MAC. This routine passes
|
||||||
* it directly to the ethernet layer without decompressing.
|
* it directly to the ethernet layer without decompressing.
|
||||||
*/
|
*/
|
||||||
void mac_802154raw(const struct mac_driver *r)
|
void mac_802154raw(const struct mac_driver *r) {
|
||||||
{
|
mac_log_802_15_4_tx(radio_frame_data(), radio_frame_length());
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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 */
|
#endif /* !RF230BB */
|
||||||
/** @} */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
Loading…
Reference in a new issue