From a634709c00c40a4e91f71cd2615135b9631dd74b Mon Sep 17 00:00:00 2001 From: Ludwig Ortmann Date: Wed, 26 Jun 2013 23:29:09 +0200 Subject: [PATCH 1/2] native cc1100x_ng network not properly passing received data to transceiver atm --- cpu/native/Makefile | 2 +- cpu/native/README | 26 + cpu/native/cc110x_ng/cc1100-sim.c | 756 ++++++++++++++++++++ cpu/native/cc110x_ng/cc110x_ng_cpu.c | 64 +- cpu/native/hwtimer_cpu.c | 4 +- cpu/native/include/cc1100sim.h | 39 + cpu/native/include/cpu-conf.h | 10 +- cpu/native/include/cpu.h | 7 + cpu/native/include/tap.h | 29 + cpu/native/irq_cpu.c | 27 +- cpu/native/lpm_cpu.c | 11 +- cpu/native/native_cpu.c | 4 + cpu/native/startup.c | 18 +- cpu/native/tap.c | 235 ++++++ cpu/native/tapsetup-osx.sh | 47 ++ cpu/native/tapsetup.sh | 50 ++ drivers/cc110x_ng/include/cc110x-internal.h | 2 +- 17 files changed, 1281 insertions(+), 50 deletions(-) create mode 100644 cpu/native/README create mode 100644 cpu/native/cc110x_ng/cc1100-sim.c create mode 100644 cpu/native/include/cc1100sim.h create mode 100644 cpu/native/include/tap.h create mode 100644 cpu/native/tap.c create mode 100755 cpu/native/tapsetup-osx.sh create mode 100755 cpu/native/tapsetup.sh diff --git a/cpu/native/Makefile b/cpu/native/Makefile index 4b642a35e106..34ae69f430e1 100644 --- a/cpu/native/Makefile +++ b/cpu/native/Makefile @@ -1,6 +1,6 @@ MODULE = cpu -INCLUDES = -I../include -I$(RIOTBASE)/core/include +INCLUDES = -I../include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/cc110x_ng/include DIRS = ifneq (,$(findstring rtc,$(USEMODULE))) DIRS += rtc diff --git a/cpu/native/README b/cpu/native/README new file mode 100644 index 000000000000..ccd8cd1136e8 --- /dev/null +++ b/cpu/native/README @@ -0,0 +1,26 @@ +If you compile RIOT for the native cpu and include the cc110x_ng +module, you need to specify a network interface like this: +./bin/default-native.elf tap0 + + +SETTING UP A TAP NETWORK +======================== + +There is a shellscript in RIOT/cpu/native called tapsetup.sh which you +can use to create a network of tap interfaces. + +Usage: +To create a bridge and two (or count at your option) tap interfaces: +./tapsetup.sh create [count] +To delete the bridge and all tap interfaces: +./tapsetup.sh delete + + +OSX +=== + +For tun/tap networking in OSX you will need: +http://tuntaposx.sourceforge.net/ + +For OSX there is a seperate script called tapsetup-osx.sh. Usage is +just like the other one. diff --git a/cpu/native/cc110x_ng/cc1100-sim.c b/cpu/native/cc110x_ng/cc1100-sim.c new file mode 100644 index 000000000000..3644e0ab09d1 --- /dev/null +++ b/cpu/native/cc110x_ng/cc1100-sim.c @@ -0,0 +1,756 @@ +#include +#include +#include +#include +#include + +#include "debug.h" + +#include "cc110x_ng.h" +#include "cc110x-internal.h" /* CC1100_READ_BURST etc. */ +#include "tap.h" +#include "cc1100sim.h" + +#define CC1100_EVENT_SET_POWER 0x01 +#define CC1100_EVENT_SET_CHANNEL 0x02 + +/** + * simplified states according to cc1100.pdf figure 5, page 23 + */ +#define STATE_IDLE 0x00 +/* SPWD || WOR -> STATE_SLEEP + * SXOFF -> STATE_XTALOFF + * SCAL -> STATE_FREQ_SCAL + * SRX || STX || WOR -> STATE_FREQ_SST */ +#define STATE_SLEEP 0x01 /* CSn=0 -> STATE_IDLE */ +#define STATE_XTALOFF 0x02 /* CSn=0 -> STATE_IDLE */ +#define STATE_FREQ_SCAL 0x03 /* -> STATE_IDLE */ + +#define STATE_FREQ_SST 0x04 +/* SFSTXON -> STATE_FREQ_SON + * STX -> STATE_TX + * SRX||WOR -> STATE_RX */ +#define STATE_FREQ_SON 0x05 /* STX -> STATE_TX */ +#define STATE_TX 0x06 +/* TXOFF_MODE = 11 || SRX -> STATE_RX + * TXOFF_MODE = 01 -> STATE_FREQ_SON + * STATE_TX_FFUF */ +#define STATE_TX_FFUF 0x07 /* SFTX -> STATE_IDLE */ +#define STATE_RX 0x08 +/* RXOFF_MODE = 10 || STX -> STATE_TX + * RXOFF_MODE = 00 -> STATE_FREQ_SON + * -> STATE_TX_FFUF */ +#define STATE_RX_FFOF 0x09 /* SFRX -> STATE_IDLE */ + + +/** + * status byte state bits according to cc1100.pdf, page 26, table 17 + */ +#define M_IDLE 0x00 +#define M_RX 0x10 +#define M_TX 0x20 +#define M_FSTXON 0x30 +#define M_CALIBRATE 0x40 +#define M_SETTLING 0x50 +#define M_RXFIFO_OVERFLOW 0x60 +#define M_TXFIFO_UNDERFLOW 0x70 + +#define MASK_STATE 0x70 +#define MASK_CHIP_RDYn 0x80 +#define MASK_FIFO_BYTES_AVAILABLE 0x0F + +#if 0 +static uint8_t internal_state; /* according to table 17 */ +static uint8_t _native_cc1100_spi; /* the pins */ +/* one byte goes in, one byte goes out */ +static uint8_t _native_cc1100_serial_io; +#endif + +uint8_t addr; /* as sent in header */ +uint8_t _native_cc110x_state; + + +uint8_t configuration_registers[((0x2E)+1)]; /* address 0x00 - 0x2E */ +uint8_t configuration_registers_idx; /* for burst access */ +uint8_t status_registers[((0x3D-0x30)+1)]; /* address 0x30 - 0x3D */ +/* command strobes reside at the addresses 0x30 to 0x3D when writing */ +uint8_t patable[8]; /* address 0x3E */ +uint8_t patable_idx; /* for burst access */ + +uint8_t tx_fifo[64]; +uint8_t tx_fifo_idx; +uint8_t rx_fifo[64]; +uint8_t rx_fifo_idx; + +int native_cc110x_gd0; +int native_cc110x_gd1; +int native_cc110x_gd2; +int native_cc110x_gd0_enabled; +int native_cc110x_gd2_enabled; + +/* static uint8_t address_space[0xFF]; */ +/* static uint8_t address_space_pointer; */ + +/* network layer handlers for cc1100 events: */ +struct cc1100_callback_t { + void (*func)(void); +}; +static struct cc1100_callback_t _native_cc1100_callbacks[255]; + +/* cc1100 default configuration */ +unsigned char cc1100_reset_configuration_regs[] = { + 0x29, /* IOCFG2 */ + 0x2E, /* IOCFG1 */ + 0x3F, /* IOCFG0 */ + 0x07, /* FIFOTHR */ + 0xD3, /* SYNC1 */ + 0x91, /* SYNC0 */ + 0xFF, /* PKTLEN */ + 0x04, /* PKTCTRL1 */ + 0x45, /* PKTCTRL0 */ + 0x00, /* ADDR */ + 0x00, /* CHANNR */ + 0x0F, /* FSCTRL1 */ + 0x00, /* FSCTRL0 */ + 0x1E, /* FREQ2 */ + 0xC4, /* FREQ1 */ + 0xEC, /* FREQ0 */ + 0x2C, /* MDMCFG4 */ + 0x22, /* MDMCFG3 */ + 0x02, /* MDMCFG2 */ + 0x22, /* MDMCFG1 */ + 0xF8, /* MDMCFG0 */ + 0x47, /* DEVIATN */ + 0x07, /* MCSM2 */ + 0x30, /* MCSM1 */ + 0x04, /* MCSM0 */ + 0x66, /* FOCCFG */ + 0x66, /* BSCFG */ + 0x03, /* AGCCTRL2 */ + 0x40, /* AGCCTRL1 */ + 0x91, /* AGCCTRL0 */ + 0x87, /* WOREVT1 */ + 0x6B, /* WOREVT0 */ + 0xF8, /* WORCTRL */ + 0x56, /* FREND1 */ + 0x10, /* FREND0 */ + 0xA9, /* FSCAL3 */ + 0x0A, /* FSCAL2 */ + 0x20, /* FSCAL1 */ + 0x0D, /* FSCAL0 */ + 0x41, /* RCCTRL1 */ + 0x00, /* RCCTRL0 */ + 0x59, /* FSTEST */ + 0x7F, /* PTEST */ + 0x3F, /* AGCTEST */ + 0x88, /* TEST2 */ + 0x31, /* TEST1 */ + 0x0B /* TEST0 */ +}; + +/* cc1100 default status */ +unsigned char cc1100_reset_status_regs[] = { + 0x00, /* PARTNUM */ + 0x03, /* VERSION */ + 0x00, /* FREQEST */ + 0x00, /* LQI */ + 0x00, /* RSSI */ + 0x00, /* MARCSTATE */ + 0x00, /* WORTIME1 */ + 0x00, /* WORTIME0 */ + 0x00, /* PKTSTATUS */ + 0x00, /* VCO_VC_DAC */ + 0x00, /* TXBYTES */ + 0x00, /* RXBYTES */ + 0x00, /* RCCTRL1_STATUS */ + 0x00 /* RCCTRL0_STATUS */ +}; + +void do_sres(void) +{ + int i; + + for (i = 0; i < 0x2E; i++) { + configuration_registers[i] = cc1100_reset_configuration_regs[i]; + } + for (i = 0; i < (0x3D - 0x30); i++) { + status_registers[i] = cc1100_reset_status_regs[i]; + } + for (i = 1; i < 8; i++) { + patable[i] = 0; + } +} + +uint8_t do_strobe(void) +{ + DEBUG("issue strobe command\n"); + switch (addr) { + case CC1100_SRES: + do_sres(); + break; + case CC1100_SFSTXON: + //warnx("do_strobe: not implemented: CC1100_SFSTXON"); + break; + case CC1100_SXOFF: + //warnx("do_strobe: not implemented: CC1100_SXOFF"); + break; + case CC1100_SCAL: + //warnx("do_strobe: not implemented: CC1100_SCAL"); + break; + case CC1100_SRX: + //warnx("do_strobe: not implemented: CC1100_SRX"); + break; + case CC1100_STX: + //warnx("do_strobe: not properly implemented: CC1100_STX"); + if (((status_registers[CC1100_TXBYTES - 0x30] & 0x7F) > 0) && (send_buf() == -1)) { + native_cc110x_gd2 = 1; + } + else { + native_cc110x_gd2 = 1; + } + break; + case CC1100_SIDLE: + //warnx("do_strobe: not implemented: CC1100_SIDLE "); + break; + case CC1100_SAFC: + //warnx("do_strobe: not implemented: CC1100_SAFC"); + break; + case CC1100_SWOR: + //warnx("do_strobe: not implemented: CC1100_SWOR"); + break; + case CC1100_SPWD: + //warnx("do_strobe: not implemented: CC1100_SPWD"); + break; + case CC1100_SFRX: + status_registers[CC1100_RXBYTES - 0x30] = 0x00; + rx_fifo_idx = 0x00; + break; + case CC1100_SFTX: + status_registers[CC1100_TXBYTES - 0x30] = 0x00; + tx_fifo_idx = 0x00; + break; + case CC1100_SWORRST: + //warnx("do_strobe: not implemented: CC1100_SWORRST"); + break; + case CC1100_SNOP: + //warnx("do_strobe: not implemented: CC1100_SNOP"); + break; + default: + errx(EXIT_FAILURE, "do_strobe: internal error"); + } + return addr; +} + +uint8_t parse_header(uint8_t c) +{ + DEBUG("parse_header(0x%02X): ", c); + + addr = c & 0x3F; /* bits [5..0] */ + uint8_t mode = c & 0xC0; /* bits [76]*/ + + /* set access mode, set status bute (c) */ + switch (mode) { + case CC1100_READ_BURST: + /* status registers can only be read single */ + if ((addr >= 0x30) && (addr <= 0x3D)) { + DEBUG(" CC1100_READ_SINGLE"); + _native_cc110x_state = STATE_READ_S; + } + else { + DEBUG(" CC1100_READ_BURST"); + _native_cc110x_state = STATE_READ_B; + } + c = status_registers[CC1100_RXBYTES - 0x30] - rx_fifo_idx; + break; + case CC1100_WRITE_BURST: + DEBUG(" CC1100_WRITE_BURST"); + _native_cc110x_state = STATE_WRITE_B; + c = 0x0F - status_registers[CC1100_TXBYTES - 0x30]; + break; + case CC1100_READ_SINGLE: + DEBUG(" CC1100_READ_SINGLE"); + _native_cc110x_state = STATE_READ_S; + c = status_registers[CC1100_RXBYTES - 0x30] - rx_fifo_idx; + break; + default: + DEBUG(" CC1100_WRITE_SINGLE"); + _native_cc110x_state = STATE_WRITE_S; + c = 0x0F - status_registers[CC1100_TXBYTES - 0x30]; + } + if (addr <= 0x2E) { + DEBUG(" configuration register"); + } + else if ((addr >= 0x30) && (addr <= 0x3D)) { + if ((_native_cc110x_state == STATE_WRITE_B) || (_native_cc110x_state == STATE_WRITE_S)) { + DEBUG(" strobe command"); + /* strobe commands get executed directly */ + do_strobe(); + } + else { + DEBUG(" status register"); + } + } + else if (addr == 0x3E) { + DEBUG(" patable"); + } + else if (addr == 0x3F) { + if ((_native_cc110x_state == STATE_WRITE_B) || (_native_cc110x_state == STATE_WRITE_S)) { + DEBUG(" TX"); + } + else { + DEBUG(" RX"); + } + } + else { + errx(EXIT_FAILURE, "parse_header: unhandled addr: 0x%02X", addr); + } + DEBUG("==\n"); + + return c; +} + +uint8_t read_single(uint8_t c) +{ + DEBUG("read_single\n"); + if (addr <= 0x2E) { + DEBUG("read configuration_registers\n"); + return configuration_registers[addr++]; + } + else if ((addr >= 0x30) && (addr <= 0x3D)) { + DEBUG("read status_registers\n"); + if (addr == 0x3B) { + DEBUG("\n\n\t\treturning RXBYTES: %d\n\n", status_registers[(addr) - 0x30]); + } + else { + DEBUG("\n\n\t\treturning: %d\n\n", status_registers[(addr) - 0x30]); + } + return status_registers[(addr++) - 0x30]; + } + else if (addr == 0x3E) { + DEBUG("read patable\n"); + if (patable_idx > 7) { + patable_idx = 0; + } + return patable[patable_idx++]; + } + else if (addr == 0x3F) { + DEBUG("read rx fifo\n"); + int off = (status_registers[CC1100_RXBYTES - 0x30] - rx_fifo_idx); + switch (off) { + case 0: + /* CRC OK */ + return CRC_OK; + case -1: + /* CRC OK */ + return 0xFF; + } + if (rx_fifo_idx >= status_registers[CC1100_RXBYTES - 0x30]) { + //warnx("read_single: buffer empty"); + } + return rx_fifo[rx_fifo_idx++]; + } + else { + errx(EXIT_FAILURE, "read_single: unhandled addr: 0x%02X", addr); + } + return c; +} + +uint8_t read_burst(uint8_t c) +{ + DEBUG(" read_burst: "); + if (c != 0xFF) { + warnx("read_burst: unexpected value"); + } + + if (addr <= 0x2E) { + DEBUG("read configuration_registers\n"); + return configuration_registers[addr++]; + } + else if ((addr >= 0x30) && (addr <= 0x3D)) { + DEBUG("read status_registers\n"); + return status_registers[(addr++) - 0x30]; + } + else if (addr == 0x3E) { + DEBUG("read patable\n"); + if (patable_idx > 7) { + patable_idx = 0; + } + return patable[patable_idx++]; + } + else if (addr == 0x3F) { + DEBUG("read rx fifo\n"); + int off = (status_registers[CC1100_RXBYTES - 0x30] - rx_fifo_idx); + switch (off) { + case 0: + /* CRC OK */ + return CRC_OK; + case -1: + /* CRC OK */ + return 0xFF; + } + if (rx_fifo_idx >= status_registers[CC1100_RXBYTES - 0x30]) { + //warnx("read_burst: buffer empty"); + } + return rx_fifo[rx_fifo_idx++]; + } + else { + errx(EXIT_FAILURE, "write_single: unhandled addr: 0x%02X", addr); + } +} + +void do_write_conf(uint8_t c) +{ + DEBUG("write configuration register\n"); + configuration_registers[addr] = c; + if (_native_cc1100_callbacks[addr].func != NULL) { + DEBUG("calling cc1100 callback for %i\n", addr); + _native_cc1100_callbacks[addr].func(); + } +} + +void do_write_patable(uint8_t c) +{ + DEBUG("write patable\n"); + patable[patable_idx] = c; +} +void do_write_tx(uint8_t c) +{ + DEBUG("write TX\n"); + if (status_registers[CC1100_TXBYTES - 0x30] == CC1100_FIFO_LENGTH) { + errx(EXIT_FAILURE, "do_write_tx: buffer too small"); + } + tx_fifo[tx_fifo_idx++] = c; + status_registers[CC1100_TXBYTES - 0x30]++; +} + +uint8_t write_single(uint8_t c) +{ + DEBUG("write_single\n"); + + if (addr <= 0x2E) { + do_write_conf(c); + } + else if ((addr >= 0x30) && (addr <= 0x3D)) { + do_strobe(); + } + else if (addr == 0x3E) { + do_write_patable(c); + } + else if (addr == 0x3F) { + do_write_tx(c); + } + else { + errx(EXIT_FAILURE, "write_single: unhandled addr: 0x%02X", addr); + } + + return 0; +} + +uint8_t write_burst(uint8_t c) +{ + DEBUG("write_burst\n"); + + if (addr <= 0x2E) { + do_write_conf(c); + addr++; + } + else if ((addr >= 0x30) && (addr <= 0x3D)) { + do_strobe(); + addr++; + } + else if (addr == 0x3E) { + DEBUG("write patable\n"); + } + else if (addr == 0x3F) { + do_write_tx(c); + } + else { + errx(EXIT_FAILURE, "write_single: unhandled addr: 0x%02X", addr); + } + + return 0; +} + +uint8_t do_txrx(uint8_t c) +{ + switch (_native_cc110x_state) { + case STATE_SEL: + c = parse_header(c); + break; + case STATE_WRITE_B: + c = write_burst(c); + break; + case STATE_READ_B: + c = read_burst(c); + break; + case STATE_READ_S: + c = read_single(c); + _native_cc110x_state = STATE_SEL; + break; + case STATE_WRITE_S: + c = write_single(c); + _native_cc110x_state = STATE_SEL; + break; + case STATE_NULL: + //warnx("received command(?) in NULL state"); + c = 0x00; + default: + errx(EXIT_FAILURE, "funny cc110x_ng state"); + } + return c; +} + +void _native_cc1100_register_callback(int event, void *cb) +{ + _native_cc1100_callbacks[event].func = cb; +} + +void _native_cc1100_handle_packet(unsigned char *buf, int size) +{ + unsigned char dst_addr; + + dst_addr = buf[1]; + + /* packet automation */ + + /* monitor mode */ + if ((configuration_registers[CC1100_PKTCTRL1] & 0x03) == 0x00) { + DEBUG("_native_cc1100_handle_packet: not filtering address\n"); + } + /* address filter */ + else { + /* own addr check */ + if (dst_addr == configuration_registers[CC1100_ADDR]) { + DEBUG("_native_cc1100_handle_packet: accept packet, addressed to us\n"); + } + /* 0x00 only broadcast */ + else if ( + ((configuration_registers[CC1100_PKTCTRL1] & 0x03) == 0x02) && + (dst_addr == 0x00) + ) { + DEBUG("_native_cc1100_handle_packet: accept packet, broadcast\n"); + } + /* 0x00 only broadcast */ + else if ( + ((configuration_registers[CC1100_PKTCTRL1] & 0x03) == 0x03) && + ((dst_addr == 0x00) || (dst_addr == 0xFF)) + ) { + DEBUG("_native_cc1100_handle_packet: accept packet, broadcast\n"); + } + else { + DEBUG("_native_cc1100_handle_packet: discard packet addressed to someone else\n"); + return; + } + } + /* length filter */ + /* variable packet length */ + if ((configuration_registers[CC1100_PKTCTRL0] & 0x03) == 0x01) { + if (size > configuration_registers[CC1100_PKTLEN]) { + DEBUG("_native_cc1100_handle_packet: discard packet longer than CC1100_PKTLEN\n"); + return; + } + else { + DEBUG("_native_cc1100_handle_packet: accept packet <= CC1100_PKTLEN\n"); + } + } + /* fixed packet length */ + else if ((configuration_registers[CC1100_PKTCTRL0] & 0x03) == 0x00) { + if (size != configuration_registers[CC1100_PKTLEN]) { + DEBUG("_native_cc1100_handle_packet: discard packet, size differs from CC1100_PKTLEN\n"); + return; + } + else { + DEBUG("_native_cc1100_handle_packet: accept packet == CC1100_PKTLEN\n"); + } + } + else { + errx(EXIT_FAILURE, "_native_cc1100_handle_packet: packet length mode not supported"); + } + + /* copy packet to rx_fifo */ + /* XXX: handle overflow */ + rx_fifo_idx = 0; + memcpy(rx_fifo, buf, size); + status_registers[CC1100_RXBYTES - 0x30] = size; + DEBUG("_native_cc1100_handle_packet: got %d bytes payload\n", size); + + /* toggle interrupt */ + cc110x_gdo2_irq(); +} + +#if 0 /* future ahead */ + +void step_state_idle(void) +{ + switch (addr) { + /* configuration registers: */ + case CC1100_IOCFG2: + case CC1100_IOCFG1: + case CC1100_IOCFG0: + case CC1100_FIFOTHR: + case CC1100_SYNC1: + case CC1100_SYNC0: + case CC1100_PKTLEN: + case CC1100_PKTCTRL1: + case CC1100_PKTCTRL0: + case CC1100_ADDR: + case CC1100_CHANNR: + case CC1100_FSCTRL1: + case CC1100_FSCTRL0: + case CC1100_FREQ2: + case CC1100_FREQ1: + case CC1100_FREQ0: + case CC1100_MDMCFG4: + case CC1100_MDMCFG3: + case CC1100_MDMCFG2: + case CC1100_MDMCFG1: + case CC1100_MDMCFG0: + case CC1100_DEVIATN: + case CC1100_MCSM2: + case CC1100_MCSM1: + case CC1100_MCSM0: + case CC1100_FOCCFG: + case CC1100_BSCFG: + case CC1100_AGCCTRL2: + case CC1100_AGCCTRL1: + case CC1100_AGCCTRL0: + case CC1100_WOREVT1: + case CC1100_WOREVT0: + case CC1100_WORCTRL: + case CC1100_FREND1: + case CC1100_FREND0: + case CC1100_FSCAL3: + case CC1100_FSCAL2: + case CC1100_FSCAL1: + case CC1100_FSCAL0: + case CC1100_RCCTRL1: + case CC1100_RCCTRL0: + case CC1100_FSTEST: + case CC1100_PTEST: + case CC1100_AGCTEST: + case CC1100_TEST2: + case CC1100_TEST1: + case CC1100_TEST0: + /* command strobes */ + case CC1100_SRES: + case CC1100_SFSTXON: + case CC1100_SXOFF: + case CC1100_SCAL: + case CC1100_SRX: + case CC1100_STX: + case CC1100_SIDLE: + case CC1100_SAFC: + case CC1100_SWOR: + case CC1100_SPWD: + case CC1100_SFRX: + case CC1100_SFTX: + case CC1100_SWORRST: + case CC1100_SNOP: + /* patable */ + case CC1100_PATABLE: + /* tx/rx */ + case CC1100_RXFIFO: /* == CC1100_TXFIFO */ + default: + errx(EXIT_FAILURE, "step_state_idle: unhandled addr: %d", addr); + } +} + +void step_state_sleep(void) +{ + ; +} + +void step_state_xtaloff(void) +{ + ; +} + +void step_state_freq_scal(void) +{ + ; +} + +void step_state_freq_sst(void) +{ + ; +} + +void step_state_freq_son(void) +{ + ; +} + +void step_state_tx(void) +{ + ; +} + +void step_state_rx(void) +{ + ; +} + +void step_state_tx_ffuf(void) +{ + ; +} + +void step_state_rx_ffof(void) +{ + ; +} + +void step(void) +{ + switch (internal_state) { + case (STATE_IDLE): + step_state_idle(); + break; + + case (STATE_SLEEP): + step_state_sleep(); + break; + + case (STATE_XTALOFF): + step_state_xtaloff(); + break; + + case (STATE_FREQ_SCAL): + step_state_freq_scal(); + break; + + case (STATE_FREQ_SST): + step_state_freq_sst(); + break; + + case (STATE_FREQ_SON): + step_state_freq_son(); + break; + + case (STATE_TX): + step_state_tx(); + break; + + case (STATE_RX): + step_state_rx(); + break; + + case (STATE_TX_FFUF): + step_state_tx_ffuf(); + break; + + case (STATE_RX_FFOF): + step_state_rx_ffof(); + break; + + default: + errx(EXIT_FAILURE, "internal error in CC1100 state machine"); + } +} + +void _native_cc1100_receive(uint8_t *buf, int len) +{ + ; +} + +#endif diff --git a/cpu/native/cc110x_ng/cc110x_ng_cpu.c b/cpu/native/cc110x_ng/cc110x_ng_cpu.c index 2b641593842e..551010fd779e 100644 --- a/cpu/native/cc110x_ng/cc110x_ng_cpu.c +++ b/cpu/native/cc110x_ng/cc110x_ng_cpu.c @@ -1,44 +1,36 @@ #include #include +#include +#include +#include +#include -#include +#include -#include -#include -#include -#include /* CC1100_READ_BURST etc. */ +#include "debug.h" -static int native_cc110x_enabled; +#include "tap.h" +#include "cc1100sim.h" +#include "cpu.h" -static int native_cc110x_gd0; -static int native_cc110x_gd1; -static int native_cc110x_gd2; +#include "cc110x-arch.h" +#include "cc110x_ng.h" +#include "cc110x_spi.h" +#include "cc110x-internal.h" /* CC1100 constants */ -static int native_cc110x_gd0_enabled; -static int native_cc110x_gd2_enabled; -static uint8_t native_cc110x_ssp0dr; +static int _native_cc110x_enabled; /* arch */ /** * writes to SSP0 data register and reads from it once it is ready + * TODO: move content to simulator */ uint8_t cc110x_txrx(uint8_t c) { - native_cc110x_ssp0dr = c; - - switch(c) { - case CC1100_READ_BURST: - case CC1100_WRITE_BURST: - case CC1100_READ_SINGLE: - case CC1100_NOBYTE: - default: - warnx("cc110x_txrx (%i): not implemented", c); - } - DEBUG("cc110x_txrx\n"); - return native_cc110x_ssp0dr; + return do_txrx(c); } /** @@ -47,19 +39,18 @@ uint8_t cc110x_txrx(uint8_t c) void cc110x_gdo0_enable(void) { /* this would be for rising/high edge if this was proper hardware */ - native_cc110x_gd0_enabled = 1; DEBUG("cc110x_gdo0_enable\n"); + native_cc110x_gd0_enabled = 1; return; } - /** * enables GDO0 interrupt */ void cc110x_gdo0_disable(void) { - native_cc110x_gd0_enabled = 0; DEBUG("cc110x_gdo0_disable\n"); + native_cc110x_gd0_enabled = 0; return; } @@ -69,8 +60,8 @@ void cc110x_gdo0_disable(void) void cc110x_gdo2_enable(void) { /* this would be for falling/low edge if this was proper hardware */ - native_cc110x_gd2_enabled = 1; DEBUG("cc110x_gdo2_enable\n"); + native_cc110x_gd2_enabled = 1; return; } @@ -79,8 +70,8 @@ void cc110x_gdo2_enable(void) */ void cc110x_gdo2_disable(void) { - native_cc110x_gd2_enabled = 0; DEBUG("cc110x_gdo2_disable\n"); + native_cc110x_gd2_enabled = 0; return; } @@ -90,22 +81,23 @@ void cc110x_gdo2_disable(void) void cc110x_init_interrupts(void) { /* this would be for low edge in both cases if this was proper hardware */ + DEBUG("cc110x_init_interrupts\n"); cc110x_gdo2_enable(); cc110x_gdo0_enable(); - DEBUG("cc110x_init_interrupts\n"); return; } +/* Disables RX interrupt etc. */ void cc110x_before_send(void) { - cc110x_gdo2_disable(); DEBUG("cc110x_before_send\n"); + cc110x_gdo2_disable(); return; } void cc110x_after_send(void) { - cc110x_gdo2_enable(); DEBUG("cc110x_after_send\n"); + cc110x_gdo2_enable(); return; } @@ -124,13 +116,13 @@ int cc110x_get_gdo1(void) int cc110x_get_gdo2(void) { DEBUG("cc110x_get_gdo2\n"); - return native_cc110x_gd2; + return native_cc110x_gd2--; } void cc110x_spi_init(void) { - native_cc110x_enabled = 1; /* power on */ DEBUG("cc110x_spi_init\n"); + _native_cc110x_enabled = 1; /* power on */ return; } @@ -141,12 +133,14 @@ void cc110x_spi_cs(void) } void cc110x_spi_select(void) { - DEBUG("cc110x_spi_select\n"); + DEBUG("___cc110x_spi_select\n"); + _native_cc110x_state = STATE_SEL; return; } void cc110x_spi_unselect(void) { DEBUG("cc110x_spi_unselect\n"); + _native_cc110x_state = STATE_NULL; return; } diff --git a/cpu/native/hwtimer_cpu.c b/cpu/native/hwtimer_cpu.c index 993d7a4677a0..f8c30d56f24f 100644 --- a/cpu/native/hwtimer_cpu.c +++ b/cpu/native/hwtimer_cpu.c @@ -40,7 +40,7 @@ #include "debug.h" -#define HWTIMERMINOFFSET 1000 +#define HWTIMERMINOFFSET 100000 static unsigned long native_hwtimer_now; @@ -217,6 +217,7 @@ unsigned long hwtimer_arch_now(void) DEBUG("hwtimer_arch_now()\n"); + _native_in_syscall = 1; #ifdef __MACH__ clock_serv_t cclock; mach_timespec_t mts; @@ -232,6 +233,7 @@ unsigned long hwtimer_arch_now(void) } #endif + _native_in_syscall = 0; native_hwtimer_now = ts2ticks(&t); diff --git a/cpu/native/include/cc1100sim.h b/cpu/native/include/cc1100sim.h new file mode 100644 index 000000000000..797501119f7e --- /dev/null +++ b/cpu/native/include/cc1100sim.h @@ -0,0 +1,39 @@ +extern uint8_t configuration_registers[((0x2E)+1)]; /* address 0x00 - 0x2E */ +extern uint8_t configuration_registers_idx; /* for burst access */ +extern uint8_t status_registers[((0x3D-0x30)+1)]; /* address 0x30 - 0x3D */ +extern uint8_t rx_fifo[]; /* address 0x3F + RW high (BF: 1011 1111) */ +extern uint8_t rx_fifo_idx; /* for burst access */ +extern uint8_t tx_fifo[]; /* address 0x3F + RW low (3F: 0011 1111) */ +extern uint8_t tx_fifo_idx; /* for burst access */ +extern uint8_t patable[8]; /* address 0x3E */ +extern uint8_t patable_idx; /* for burst access */ + + +extern int native_cc110x_gd0; +extern int native_cc110x_gd1; +extern int native_cc110x_gd2; +extern int native_cc110x_gd0_enabled; +extern int native_cc110x_gd2_enabled; + +extern uint8_t addr; +extern uint8_t _native_cc110x_state; + +uint8_t do_txrx(uint8_t c); +void do_sres(void); +uint8_t do_strobe(void); +uint8_t parse_header(uint8_t c); +uint8_t write_burst(uint8_t c); +uint8_t read_burst(uint8_t c); +uint8_t write_single(uint8_t c); +uint8_t read_single(uint8_t c); + +#define STATE_NULL 0x00 +#define STATE_SEL 0x01 +#define STATE_WRITE_B 0x02 +#define STATE_READ_B 0x03 +#define STATE_READ_S 0x04 +#define STATE_WRITE_S 0x05 + +void _native_cc1100_handle_packet(unsigned char *buf, int size); + +#define CC1100_FIFO_LENGTH 64 diff --git a/cpu/native/include/cpu-conf.h b/cpu/native/include/cpu-conf.h index 337b38c0ca18..e631e6249a54 100644 --- a/cpu/native/include/cpu-conf.h +++ b/cpu/native/include/cpu-conf.h @@ -18,15 +18,15 @@ #include /* TODO: choose more sensibly? */ -#define KERNEL_CONF_STACKSIZE_PRINTF (8192) +#define KERNEL_CONF_STACKSIZE_PRINTF (81920) -#ifdef __MACH__ +#ifdef __MACH__ /* OSX */ #define KERNEL_CONF_STACKSIZE_DEFAULT (163840) #define KERNEL_CONF_STACKSIZE_IDLE (163840) #define NATIVE_ISR_STACKSIZE (163840) #define TRANSCEIVER_STACK_SIZE (163840) #define MINIMUM_STACK_SIZE (163840) -#else +#else /* Linux etc. */ #define KERNEL_CONF_STACKSIZE_DEFAULT (8192) #define KERNEL_CONF_STACKSIZE_IDLE (16384) #define NATIVE_ISR_STACKSIZE (16384) @@ -35,12 +35,12 @@ #undef TRANSCEIVER_STACK_SIZE #endif #define TRANSCEIVER_STACK_SIZE (16384) - #define MINIMUM_STACK_SIZE (16384) -#endif +#endif /* OS */ /* for cc110x_ng */ #define RX_BUF_SIZE (10) #define TRANSCEIVER_BUFFER_SIZE (3) +#define NATIVE_ETH_PROTO 0x1234 #endif /* CPUCONF_H_ */ diff --git a/cpu/native/include/cpu.h b/cpu/native/include/cpu.h index 1187129df94a..955bb8552237 100644 --- a/cpu/native/include/cpu.h +++ b/cpu/native/include/cpu.h @@ -68,5 +68,12 @@ extern unsigned int _native_saved_eip; extern int _native_in_isr; extern int _native_in_syscall; extern int _native_sigpend; +#if (defined(MODULE_UART0) || defined(MODULE_CC110X_NG)) +#include +extern fd_set _native_rfds; +#endif +#ifdef MODULE_CC110X_NG +int _native_set_cc110xng_fds(void); +#endif /** @} */ #endif //_CPU_H diff --git a/cpu/native/include/tap.h b/cpu/native/include/tap.h new file mode 100644 index 000000000000..65d1351703d1 --- /dev/null +++ b/cpu/native/include/tap.h @@ -0,0 +1,29 @@ +#ifndef _TAP_H +#define _TAP_H + +#include + +/** + * create and/or open tap device "name" + * + * if "name" is an empty string, the kernel chooses a name + * if "name" is an existing device, that device is used + * otherwise a device named "name" is created + */ +int tap_init(char *name); +int send_buf(void); +void _native_marshall_ethernet(uint8_t *framebuf, uint8_t *data, int data_len); +void _native_cc1100_handle_input(unsigned char *buf, int size); + +extern int _native_tap_fd; +extern unsigned char _native_tap_mac[ETHER_ADDR_LEN]; + +union eth_frame { + struct { + struct ether_header header; + unsigned char data[ETHERMTU]; + } field; + unsigned char buffer[ETHER_MAX_LEN]; +}; + +#endif /* _TAP_H */ diff --git a/cpu/native/irq_cpu.c b/cpu/native/irq_cpu.c index 7dfd33884b7b..365308aed05f 100644 --- a/cpu/native/irq_cpu.c +++ b/cpu/native/irq_cpu.c @@ -49,6 +49,10 @@ struct int_handler_t { static struct int_handler_t native_irq_handlers[255]; char sigalt_stk[SIGSTKSZ]; + +void native_irq_handler(); + + void print_thread_sigmask(ucontext_t *cp) { sigset_t *p = &cp->uc_sigmask; @@ -133,6 +137,10 @@ unsigned disableIRQ(void) _native_in_syscall = 1; DEBUG("disableIRQ()\n"); + if (_native_in_isr == 1) { + DEBUG("disableIRQ + _native_in_isr\n"); + } + if (sigfillset(&mask) == -1) { err(1, "disableIRQ(): sigfillset"); } @@ -155,10 +163,13 @@ unsigned disableIRQ(void) prev_state = native_interrupts_enabled; native_interrupts_enabled = 0; - if (_native_sigpend > 0) { + // XXX: does this make sense? + if ((_native_sigpend > 0) && (_native_in_isr == 0)) { DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n"); _native_in_syscall = 0; - printf("calling swapcontext()\n"); + printf("disableIRQ: calling swapcontext()\n"); + printf("disableIRQ: _native_cur_ctx == %p, _native_isr_ctx == %p\n", _native_cur_ctx, _native_isr_ctx); + makecontext(&native_isr_context, native_irq_handler, 0); swapcontext(_native_cur_ctx, _native_isr_ctx); } else { @@ -180,6 +191,10 @@ unsigned enableIRQ(void) _native_in_syscall = 1; DEBUG("enableIRQ()\n"); + if (_native_in_isr == 1) { + DEBUG("enableIRQ + _native_in_isr\n"); + } + if (sigprocmask(SIG_SETMASK, &native_sig_set, NULL) == -1) { err(1, "enableIRQ(): sigprocmask()"); } @@ -189,10 +204,12 @@ unsigned enableIRQ(void) //print_sigmasks(); //native_print_signals(); - if (_native_sigpend > 0) { + if ((_native_sigpend > 0) && (_native_in_isr == 0)) { DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n"); _native_in_syscall = 0; - printf("calling swapcontext()\n"); + printf("enableIRQ: calling swapcontext()\n"); + printf("enableIRQ: _native_cur_ctx == %p, _native_isr_ctx == %p\n", _native_cur_ctx, _native_isr_ctx); + makecontext(&native_isr_context, native_irq_handler, 0); swapcontext(_native_cur_ctx, _native_isr_ctx); } else { @@ -243,6 +260,7 @@ int _native_popsig(void) nleft = sizeof(int); i = 0; + _native_in_syscall = 1; while ((nleft > 0) && ((nread = read(pipefd[0], &sig + i, nleft)) != -1)) { i += nread; nleft -= nread; @@ -251,6 +269,7 @@ int _native_popsig(void) if (nread == -1) { err(1, "_native_popsig(): read()"); } + _native_in_syscall = 0; return sig; } diff --git a/cpu/native/lpm_cpu.c b/cpu/native/lpm_cpu.c index 3931df7ba519..576a3e24759c 100644 --- a/cpu/native/lpm_cpu.c +++ b/cpu/native/lpm_cpu.c @@ -44,8 +44,15 @@ void lpm_init(void) void _native_lpm_sleep() { #ifdef MODULE_UART0 - int retval; - retval = select(1, &_native_uart_rfds, NULL, NULL, NULL); + int retval, nfds; + + /* set fds */ + nfds = 0; + FD_ZERO(&_native_rfds); + nfds = _native_set_uart_fds(); + nfds++; + + retval = select(nfds, &_native_rfds, NULL, NULL, NULL); DEBUG("_native_lpm_sleep: retval: %i\n", retval); if (retval != -1) { diff --git a/cpu/native/native_cpu.c b/cpu/native/native_cpu.c index f9a4ce35c8a4..8323654c9e31 100644 --- a/cpu/native/native_cpu.c +++ b/cpu/native/native_cpu.c @@ -36,6 +36,10 @@ extern volatile tcb_t *active_thread; static ucontext_t end_context; static char __isr_stack[SIGSTKSZ]; +#if (defined(MODULE_UART0) || defined(MODULE_CC110X_NG)) +fd_set _native_rfds; +#endif + /** * TODO: implement */ diff --git a/cpu/native/startup.c b/cpu/native/startup.c index 39a3534dbdd1..fe371cd3ba51 100644 --- a/cpu/native/startup.c +++ b/cpu/native/startup.c @@ -15,17 +15,33 @@ */ #include +#include +#include + #include #include +#include "tap.h" + extern void board_init(void); extern void native_cpu_init(void); extern void native_interrupt_init(void); -__attribute__((constructor)) static void startup(void) +__attribute__((constructor)) static void startup(int argc, char **argv) { + +#ifdef MODULE_CC110X_NG + if (argc < 2) { + printf("usage: %s \n", argv[0]); + exit(EXIT_FAILURE); + } +#endif + native_cpu_init(); native_interrupt_init(); +#ifdef MODULE_CC110X_NG + tap_init(argv[1]); +#endif board_init(); diff --git a/cpu/native/tap.c b/cpu/native/tap.c new file mode 100644 index 000000000000..8f75f0a1d175 --- /dev/null +++ b/cpu/native/tap.c @@ -0,0 +1,235 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __MACH__ +#define _POSIX_C_SOURCE +#include +#undef _POSIX_C_SOURCE +#include +#include +#else +#include +#include +#include +#endif + +#include "debug.h" + +#include "cpu.h" +#include "cpu-conf.h" +#include "tap.h" +#include "cc1100sim.h" +#include "cc110x-internal.h" /* CC1100 constants */ + +#define TAP_BUFFER_LENGTH (CC1100_FIFO_LENGTH + ETHER_HDR_LEN + 1) + +int _native_tap_fd; +unsigned char _native_tap_mac[ETHER_ADDR_LEN]; + +void _native_handle_cc110xng_input(void) +{ + int nread; + unsigned char buf[TAP_BUFFER_LENGTH]; + union eth_frame *f; + + DEBUG("_native_handle_cc110xng_input\n"); + + /* TODO: check whether this is an input or an output event + TODO: refactor this into general io-signal multiplexer */ + + _native_in_syscall = 1; + nread = read(_native_tap_fd, buf, TAP_BUFFER_LENGTH); + _native_in_syscall = 0; + DEBUG("_native_handle_cc110xng_input - read %d bytes\n", nread); + if (nread > 0) { + f = (union eth_frame*)&buf; + if (ntohs(f->field.header.ether_type) == NATIVE_ETH_PROTO) { + nread = nread - ETHER_HDR_LEN; + if ((nread - 1) <= 0) { + DEBUG("_native_handle_cc110xng_input: no payload"); + } + else { + nread = buf[ETHER_HDR_LEN]; + _native_cc1100_handle_packet(buf+ETHER_HDR_LEN+1, nread); + } + } + else { + DEBUG("ignoring non-native frame\n"); + } + } + else if (nread == -1) { + err(EXIT_FAILURE, "read"); + } + else { + errx(EXIT_FAILURE, "internal error in _native_handle_cc110xng_input"); + } +} + +int send_buf(void) +{ + uint8_t buf[TAP_BUFFER_LENGTH]; + int nsent; + uint8_t to_send; + + to_send = status_registers[CC1100_TXBYTES - 0x30]; + _native_marshall_ethernet(buf, tx_fifo, to_send); + to_send += 1; + + if ((ETHER_HDR_LEN + to_send) < ETHERMIN) { + DEBUG("padding data! (%d ->", to_send); + to_send = ETHERMIN - ETHER_HDR_LEN; + DEBUG("%d)\n", to_send); + } + + if ((nsent = write(_native_tap_fd, buf, to_send + ETHER_HDR_LEN)) == -1) {; + warn("write"); + return -1; + } + return 0; +} + +int tap_init(char *name) +{ + +#ifdef __MACH__ /* OSX */ + char clonedev[255] = "/dev/"; /* XXX bad size */ + strncpy(clonedev+5, name, 250); +#else /* Linux */ + struct ifreq ifr; + char *clonedev = "/dev/net/tun"; +#endif + + /* implicitly create the tap interface */ + if ((_native_tap_fd = open(clonedev , O_RDWR)) == -1) { + err(EXIT_FAILURE, "open(%s)", clonedev); + } + +#ifdef __MACH__ /* OSX */ + struct ifaddrs* iflist; + if (getifaddrs(&iflist) == 0) { + for (struct ifaddrs *cur = iflist; cur; cur = cur->ifa_next) { + if ((cur->ifa_addr->sa_family == AF_LINK) && (strcmp(cur->ifa_name, name) == 0) && cur->ifa_addr) { + struct sockaddr_dl* sdl = (struct sockaddr_dl*)cur->ifa_addr; + memcpy(_native_tap_mac, LLADDR(sdl), sdl->sdl_alen); + break; + } + } + + freeifaddrs(iflist); + } +#else /* Linux */ + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + strncpy(ifr.ifr_name, name, IFNAMSIZ); + + if (ioctl(_native_tap_fd, TUNSETIFF, (void *)&ifr) == -1) { + warn("ioctl"); + if (close(_native_tap_fd) == -1) { + warn("close"); + } + exit(EXIT_FAILURE); + } + + /* TODO: use strncpy */ + strcpy(name, ifr.ifr_name); + + + /* get MAC address */ + memset (&ifr, 0, sizeof (ifr)); + snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", name); + if (ioctl(_native_tap_fd, SIOCGIFHWADDR, &ifr) == -1) { + warn("ioctl"); + if (close(_native_tap_fd) == -1) { + warn("close"); + } + exit(EXIT_FAILURE); + } + memcpy(_native_tap_mac, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); +#endif + +/*TODO: check OSX vvv */ + /* configure signal handler for fds */ + register_interrupt(SIGIO, _native_handle_cc110xng_input); + + /* configure fds to send signals on io */ + if (fcntl(_native_tap_fd, F_SETOWN, getpid()) == -1) { + err(1, "_native_init_uart0(): fcntl()"); + } + + /* set file access mode to nonblocking */ + if (fcntl(_native_tap_fd, F_SETFL, O_NONBLOCK|O_ASYNC) == -1) { + err(1, "_native_init_uart0(): fcntl()"); + } +/*TODO: check OSX ^^^ */ + + puts("RIOT native tap initialized."); + return _native_tap_fd; +} + +void _native_marshall_ethernet(uint8_t *framebuf, uint8_t *data, int data_len) +{ + union eth_frame *f; + unsigned char addr[ETHER_ADDR_LEN]; + + f = (union eth_frame*)framebuf; + addr[0] = addr[1] = addr[2] = addr[3] = addr[4] = addr[5] = (char)0xFF; + + //memcpy(f->field.header.ether_dhost, dst, ETHER_ADDR_LEN); + memcpy(f->field.header.ether_dhost, addr, ETHER_ADDR_LEN); + //memcpy(f->field.header.ether_shost, src, ETHER_ADDR_LEN); + memcpy(f->field.header.ether_shost, _native_tap_mac, ETHER_ADDR_LEN); + f->field.header.ether_type = htons(NATIVE_ETH_PROTO); + memcpy(f->field.data+1, data, data_len); + f->field.data[0] = (uint8_t)data_len; +} + +#ifdef TAPTESTBINARY +/** + * test tap device + */ +int main(int argc, char *argv[]) +{ + int fd; + unsigned char buffer[2048]; + + if (argc < 2) { + errx(EXIT_FAILURE, "you need to specify a tap name"); + } + fd = tap_init(argv[1]); + + printf("trying to write to fd: %i\n", _native_tap_fd); + char *payld = "abcdefg"; + int data_len = strlen(payld); + _native_marshall_ethernet(buffer, payld, data_len); + if (write(_native_tap_fd, buffer, ETHER_HDR_LEN + data_len) == -1) { + err(EXIT_FAILURE, "write"); + } + + printf("reading\n"); + int nread; + while (1) { + /* Note that "buffer" should be at least the MTU size of the + * interface, eg 1500 bytes */ + nread = read(fd,buffer,sizeof(buffer)); + if(nread < 0) { + warn("Reading from interface"); + if (close(fd) == -1) { + warn("close"); + } + exit(EXIT_FAILURE); + } + + /* Do whatever with the data */ + printf("Read %d bytes\n", nread); + } + + return EXIT_SUCCESS; +} +#endif diff --git a/cpu/native/tapsetup-osx.sh b/cpu/native/tapsetup-osx.sh new file mode 100755 index 000000000000..36317f2ef92d --- /dev/null +++ b/cpu/native/tapsetup-osx.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +COMMAND=${1} +COUNT=${2} + +DEFCOUNT="2" +DEFBRNAME="bridge1234" + +if [ -z "${USER}" ]; then + echo 'need to export $USER' + exit 1 +fi +if [ -z "${COMMAND}" ]; then + echo "usage: $(basename $0) " + exit 1 +fi + +if [ -z "${BRNAME}" ]; then + BRNAME="${DEFBRNAME}" +fi + +if [ "${COMMAND}" = 'create' ]; then + if [ -z "${COUNT}" ]; then + COUNT="${DEFCOUNT}" + fi + + sudo ifconfig ${BRNAME} create || exit 1 + echo "upping ${BRNAME}" + sudo ifconfig ${BRNAME} up || exit 1 + + for N in $(seq 0 "$((COUNT - 1))"); do + sudo chown ${USER} /dev/tap${N} || exit 1 + echo "start RIOT instance for tap${N} now and hit enter" + read + sudo ifconfig ${BRNAME} addm tap${N} || exit 1 + sudo ifconfig tap${N} up + done + +elif [ "${COMMAND}" = 'delete' ]; then + sudo ifconfig ${BRNAME} destroy + +else + echo 'unknown command' + exit 1 +fi + +exit 0 diff --git a/cpu/native/tapsetup.sh b/cpu/native/tapsetup.sh new file mode 100755 index 000000000000..e64485a4133f --- /dev/null +++ b/cpu/native/tapsetup.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +COMMAND=${1} +COUNT=${2} + +DEFCOUNT="2" +DEFBRNAME="tapbr0" + +if [ -z "${USER}" ]; then + echo 'need to export $USER' + exit 1 +fi +if [ -z "${COMMAND}" ]; then + echo "usage: $(basename $0) " + exit 1 +fi + +if [ -z "${BRNAME}" ]; then + BRNAME="${DEFBRNAME}" +fi + +if [ "${COMMAND}" = 'create' ]; then + if [ -z "${COUNT}" ]; then + COUNT="${DEFCOUNT}" + fi + + sudo brctl addbr ${BRNAME} || exit 1 + sudo -s sh -c "echo 1 > /proc/sys/net/ipv6/conf/${BRNAME}/disable_ipv6" || exit 1 + sudo ip link set ${BRNAME} up || exit 1 + + for N in $(seq 0 "$((COUNT - 1))"); do + sudo ip tuntap add dev tap${N} mode tap user ${USER} || exit 1 + sudo -s sh -c "echo 1 > /proc/sys/net/ipv6/conf/tap${N}/disable_ipv6" || exit 1 + sudo brctl addif ${BRNAME} tap${N} || exit 1 + sudo ip link set tap${N} up || exit 1 + done + +elif [ "${COMMAND}" = 'delete' ]; then + for IF in $(ls /sys/class/net/${BRNAME}/brif); do + sudo ip link delete "${IF}" + done + sudo ip link set ${BRNAME} down + sudo brctl delbr ${BRNAME} + +else + echo 'unknown command' + exit 1 +fi + +exit 0 diff --git a/drivers/cc110x_ng/include/cc110x-internal.h b/drivers/cc110x_ng/include/cc110x-internal.h index 392b30626d91..d3409e99792f 100644 --- a/drivers/cc110x_ng/include/cc110x-internal.h +++ b/drivers/cc110x_ng/include/cc110x-internal.h @@ -88,7 +88,7 @@ #define CC1100_WRITE_BURST (0x40) ///< Offset for burst write. #define CC1100_READ_SINGLE (0x80) ///< Offset for read single byte. #define CC1100_READ_BURST (0xC0) ///< Offset for read burst. -#define CC1100_NOBYTE (0x00) ///< No command (for reading). +#define CC1100_NOBYTE (0xFF) ///< No command (for reading). /** @} */ /** From 708ece68cc78ed7ffe61f864c208a93f73918ac1 Mon Sep 17 00:00:00 2001 From: Ludwig Ortmann Date: Thu, 8 Aug 2013 11:08:33 +0200 Subject: [PATCH 2/2] cc1100 -> nativenet --- cpu/native/Makefile | 7 +- cpu/native/README | 2 +- cpu/native/cc110x_ng/Makefile | 7 - cpu/native/cc110x_ng/cc1100-sim.c | 756 -------------------- cpu/native/cc110x_ng/cc110x_ng_cpu.c | 147 ---- cpu/native/include/cc1100sim.h | 39 - cpu/native/include/cpu-conf.h | 5 +- cpu/native/include/cpu.h | 5 +- cpu/native/include/nativenet.h | 29 + cpu/native/include/nativenet_internal.h | 24 + cpu/native/include/tap.h | 6 +- cpu/native/irq_cpu.c | 10 +- cpu/native/native_cpu.c | 2 +- cpu/native/net/Makefile | 6 + cpu/native/net/interface.c | 186 +++++ cpu/native/{ => net}/tap.c | 124 ++-- cpu/native/startup.c | 4 +- drivers/cc110x_ng/include/cc110x-internal.h | 2 +- sys/include/transceiver.h | 7 + sys/shell/commands/Makefile | 4 + sys/shell/commands/sc_nativenet.c | 127 ++++ sys/shell/commands/shell_commands.c | 17 + sys/transceiver/transceiver.c | 88 ++- 23 files changed, 551 insertions(+), 1053 deletions(-) delete mode 100644 cpu/native/cc110x_ng/Makefile delete mode 100644 cpu/native/cc110x_ng/cc1100-sim.c delete mode 100644 cpu/native/cc110x_ng/cc110x_ng_cpu.c delete mode 100644 cpu/native/include/cc1100sim.h create mode 100644 cpu/native/include/nativenet.h create mode 100644 cpu/native/include/nativenet_internal.h create mode 100644 cpu/native/net/Makefile create mode 100644 cpu/native/net/interface.c rename cpu/native/{ => net}/tap.c (66%) create mode 100644 sys/shell/commands/sc_nativenet.c diff --git a/cpu/native/Makefile b/cpu/native/Makefile index 34ae69f430e1..2c6f560a347d 100644 --- a/cpu/native/Makefile +++ b/cpu/native/Makefile @@ -1,13 +1,12 @@ MODULE = cpu -INCLUDES = -I../include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/cc110x_ng/include +INCLUDES += -I../include -I$(RIOTBASE)/core/include DIRS = ifneq (,$(findstring rtc,$(USEMODULE))) DIRS += rtc endif -ifneq (,$(findstring cc110x_ng,$(USEMODULE))) - DIRS += cc110x_ng - INCLUDES += -I$(RIOTBASE)/drivers/cc110x_ng/include +ifneq (,$(findstring nativenet,$(USEMODULE))) + DIRS += net endif all: $(BINDIR)$(MODULE).a diff --git a/cpu/native/README b/cpu/native/README index ccd8cd1136e8..f53725842e01 100644 --- a/cpu/native/README +++ b/cpu/native/README @@ -1,4 +1,4 @@ -If you compile RIOT for the native cpu and include the cc110x_ng +If you compile RIOT for the native cpu and include the native_net module, you need to specify a network interface like this: ./bin/default-native.elf tap0 diff --git a/cpu/native/cc110x_ng/Makefile b/cpu/native/cc110x_ng/Makefile deleted file mode 100644 index db427dad5ac4..000000000000 --- a/cpu/native/cc110x_ng/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -INCLUDES = -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/core/include -INCLUDES += -I$(RIOTBASE)/drivers/cc110x_ng/include/ -I$(RIOTBASE)/sys/include - -MODULE =cc110x_ng - -include $(MAKEBASE)/Makefile.base - diff --git a/cpu/native/cc110x_ng/cc1100-sim.c b/cpu/native/cc110x_ng/cc1100-sim.c deleted file mode 100644 index 3644e0ab09d1..000000000000 --- a/cpu/native/cc110x_ng/cc1100-sim.c +++ /dev/null @@ -1,756 +0,0 @@ -#include -#include -#include -#include -#include - -#include "debug.h" - -#include "cc110x_ng.h" -#include "cc110x-internal.h" /* CC1100_READ_BURST etc. */ -#include "tap.h" -#include "cc1100sim.h" - -#define CC1100_EVENT_SET_POWER 0x01 -#define CC1100_EVENT_SET_CHANNEL 0x02 - -/** - * simplified states according to cc1100.pdf figure 5, page 23 - */ -#define STATE_IDLE 0x00 -/* SPWD || WOR -> STATE_SLEEP - * SXOFF -> STATE_XTALOFF - * SCAL -> STATE_FREQ_SCAL - * SRX || STX || WOR -> STATE_FREQ_SST */ -#define STATE_SLEEP 0x01 /* CSn=0 -> STATE_IDLE */ -#define STATE_XTALOFF 0x02 /* CSn=0 -> STATE_IDLE */ -#define STATE_FREQ_SCAL 0x03 /* -> STATE_IDLE */ - -#define STATE_FREQ_SST 0x04 -/* SFSTXON -> STATE_FREQ_SON - * STX -> STATE_TX - * SRX||WOR -> STATE_RX */ -#define STATE_FREQ_SON 0x05 /* STX -> STATE_TX */ -#define STATE_TX 0x06 -/* TXOFF_MODE = 11 || SRX -> STATE_RX - * TXOFF_MODE = 01 -> STATE_FREQ_SON - * STATE_TX_FFUF */ -#define STATE_TX_FFUF 0x07 /* SFTX -> STATE_IDLE */ -#define STATE_RX 0x08 -/* RXOFF_MODE = 10 || STX -> STATE_TX - * RXOFF_MODE = 00 -> STATE_FREQ_SON - * -> STATE_TX_FFUF */ -#define STATE_RX_FFOF 0x09 /* SFRX -> STATE_IDLE */ - - -/** - * status byte state bits according to cc1100.pdf, page 26, table 17 - */ -#define M_IDLE 0x00 -#define M_RX 0x10 -#define M_TX 0x20 -#define M_FSTXON 0x30 -#define M_CALIBRATE 0x40 -#define M_SETTLING 0x50 -#define M_RXFIFO_OVERFLOW 0x60 -#define M_TXFIFO_UNDERFLOW 0x70 - -#define MASK_STATE 0x70 -#define MASK_CHIP_RDYn 0x80 -#define MASK_FIFO_BYTES_AVAILABLE 0x0F - -#if 0 -static uint8_t internal_state; /* according to table 17 */ -static uint8_t _native_cc1100_spi; /* the pins */ -/* one byte goes in, one byte goes out */ -static uint8_t _native_cc1100_serial_io; -#endif - -uint8_t addr; /* as sent in header */ -uint8_t _native_cc110x_state; - - -uint8_t configuration_registers[((0x2E)+1)]; /* address 0x00 - 0x2E */ -uint8_t configuration_registers_idx; /* for burst access */ -uint8_t status_registers[((0x3D-0x30)+1)]; /* address 0x30 - 0x3D */ -/* command strobes reside at the addresses 0x30 to 0x3D when writing */ -uint8_t patable[8]; /* address 0x3E */ -uint8_t patable_idx; /* for burst access */ - -uint8_t tx_fifo[64]; -uint8_t tx_fifo_idx; -uint8_t rx_fifo[64]; -uint8_t rx_fifo_idx; - -int native_cc110x_gd0; -int native_cc110x_gd1; -int native_cc110x_gd2; -int native_cc110x_gd0_enabled; -int native_cc110x_gd2_enabled; - -/* static uint8_t address_space[0xFF]; */ -/* static uint8_t address_space_pointer; */ - -/* network layer handlers for cc1100 events: */ -struct cc1100_callback_t { - void (*func)(void); -}; -static struct cc1100_callback_t _native_cc1100_callbacks[255]; - -/* cc1100 default configuration */ -unsigned char cc1100_reset_configuration_regs[] = { - 0x29, /* IOCFG2 */ - 0x2E, /* IOCFG1 */ - 0x3F, /* IOCFG0 */ - 0x07, /* FIFOTHR */ - 0xD3, /* SYNC1 */ - 0x91, /* SYNC0 */ - 0xFF, /* PKTLEN */ - 0x04, /* PKTCTRL1 */ - 0x45, /* PKTCTRL0 */ - 0x00, /* ADDR */ - 0x00, /* CHANNR */ - 0x0F, /* FSCTRL1 */ - 0x00, /* FSCTRL0 */ - 0x1E, /* FREQ2 */ - 0xC4, /* FREQ1 */ - 0xEC, /* FREQ0 */ - 0x2C, /* MDMCFG4 */ - 0x22, /* MDMCFG3 */ - 0x02, /* MDMCFG2 */ - 0x22, /* MDMCFG1 */ - 0xF8, /* MDMCFG0 */ - 0x47, /* DEVIATN */ - 0x07, /* MCSM2 */ - 0x30, /* MCSM1 */ - 0x04, /* MCSM0 */ - 0x66, /* FOCCFG */ - 0x66, /* BSCFG */ - 0x03, /* AGCCTRL2 */ - 0x40, /* AGCCTRL1 */ - 0x91, /* AGCCTRL0 */ - 0x87, /* WOREVT1 */ - 0x6B, /* WOREVT0 */ - 0xF8, /* WORCTRL */ - 0x56, /* FREND1 */ - 0x10, /* FREND0 */ - 0xA9, /* FSCAL3 */ - 0x0A, /* FSCAL2 */ - 0x20, /* FSCAL1 */ - 0x0D, /* FSCAL0 */ - 0x41, /* RCCTRL1 */ - 0x00, /* RCCTRL0 */ - 0x59, /* FSTEST */ - 0x7F, /* PTEST */ - 0x3F, /* AGCTEST */ - 0x88, /* TEST2 */ - 0x31, /* TEST1 */ - 0x0B /* TEST0 */ -}; - -/* cc1100 default status */ -unsigned char cc1100_reset_status_regs[] = { - 0x00, /* PARTNUM */ - 0x03, /* VERSION */ - 0x00, /* FREQEST */ - 0x00, /* LQI */ - 0x00, /* RSSI */ - 0x00, /* MARCSTATE */ - 0x00, /* WORTIME1 */ - 0x00, /* WORTIME0 */ - 0x00, /* PKTSTATUS */ - 0x00, /* VCO_VC_DAC */ - 0x00, /* TXBYTES */ - 0x00, /* RXBYTES */ - 0x00, /* RCCTRL1_STATUS */ - 0x00 /* RCCTRL0_STATUS */ -}; - -void do_sres(void) -{ - int i; - - for (i = 0; i < 0x2E; i++) { - configuration_registers[i] = cc1100_reset_configuration_regs[i]; - } - for (i = 0; i < (0x3D - 0x30); i++) { - status_registers[i] = cc1100_reset_status_regs[i]; - } - for (i = 1; i < 8; i++) { - patable[i] = 0; - } -} - -uint8_t do_strobe(void) -{ - DEBUG("issue strobe command\n"); - switch (addr) { - case CC1100_SRES: - do_sres(); - break; - case CC1100_SFSTXON: - //warnx("do_strobe: not implemented: CC1100_SFSTXON"); - break; - case CC1100_SXOFF: - //warnx("do_strobe: not implemented: CC1100_SXOFF"); - break; - case CC1100_SCAL: - //warnx("do_strobe: not implemented: CC1100_SCAL"); - break; - case CC1100_SRX: - //warnx("do_strobe: not implemented: CC1100_SRX"); - break; - case CC1100_STX: - //warnx("do_strobe: not properly implemented: CC1100_STX"); - if (((status_registers[CC1100_TXBYTES - 0x30] & 0x7F) > 0) && (send_buf() == -1)) { - native_cc110x_gd2 = 1; - } - else { - native_cc110x_gd2 = 1; - } - break; - case CC1100_SIDLE: - //warnx("do_strobe: not implemented: CC1100_SIDLE "); - break; - case CC1100_SAFC: - //warnx("do_strobe: not implemented: CC1100_SAFC"); - break; - case CC1100_SWOR: - //warnx("do_strobe: not implemented: CC1100_SWOR"); - break; - case CC1100_SPWD: - //warnx("do_strobe: not implemented: CC1100_SPWD"); - break; - case CC1100_SFRX: - status_registers[CC1100_RXBYTES - 0x30] = 0x00; - rx_fifo_idx = 0x00; - break; - case CC1100_SFTX: - status_registers[CC1100_TXBYTES - 0x30] = 0x00; - tx_fifo_idx = 0x00; - break; - case CC1100_SWORRST: - //warnx("do_strobe: not implemented: CC1100_SWORRST"); - break; - case CC1100_SNOP: - //warnx("do_strobe: not implemented: CC1100_SNOP"); - break; - default: - errx(EXIT_FAILURE, "do_strobe: internal error"); - } - return addr; -} - -uint8_t parse_header(uint8_t c) -{ - DEBUG("parse_header(0x%02X): ", c); - - addr = c & 0x3F; /* bits [5..0] */ - uint8_t mode = c & 0xC0; /* bits [76]*/ - - /* set access mode, set status bute (c) */ - switch (mode) { - case CC1100_READ_BURST: - /* status registers can only be read single */ - if ((addr >= 0x30) && (addr <= 0x3D)) { - DEBUG(" CC1100_READ_SINGLE"); - _native_cc110x_state = STATE_READ_S; - } - else { - DEBUG(" CC1100_READ_BURST"); - _native_cc110x_state = STATE_READ_B; - } - c = status_registers[CC1100_RXBYTES - 0x30] - rx_fifo_idx; - break; - case CC1100_WRITE_BURST: - DEBUG(" CC1100_WRITE_BURST"); - _native_cc110x_state = STATE_WRITE_B; - c = 0x0F - status_registers[CC1100_TXBYTES - 0x30]; - break; - case CC1100_READ_SINGLE: - DEBUG(" CC1100_READ_SINGLE"); - _native_cc110x_state = STATE_READ_S; - c = status_registers[CC1100_RXBYTES - 0x30] - rx_fifo_idx; - break; - default: - DEBUG(" CC1100_WRITE_SINGLE"); - _native_cc110x_state = STATE_WRITE_S; - c = 0x0F - status_registers[CC1100_TXBYTES - 0x30]; - } - if (addr <= 0x2E) { - DEBUG(" configuration register"); - } - else if ((addr >= 0x30) && (addr <= 0x3D)) { - if ((_native_cc110x_state == STATE_WRITE_B) || (_native_cc110x_state == STATE_WRITE_S)) { - DEBUG(" strobe command"); - /* strobe commands get executed directly */ - do_strobe(); - } - else { - DEBUG(" status register"); - } - } - else if (addr == 0x3E) { - DEBUG(" patable"); - } - else if (addr == 0x3F) { - if ((_native_cc110x_state == STATE_WRITE_B) || (_native_cc110x_state == STATE_WRITE_S)) { - DEBUG(" TX"); - } - else { - DEBUG(" RX"); - } - } - else { - errx(EXIT_FAILURE, "parse_header: unhandled addr: 0x%02X", addr); - } - DEBUG("==\n"); - - return c; -} - -uint8_t read_single(uint8_t c) -{ - DEBUG("read_single\n"); - if (addr <= 0x2E) { - DEBUG("read configuration_registers\n"); - return configuration_registers[addr++]; - } - else if ((addr >= 0x30) && (addr <= 0x3D)) { - DEBUG("read status_registers\n"); - if (addr == 0x3B) { - DEBUG("\n\n\t\treturning RXBYTES: %d\n\n", status_registers[(addr) - 0x30]); - } - else { - DEBUG("\n\n\t\treturning: %d\n\n", status_registers[(addr) - 0x30]); - } - return status_registers[(addr++) - 0x30]; - } - else if (addr == 0x3E) { - DEBUG("read patable\n"); - if (patable_idx > 7) { - patable_idx = 0; - } - return patable[patable_idx++]; - } - else if (addr == 0x3F) { - DEBUG("read rx fifo\n"); - int off = (status_registers[CC1100_RXBYTES - 0x30] - rx_fifo_idx); - switch (off) { - case 0: - /* CRC OK */ - return CRC_OK; - case -1: - /* CRC OK */ - return 0xFF; - } - if (rx_fifo_idx >= status_registers[CC1100_RXBYTES - 0x30]) { - //warnx("read_single: buffer empty"); - } - return rx_fifo[rx_fifo_idx++]; - } - else { - errx(EXIT_FAILURE, "read_single: unhandled addr: 0x%02X", addr); - } - return c; -} - -uint8_t read_burst(uint8_t c) -{ - DEBUG(" read_burst: "); - if (c != 0xFF) { - warnx("read_burst: unexpected value"); - } - - if (addr <= 0x2E) { - DEBUG("read configuration_registers\n"); - return configuration_registers[addr++]; - } - else if ((addr >= 0x30) && (addr <= 0x3D)) { - DEBUG("read status_registers\n"); - return status_registers[(addr++) - 0x30]; - } - else if (addr == 0x3E) { - DEBUG("read patable\n"); - if (patable_idx > 7) { - patable_idx = 0; - } - return patable[patable_idx++]; - } - else if (addr == 0x3F) { - DEBUG("read rx fifo\n"); - int off = (status_registers[CC1100_RXBYTES - 0x30] - rx_fifo_idx); - switch (off) { - case 0: - /* CRC OK */ - return CRC_OK; - case -1: - /* CRC OK */ - return 0xFF; - } - if (rx_fifo_idx >= status_registers[CC1100_RXBYTES - 0x30]) { - //warnx("read_burst: buffer empty"); - } - return rx_fifo[rx_fifo_idx++]; - } - else { - errx(EXIT_FAILURE, "write_single: unhandled addr: 0x%02X", addr); - } -} - -void do_write_conf(uint8_t c) -{ - DEBUG("write configuration register\n"); - configuration_registers[addr] = c; - if (_native_cc1100_callbacks[addr].func != NULL) { - DEBUG("calling cc1100 callback for %i\n", addr); - _native_cc1100_callbacks[addr].func(); - } -} - -void do_write_patable(uint8_t c) -{ - DEBUG("write patable\n"); - patable[patable_idx] = c; -} -void do_write_tx(uint8_t c) -{ - DEBUG("write TX\n"); - if (status_registers[CC1100_TXBYTES - 0x30] == CC1100_FIFO_LENGTH) { - errx(EXIT_FAILURE, "do_write_tx: buffer too small"); - } - tx_fifo[tx_fifo_idx++] = c; - status_registers[CC1100_TXBYTES - 0x30]++; -} - -uint8_t write_single(uint8_t c) -{ - DEBUG("write_single\n"); - - if (addr <= 0x2E) { - do_write_conf(c); - } - else if ((addr >= 0x30) && (addr <= 0x3D)) { - do_strobe(); - } - else if (addr == 0x3E) { - do_write_patable(c); - } - else if (addr == 0x3F) { - do_write_tx(c); - } - else { - errx(EXIT_FAILURE, "write_single: unhandled addr: 0x%02X", addr); - } - - return 0; -} - -uint8_t write_burst(uint8_t c) -{ - DEBUG("write_burst\n"); - - if (addr <= 0x2E) { - do_write_conf(c); - addr++; - } - else if ((addr >= 0x30) && (addr <= 0x3D)) { - do_strobe(); - addr++; - } - else if (addr == 0x3E) { - DEBUG("write patable\n"); - } - else if (addr == 0x3F) { - do_write_tx(c); - } - else { - errx(EXIT_FAILURE, "write_single: unhandled addr: 0x%02X", addr); - } - - return 0; -} - -uint8_t do_txrx(uint8_t c) -{ - switch (_native_cc110x_state) { - case STATE_SEL: - c = parse_header(c); - break; - case STATE_WRITE_B: - c = write_burst(c); - break; - case STATE_READ_B: - c = read_burst(c); - break; - case STATE_READ_S: - c = read_single(c); - _native_cc110x_state = STATE_SEL; - break; - case STATE_WRITE_S: - c = write_single(c); - _native_cc110x_state = STATE_SEL; - break; - case STATE_NULL: - //warnx("received command(?) in NULL state"); - c = 0x00; - default: - errx(EXIT_FAILURE, "funny cc110x_ng state"); - } - return c; -} - -void _native_cc1100_register_callback(int event, void *cb) -{ - _native_cc1100_callbacks[event].func = cb; -} - -void _native_cc1100_handle_packet(unsigned char *buf, int size) -{ - unsigned char dst_addr; - - dst_addr = buf[1]; - - /* packet automation */ - - /* monitor mode */ - if ((configuration_registers[CC1100_PKTCTRL1] & 0x03) == 0x00) { - DEBUG("_native_cc1100_handle_packet: not filtering address\n"); - } - /* address filter */ - else { - /* own addr check */ - if (dst_addr == configuration_registers[CC1100_ADDR]) { - DEBUG("_native_cc1100_handle_packet: accept packet, addressed to us\n"); - } - /* 0x00 only broadcast */ - else if ( - ((configuration_registers[CC1100_PKTCTRL1] & 0x03) == 0x02) && - (dst_addr == 0x00) - ) { - DEBUG("_native_cc1100_handle_packet: accept packet, broadcast\n"); - } - /* 0x00 only broadcast */ - else if ( - ((configuration_registers[CC1100_PKTCTRL1] & 0x03) == 0x03) && - ((dst_addr == 0x00) || (dst_addr == 0xFF)) - ) { - DEBUG("_native_cc1100_handle_packet: accept packet, broadcast\n"); - } - else { - DEBUG("_native_cc1100_handle_packet: discard packet addressed to someone else\n"); - return; - } - } - /* length filter */ - /* variable packet length */ - if ((configuration_registers[CC1100_PKTCTRL0] & 0x03) == 0x01) { - if (size > configuration_registers[CC1100_PKTLEN]) { - DEBUG("_native_cc1100_handle_packet: discard packet longer than CC1100_PKTLEN\n"); - return; - } - else { - DEBUG("_native_cc1100_handle_packet: accept packet <= CC1100_PKTLEN\n"); - } - } - /* fixed packet length */ - else if ((configuration_registers[CC1100_PKTCTRL0] & 0x03) == 0x00) { - if (size != configuration_registers[CC1100_PKTLEN]) { - DEBUG("_native_cc1100_handle_packet: discard packet, size differs from CC1100_PKTLEN\n"); - return; - } - else { - DEBUG("_native_cc1100_handle_packet: accept packet == CC1100_PKTLEN\n"); - } - } - else { - errx(EXIT_FAILURE, "_native_cc1100_handle_packet: packet length mode not supported"); - } - - /* copy packet to rx_fifo */ - /* XXX: handle overflow */ - rx_fifo_idx = 0; - memcpy(rx_fifo, buf, size); - status_registers[CC1100_RXBYTES - 0x30] = size; - DEBUG("_native_cc1100_handle_packet: got %d bytes payload\n", size); - - /* toggle interrupt */ - cc110x_gdo2_irq(); -} - -#if 0 /* future ahead */ - -void step_state_idle(void) -{ - switch (addr) { - /* configuration registers: */ - case CC1100_IOCFG2: - case CC1100_IOCFG1: - case CC1100_IOCFG0: - case CC1100_FIFOTHR: - case CC1100_SYNC1: - case CC1100_SYNC0: - case CC1100_PKTLEN: - case CC1100_PKTCTRL1: - case CC1100_PKTCTRL0: - case CC1100_ADDR: - case CC1100_CHANNR: - case CC1100_FSCTRL1: - case CC1100_FSCTRL0: - case CC1100_FREQ2: - case CC1100_FREQ1: - case CC1100_FREQ0: - case CC1100_MDMCFG4: - case CC1100_MDMCFG3: - case CC1100_MDMCFG2: - case CC1100_MDMCFG1: - case CC1100_MDMCFG0: - case CC1100_DEVIATN: - case CC1100_MCSM2: - case CC1100_MCSM1: - case CC1100_MCSM0: - case CC1100_FOCCFG: - case CC1100_BSCFG: - case CC1100_AGCCTRL2: - case CC1100_AGCCTRL1: - case CC1100_AGCCTRL0: - case CC1100_WOREVT1: - case CC1100_WOREVT0: - case CC1100_WORCTRL: - case CC1100_FREND1: - case CC1100_FREND0: - case CC1100_FSCAL3: - case CC1100_FSCAL2: - case CC1100_FSCAL1: - case CC1100_FSCAL0: - case CC1100_RCCTRL1: - case CC1100_RCCTRL0: - case CC1100_FSTEST: - case CC1100_PTEST: - case CC1100_AGCTEST: - case CC1100_TEST2: - case CC1100_TEST1: - case CC1100_TEST0: - /* command strobes */ - case CC1100_SRES: - case CC1100_SFSTXON: - case CC1100_SXOFF: - case CC1100_SCAL: - case CC1100_SRX: - case CC1100_STX: - case CC1100_SIDLE: - case CC1100_SAFC: - case CC1100_SWOR: - case CC1100_SPWD: - case CC1100_SFRX: - case CC1100_SFTX: - case CC1100_SWORRST: - case CC1100_SNOP: - /* patable */ - case CC1100_PATABLE: - /* tx/rx */ - case CC1100_RXFIFO: /* == CC1100_TXFIFO */ - default: - errx(EXIT_FAILURE, "step_state_idle: unhandled addr: %d", addr); - } -} - -void step_state_sleep(void) -{ - ; -} - -void step_state_xtaloff(void) -{ - ; -} - -void step_state_freq_scal(void) -{ - ; -} - -void step_state_freq_sst(void) -{ - ; -} - -void step_state_freq_son(void) -{ - ; -} - -void step_state_tx(void) -{ - ; -} - -void step_state_rx(void) -{ - ; -} - -void step_state_tx_ffuf(void) -{ - ; -} - -void step_state_rx_ffof(void) -{ - ; -} - -void step(void) -{ - switch (internal_state) { - case (STATE_IDLE): - step_state_idle(); - break; - - case (STATE_SLEEP): - step_state_sleep(); - break; - - case (STATE_XTALOFF): - step_state_xtaloff(); - break; - - case (STATE_FREQ_SCAL): - step_state_freq_scal(); - break; - - case (STATE_FREQ_SST): - step_state_freq_sst(); - break; - - case (STATE_FREQ_SON): - step_state_freq_son(); - break; - - case (STATE_TX): - step_state_tx(); - break; - - case (STATE_RX): - step_state_rx(); - break; - - case (STATE_TX_FFUF): - step_state_tx_ffuf(); - break; - - case (STATE_RX_FFOF): - step_state_rx_ffof(); - break; - - default: - errx(EXIT_FAILURE, "internal error in CC1100 state machine"); - } -} - -void _native_cc1100_receive(uint8_t *buf, int len) -{ - ; -} - -#endif diff --git a/cpu/native/cc110x_ng/cc110x_ng_cpu.c b/cpu/native/cc110x_ng/cc110x_ng_cpu.c deleted file mode 100644 index 551010fd779e..000000000000 --- a/cpu/native/cc110x_ng/cc110x_ng_cpu.c +++ /dev/null @@ -1,147 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include - -#include "debug.h" - -#include "tap.h" -#include "cc1100sim.h" -#include "cpu.h" - -#include "cc110x-arch.h" -#include "cc110x_ng.h" -#include "cc110x_spi.h" -#include "cc110x-internal.h" /* CC1100 constants */ - - -static int _native_cc110x_enabled; - -/* arch */ - -/** - * writes to SSP0 data register and reads from it once it is ready - * TODO: move content to simulator - */ -uint8_t cc110x_txrx(uint8_t c) -{ - DEBUG("cc110x_txrx\n"); - return do_txrx(c); -} - -/** - * disables GDO0 interrupt - */ -void cc110x_gdo0_enable(void) -{ - /* this would be for rising/high edge if this was proper hardware */ - DEBUG("cc110x_gdo0_enable\n"); - native_cc110x_gd0_enabled = 1; - return; -} - -/** - * enables GDO0 interrupt - */ -void cc110x_gdo0_disable(void) -{ - DEBUG("cc110x_gdo0_disable\n"); - native_cc110x_gd0_enabled = 0; - return; -} - -/** - * enables GDO2 interrupt - */ -void cc110x_gdo2_enable(void) -{ - /* this would be for falling/low edge if this was proper hardware */ - DEBUG("cc110x_gdo2_enable\n"); - native_cc110x_gd2_enabled = 1; - return; -} - -/** - * disables GDO2 interrupt - */ -void cc110x_gdo2_disable(void) -{ - DEBUG("cc110x_gdo2_disable\n"); - native_cc110x_gd2_enabled = 0; - return; -} - -/** - * enable interrupts for GDO0 and GDO2 - */ -void cc110x_init_interrupts(void) -{ - /* this would be for low edge in both cases if this was proper hardware */ - DEBUG("cc110x_init_interrupts\n"); - cc110x_gdo2_enable(); - cc110x_gdo0_enable(); - return; -} - -/* Disables RX interrupt etc. */ -void cc110x_before_send(void) -{ - DEBUG("cc110x_before_send\n"); - cc110x_gdo2_disable(); - return; -} -void cc110x_after_send(void) -{ - DEBUG("cc110x_after_send\n"); - cc110x_gdo2_enable(); - return; -} - -/* spi */ - -int cc110x_get_gdo0(void) -{ - DEBUG("cc110x_get_gdo0\n"); - return native_cc110x_gd0; -} -int cc110x_get_gdo1(void) -{ - DEBUG("cc110x_get_gdo1\n"); - return native_cc110x_gd1; -} -int cc110x_get_gdo2(void) -{ - DEBUG("cc110x_get_gdo2\n"); - return native_cc110x_gd2--; -} - -void cc110x_spi_init(void) -{ - DEBUG("cc110x_spi_init\n"); - _native_cc110x_enabled = 1; /* power on */ - return; -} - -void cc110x_spi_cs(void) -{ - DEBUG("cc110x_spi_cs\n"); - return; -} -void cc110x_spi_select(void) -{ - DEBUG("___cc110x_spi_select\n"); - _native_cc110x_state = STATE_SEL; - return; -} -void cc110x_spi_unselect(void) -{ - DEBUG("cc110x_spi_unselect\n"); - _native_cc110x_state = STATE_NULL; - return; -} - -/* ng */ diff --git a/cpu/native/include/cc1100sim.h b/cpu/native/include/cc1100sim.h deleted file mode 100644 index 797501119f7e..000000000000 --- a/cpu/native/include/cc1100sim.h +++ /dev/null @@ -1,39 +0,0 @@ -extern uint8_t configuration_registers[((0x2E)+1)]; /* address 0x00 - 0x2E */ -extern uint8_t configuration_registers_idx; /* for burst access */ -extern uint8_t status_registers[((0x3D-0x30)+1)]; /* address 0x30 - 0x3D */ -extern uint8_t rx_fifo[]; /* address 0x3F + RW high (BF: 1011 1111) */ -extern uint8_t rx_fifo_idx; /* for burst access */ -extern uint8_t tx_fifo[]; /* address 0x3F + RW low (3F: 0011 1111) */ -extern uint8_t tx_fifo_idx; /* for burst access */ -extern uint8_t patable[8]; /* address 0x3E */ -extern uint8_t patable_idx; /* for burst access */ - - -extern int native_cc110x_gd0; -extern int native_cc110x_gd1; -extern int native_cc110x_gd2; -extern int native_cc110x_gd0_enabled; -extern int native_cc110x_gd2_enabled; - -extern uint8_t addr; -extern uint8_t _native_cc110x_state; - -uint8_t do_txrx(uint8_t c); -void do_sres(void); -uint8_t do_strobe(void); -uint8_t parse_header(uint8_t c); -uint8_t write_burst(uint8_t c); -uint8_t read_burst(uint8_t c); -uint8_t write_single(uint8_t c); -uint8_t read_single(uint8_t c); - -#define STATE_NULL 0x00 -#define STATE_SEL 0x01 -#define STATE_WRITE_B 0x02 -#define STATE_READ_B 0x03 -#define STATE_READ_S 0x04 -#define STATE_WRITE_S 0x05 - -void _native_cc1100_handle_packet(unsigned char *buf, int size); - -#define CC1100_FIFO_LENGTH 64 diff --git a/cpu/native/include/cpu-conf.h b/cpu/native/include/cpu-conf.h index e631e6249a54..e6c5fc9ef30a 100644 --- a/cpu/native/include/cpu-conf.h +++ b/cpu/native/include/cpu-conf.h @@ -27,7 +27,7 @@ #define TRANSCEIVER_STACK_SIZE (163840) #define MINIMUM_STACK_SIZE (163840) #else /* Linux etc. */ -#define KERNEL_CONF_STACKSIZE_DEFAULT (8192) +#define KERNEL_CONF_STACKSIZE_DEFAULT (KERNEL_CONF_STACKSIZE_PRINTF + 8192) #define KERNEL_CONF_STACKSIZE_IDLE (16384) #define NATIVE_ISR_STACKSIZE (16384) /* undefine the TRANSCEIVER_STACK_SIZE (2048 or 512) defined in transceiver.h */ @@ -38,9 +38,6 @@ #define MINIMUM_STACK_SIZE (16384) #endif /* OS */ -/* for cc110x_ng */ -#define RX_BUF_SIZE (10) -#define TRANSCEIVER_BUFFER_SIZE (3) #define NATIVE_ETH_PROTO 0x1234 #endif /* CPUCONF_H_ */ diff --git a/cpu/native/include/cpu.h b/cpu/native/include/cpu.h index 955bb8552237..484bafef4095 100644 --- a/cpu/native/include/cpu.h +++ b/cpu/native/include/cpu.h @@ -68,12 +68,9 @@ extern unsigned int _native_saved_eip; extern int _native_in_isr; extern int _native_in_syscall; extern int _native_sigpend; -#if (defined(MODULE_UART0) || defined(MODULE_CC110X_NG)) +#ifdef MODULE_UART0 #include extern fd_set _native_rfds; #endif -#ifdef MODULE_CC110X_NG -int _native_set_cc110xng_fds(void); -#endif /** @} */ #endif //_CPU_H diff --git a/cpu/native/include/nativenet.h b/cpu/native/include/nativenet.h new file mode 100644 index 000000000000..3d91466ad0ab --- /dev/null +++ b/cpu/native/include/nativenet.h @@ -0,0 +1,29 @@ +#include + +#define RX_BUF_SIZE (10) +#define TRANSCEIVER_BUFFER_SIZE (3) + +#ifndef NATIVE_MAX_DATA_LENGTH +/* TODO: set this properly: */ +#define NATIVE_MAX_DATA_LENGTH (ETHER_MAX_LEN - (ETHER_HDR_LEN+2)) +#else +#warning be careful not to exceed (ETHER_MAX_LEN) with NATIVE_MAX_DATA_LENGTH +#endif /* NATIVE_MAX_DATA_LENGTH */ + +void nativenet_init(int transceiver_pid); +void nativenet_powerdown(); + +void nativenet_set_monitor(uint8_t mode); + +uint8_t nativenet_send(radio_packet_t *packet); + +int16_t nativenet_set_address(radio_address_t address); +int16_t nativenet_get_address(); + +int16_t nativenet_set_channel(uint8_t channel); +int16_t nativenet_get_channel(); + +uint16_t nativenet_set_pan(uint16_t pan); +uint16_t nativenet_get_pan(); + +void nativenet_switch_to_rx(); diff --git a/cpu/native/include/nativenet_internal.h b/cpu/native/include/nativenet_internal.h new file mode 100644 index 000000000000..a20c33c8b70b --- /dev/null +++ b/cpu/native/include/nativenet_internal.h @@ -0,0 +1,24 @@ +#include "tap.h" + +#define NNEV_PWRDWN 0x01 +#define NNEV_PWRUP 0x02 +#define NNEV_MONITOR 0x03 +#define NNEV_GETCHAN 0x04 +#define NNEV_SETCHAN 0x05 +#define NNEV_GETADDR 0x06 +#define NNEV_SETADDR 0x07 +#define NNEV_GETPAN 0x08 +#define NNEV_SETPAN 0x09 +#define NNEV_SEND 0x0a +#define NNEV_SWTRX 0x0b +#define NNEV_MAXEV 0x0b + +struct rx_buffer_s { + radio_packet_t packet; + char data[NATIVE_MAX_DATA_LENGTH]; +}; + +extern struct rx_buffer_s _nativenet_rx_buffer[]; +extern volatile uint8_t rx_buffer_next; + +void _nativenet_handle_packet(radio_packet_t *packet); diff --git a/cpu/native/include/tap.h b/cpu/native/include/tap.h index 65d1351703d1..c5a5b082c262 100644 --- a/cpu/native/include/tap.h +++ b/cpu/native/include/tap.h @@ -3,6 +3,8 @@ #include +#include "radio/types.h" + /** * create and/or open tap device "name" * @@ -11,9 +13,7 @@ * otherwise a device named "name" is created */ int tap_init(char *name); -int send_buf(void); -void _native_marshall_ethernet(uint8_t *framebuf, uint8_t *data, int data_len); -void _native_cc1100_handle_input(unsigned char *buf, int size); +int send_buf(radio_packet_t *packet); extern int _native_tap_fd; extern unsigned char _native_tap_mac[ETHER_ADDR_LEN]; diff --git a/cpu/native/irq_cpu.c b/cpu/native/irq_cpu.c index 365308aed05f..053d8eb5b7f3 100644 --- a/cpu/native/irq_cpu.c +++ b/cpu/native/irq_cpu.c @@ -167,8 +167,8 @@ unsigned disableIRQ(void) if ((_native_sigpend > 0) && (_native_in_isr == 0)) { DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n"); _native_in_syscall = 0; - printf("disableIRQ: calling swapcontext()\n"); - printf("disableIRQ: _native_cur_ctx == %p, _native_isr_ctx == %p\n", _native_cur_ctx, _native_isr_ctx); + DEBUG("disableIRQ: calling swapcontext()\n"); + DEBUG("disableIRQ: _native_cur_ctx == %p, _native_isr_ctx == %p\n", _native_cur_ctx, _native_isr_ctx); makecontext(&native_isr_context, native_irq_handler, 0); swapcontext(_native_cur_ctx, _native_isr_ctx); } @@ -207,8 +207,8 @@ unsigned enableIRQ(void) if ((_native_sigpend > 0) && (_native_in_isr == 0)) { DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n"); _native_in_syscall = 0; - printf("enableIRQ: calling swapcontext()\n"); - printf("enableIRQ: _native_cur_ctx == %p, _native_isr_ctx == %p\n", _native_cur_ctx, _native_isr_ctx); + DEBUG("enableIRQ: calling swapcontext()\n"); + DEBUG("enableIRQ: _native_cur_ctx == %p, _native_isr_ctx == %p\n", _native_cur_ctx, _native_isr_ctx); makecontext(&native_isr_context, native_irq_handler, 0); swapcontext(_native_cur_ctx, _native_isr_ctx); } @@ -297,7 +297,7 @@ void native_irq_handler() DEBUG("ignoring SIGUSR1\n"); } else { - printf("XXX: no handler for signal %i\n", sig); + DEBUG("XXX: no handler for signal %i\n", sig); errx(1, "XXX: this should not have happened!\n"); } } diff --git a/cpu/native/native_cpu.c b/cpu/native/native_cpu.c index 8323654c9e31..93a96985a6f4 100644 --- a/cpu/native/native_cpu.c +++ b/cpu/native/native_cpu.c @@ -36,7 +36,7 @@ extern volatile tcb_t *active_thread; static ucontext_t end_context; static char __isr_stack[SIGSTKSZ]; -#if (defined(MODULE_UART0) || defined(MODULE_CC110X_NG)) +#ifdef MODULE_UART0 fd_set _native_rfds; #endif diff --git a/cpu/native/net/Makefile b/cpu/native/net/Makefile new file mode 100644 index 000000000000..81c828ba2470 --- /dev/null +++ b/cpu/native/net/Makefile @@ -0,0 +1,6 @@ +INCLUDES += -I$(RIOTBASE)/core/include -I$(RIOTBASE)/sys/include + +MODULE = nativenet + +include $(MAKEBASE)/Makefile.base + diff --git a/cpu/native/net/interface.c b/cpu/native/net/interface.c new file mode 100644 index 000000000000..9da1413cd034 --- /dev/null +++ b/cpu/native/net/interface.c @@ -0,0 +1,186 @@ +#include +#include +#include +#include +#include +#include + +#include + +#define ENABLE_DEBUG (0) +#include "debug.h" +#include "transceiver.h" + +#include "tap.h" +#include "nativenet.h" +#include "nativenet_internal.h" +#include "cpu.h" + +struct nativenet_callback_s { + void (*func)(void); +}; +static struct nativenet_callback_s _nativenet_callbacks[255]; + +struct rx_buffer_s _nativenet_rx_buffer[RX_BUF_SIZE]; +volatile uint8_t rx_buffer_next; + +uint8_t _native_net_chan; +uint16_t _native_net_pan; +uint8_t _native_net_monitor; +static int _native_net_tpid; +radio_address_t _native_net_addr; + +/************************************************************************/ +/* nativenet.h **********************************************************/ +/************************************************************************/ + +void nativenet_init(int transceiver_pid) +{ + DEBUG("nativenet_init(transceiver_pid=%d)", transceiver_pid); + _native_net_pan = 0; + _native_net_chan = 0; + _native_net_monitor = 0; + _native_net_tpid = transceiver_pid; +} + +void nativenet_powerdown() +{ + return; +} + +void nativenet_set_monitor(uint8_t mode) +{ + DEBUG("nativenet_set_monitor(mode=%d)\n", mode); + _native_net_monitor = mode; +} + +int16_t nativenet_set_channel(uint8_t channel) +{ + _native_net_chan = channel; + return _native_net_chan; +} + +int16_t nativenet_get_channel() +{ + return _native_net_chan; +} + +uint16_t nativenet_set_pan(uint16_t pan) +{ + _native_net_pan = pan; + return _native_net_pan; +} + +uint16_t nativenet_get_pan() +{ + return _native_net_pan; +} + +int16_t nativenet_set_address(radio_address_t address) +{ + _native_net_addr = address; + return _native_net_addr; +} + +int16_t nativenet_get_address() +{ + return _native_net_addr; +} + +uint8_t nativenet_send(radio_packet_t *packet) +{ + DEBUG("nativenet_send: Sending packet of length %u to %u: %s\n", packet->length, packet->dst, (char*) packet->data); + + if (send_buf(packet) == -1) { + warnx("nativenet_send: error sending packet"); + } + return 0; +} + +void nativenet_switch_to_rx() +{ + return; +} + +/************************************************************************/ +/* nativenet_internal.h *************************************************/ +/************************************************************************/ + +int _nativenet_register_cb(int event, void *func) +{ + if (event > NNEV_MAXEV) { + DEBUG("_nativenet_register_cb: event > NNEV_MAXEV"); + return -1; + } + + _nativenet_callbacks[event].func = func; + return 0; +} + +int _nativenet_unregister_cb(int event) +{ + if (event > NNEV_MAXEV) { + DEBUG("_nativenet_unregister_cb: event > NNEV_MAXEV"); + return -1; + } + + _nativenet_callbacks[event].func = NULL; + return 0; +} + +void do_cb(int event) +{ + if (event > NNEV_MAXEV) { + DEBUG("do_cb: event > NNEV_MAXEV"); + return; + } + + if (_nativenet_callbacks[event].func != NULL) { + _nativenet_callbacks[event].func(); + } +} + +void _nativenet_handle_packet(radio_packet_t *packet) +{ + uint8_t dst_addr = packet->dst; + + /* address filter / monitor mode */ + if (_native_net_monitor == 1) { + DEBUG("_nativenet_handle_packet: monitoring, not filtering address \n"); + } + else { + /* own addr check */ + if (dst_addr == _native_net_addr) { + DEBUG("_nativenet_handle_packet: accept packet, addressed to us\n"); + } + else if (dst_addr == 0) { + DEBUG("_nativenet_handle_packet: accept packet, broadcast\n"); + } + else { + DEBUG("_nativenet_handle_packet: discard packet addressed to someone else\n"); + return; + } + } + + /* copy packet to rx buffer */ + memcpy(&_nativenet_rx_buffer[rx_buffer_next].data, packet->data, packet->length); + memcpy(&_nativenet_rx_buffer[rx_buffer_next].packet, packet, sizeof(radio_packet_t)); + + /* notify transceiver thread if any */ + if (_native_net_tpid) { + DEBUG("_nativenet_handle_packet: notifying transceiver thread!\n"); + msg_t m; + m.type = (uint16_t) RCV_PKT_NATIVE; + m.content.value = rx_buffer_next; + msg_send_int(&m, _native_net_tpid); + } + else { + DEBUG("_nativenet_handle_packet: no one to notify =(\n"); + } + + /* shift to next buffer element */ + if (++rx_buffer_next == RX_BUF_SIZE) { + rx_buffer_next = 0; + } + +} diff --git a/cpu/native/tap.c b/cpu/native/net/tap.c similarity index 66% rename from cpu/native/tap.c rename to cpu/native/net/tap.c index 8f75f0a1d175..356f0d74bc50 100644 --- a/cpu/native/tap.c +++ b/cpu/native/net/tap.c @@ -20,26 +20,29 @@ #include #endif +#define ENABLE_DEBUG (0) #include "debug.h" #include "cpu.h" #include "cpu-conf.h" #include "tap.h" -#include "cc1100sim.h" -#include "cc110x-internal.h" /* CC1100 constants */ +#include "nativenet.h" +#include "nativenet_internal.h" -#define TAP_BUFFER_LENGTH (CC1100_FIFO_LENGTH + ETHER_HDR_LEN + 1) +#define TAP_BUFFER_LENGTH (ETHER_MAX_LEN) +int _native_marshall_ethernet(uint8_t *framebuf, radio_packet_t *packet); int _native_tap_fd; unsigned char _native_tap_mac[ETHER_ADDR_LEN]; -void _native_handle_cc110xng_input(void) +void _native_handle_tap_input(void) { int nread; unsigned char buf[TAP_BUFFER_LENGTH]; union eth_frame *f; + radio_packet_t p; - DEBUG("_native_handle_cc110xng_input\n"); + DEBUG("_native_handle_tap_input\n"); /* TODO: check whether this is an input or an output event TODO: refactor this into general io-signal multiplexer */ @@ -47,17 +50,21 @@ void _native_handle_cc110xng_input(void) _native_in_syscall = 1; nread = read(_native_tap_fd, buf, TAP_BUFFER_LENGTH); _native_in_syscall = 0; - DEBUG("_native_handle_cc110xng_input - read %d bytes\n", nread); + DEBUG("_native_handle_tap_input - read %d bytes\n", nread); if (nread > 0) { f = (union eth_frame*)&buf; if (ntohs(f->field.header.ether_type) == NATIVE_ETH_PROTO) { nread = nread - ETHER_HDR_LEN; if ((nread - 1) <= 0) { - DEBUG("_native_handle_cc110xng_input: no payload"); + DEBUG("_native_handle_tap_input: no payload"); } else { - nread = buf[ETHER_HDR_LEN]; - _native_cc1100_handle_packet(buf+ETHER_HDR_LEN+1, nread); + /* XXX: check overflow */ + p.length = (uint8_t)buf[ETHER_HDR_LEN]; + p.dst = (uint8_t)buf[ETHER_HDR_LEN+1]; + p.data = buf+ETHER_HDR_LEN+2; + DEBUG("_native_handle_tap_input: received packet of length %u for %u: %s\n", p.length, p.dst, (char*) p.data); + _nativenet_handle_packet(&p); } } else { @@ -68,19 +75,39 @@ void _native_handle_cc110xng_input(void) err(EXIT_FAILURE, "read"); } else { - errx(EXIT_FAILURE, "internal error in _native_handle_cc110xng_input"); + errx(EXIT_FAILURE, "internal error _native_handle_tap_input"); } } -int send_buf(void) +int _native_marshall_ethernet(uint8_t *framebuf, radio_packet_t *packet) +{ + int data_len; + union eth_frame *f; + unsigned char addr[ETHER_ADDR_LEN]; + + f = (union eth_frame*)framebuf; + addr[0] = addr[1] = addr[2] = addr[3] = addr[4] = addr[5] = (char)0xFF; + + memcpy(f->field.header.ether_dhost, addr, ETHER_ADDR_LEN); + memcpy(f->field.header.ether_shost, _native_tap_mac, ETHER_ADDR_LEN); + f->field.header.ether_type = htons(NATIVE_ETH_PROTO); + + /* XXX: check overflow */ + memcpy(f->field.data+2, packet->data, packet->length); + f->field.data[0] = packet->length; + f->field.data[1] = packet->dst; + data_len = packet->length + 2; + + return data_len; +} + +int send_buf(radio_packet_t *packet) { uint8_t buf[TAP_BUFFER_LENGTH]; - int nsent; - uint8_t to_send; + int nsent, to_send; - to_send = status_registers[CC1100_TXBYTES - 0x30]; - _native_marshall_ethernet(buf, tx_fifo, to_send); - to_send += 1; + DEBUG("send_buf: Sending packet of length %u to %u: %s\n", packet->length, packet->dst, (char*) packet->data); + to_send = _native_marshall_ethernet(buf, packet); if ((ETHER_HDR_LEN + to_send) < ETHERMIN) { DEBUG("padding data! (%d ->", to_send); @@ -88,6 +115,8 @@ int send_buf(void) DEBUG("%d)\n", to_send); } + DEBUG("send_buf: trying to send %d bytes\n", to_send); + if ((nsent = write(_native_tap_fd, buf, to_send + ETHER_HDR_LEN)) == -1) {; warn("write"); return -1; @@ -156,7 +185,7 @@ int tap_init(char *name) /*TODO: check OSX vvv */ /* configure signal handler for fds */ - register_interrupt(SIGIO, _native_handle_cc110xng_input); + register_interrupt(SIGIO, _native_handle_tap_input); /* configure fds to send signals on io */ if (fcntl(_native_tap_fd, F_SETOWN, getpid()) == -1) { @@ -172,64 +201,3 @@ int tap_init(char *name) puts("RIOT native tap initialized."); return _native_tap_fd; } - -void _native_marshall_ethernet(uint8_t *framebuf, uint8_t *data, int data_len) -{ - union eth_frame *f; - unsigned char addr[ETHER_ADDR_LEN]; - - f = (union eth_frame*)framebuf; - addr[0] = addr[1] = addr[2] = addr[3] = addr[4] = addr[5] = (char)0xFF; - - //memcpy(f->field.header.ether_dhost, dst, ETHER_ADDR_LEN); - memcpy(f->field.header.ether_dhost, addr, ETHER_ADDR_LEN); - //memcpy(f->field.header.ether_shost, src, ETHER_ADDR_LEN); - memcpy(f->field.header.ether_shost, _native_tap_mac, ETHER_ADDR_LEN); - f->field.header.ether_type = htons(NATIVE_ETH_PROTO); - memcpy(f->field.data+1, data, data_len); - f->field.data[0] = (uint8_t)data_len; -} - -#ifdef TAPTESTBINARY -/** - * test tap device - */ -int main(int argc, char *argv[]) -{ - int fd; - unsigned char buffer[2048]; - - if (argc < 2) { - errx(EXIT_FAILURE, "you need to specify a tap name"); - } - fd = tap_init(argv[1]); - - printf("trying to write to fd: %i\n", _native_tap_fd); - char *payld = "abcdefg"; - int data_len = strlen(payld); - _native_marshall_ethernet(buffer, payld, data_len); - if (write(_native_tap_fd, buffer, ETHER_HDR_LEN + data_len) == -1) { - err(EXIT_FAILURE, "write"); - } - - printf("reading\n"); - int nread; - while (1) { - /* Note that "buffer" should be at least the MTU size of the - * interface, eg 1500 bytes */ - nread = read(fd,buffer,sizeof(buffer)); - if(nread < 0) { - warn("Reading from interface"); - if (close(fd) == -1) { - warn("close"); - } - exit(EXIT_FAILURE); - } - - /* Do whatever with the data */ - printf("Read %d bytes\n", nread); - } - - return EXIT_SUCCESS; -} -#endif diff --git a/cpu/native/startup.c b/cpu/native/startup.c index fe371cd3ba51..74f28f8b654f 100644 --- a/cpu/native/startup.c +++ b/cpu/native/startup.c @@ -30,7 +30,7 @@ extern void native_interrupt_init(void); __attribute__((constructor)) static void startup(int argc, char **argv) { -#ifdef MODULE_CC110X_NG +#ifdef MODULE_NATIVENET if (argc < 2) { printf("usage: %s \n", argv[0]); exit(EXIT_FAILURE); @@ -39,7 +39,7 @@ __attribute__((constructor)) static void startup(int argc, char **argv) native_cpu_init(); native_interrupt_init(); -#ifdef MODULE_CC110X_NG +#ifdef MODULE_NATIVENET tap_init(argv[1]); #endif diff --git a/drivers/cc110x_ng/include/cc110x-internal.h b/drivers/cc110x_ng/include/cc110x-internal.h index d3409e99792f..392b30626d91 100644 --- a/drivers/cc110x_ng/include/cc110x-internal.h +++ b/drivers/cc110x_ng/include/cc110x-internal.h @@ -88,7 +88,7 @@ #define CC1100_WRITE_BURST (0x40) ///< Offset for burst write. #define CC1100_READ_SINGLE (0x80) ///< Offset for read single byte. #define CC1100_READ_BURST (0xC0) ///< Offset for read burst. -#define CC1100_NOBYTE (0xFF) ///< No command (for reading). +#define CC1100_NOBYTE (0x00) ///< No command (for reading). /** @} */ /** diff --git a/sys/include/transceiver.h b/sys/include/transceiver.h index ae35a4b9a700..5ce94ab50824 100644 --- a/sys/include/transceiver.h +++ b/sys/include/transceiver.h @@ -54,6 +54,11 @@ #define PAYLOAD_SIZE (MC1322X_MAX_DATA_LENGTH) #endif #endif +#ifdef MODULE_NATIVENET +#if (NATIVE_MAX_DATA_LENGTH > PAYLOAD_SIZE) +#define PAYLOAD_SIZE (NATIVE_MAX_DATA_LENGTH) +#endif +#endif /* The maximum of threads to register */ #define TRANSCEIVER_MAX_REGISTERED (4) @@ -69,6 +74,7 @@ #define TRANSCEIVER_CC1020 (0x02) ///< CC1020 transceivers #define TRANSCEIVER_CC2420 (0x04) ///< CC2420 transceivers #define TRANSCEIVER_MC1322X (0x08) ///< MC1322X transceivers +#define TRANSCEIVER_NATIVE (0x10) ///< NATIVE transceivers /** * @brief Data type for transceiver specification @@ -84,6 +90,7 @@ enum transceiver_msg_type_t { RCV_PKT_CC1100, ///< packet was received by CC1100 transceiver RCV_PKT_CC2420, ///< packet was received by CC2420 transceiver RCV_PKT_MC1322X, ///< packet was received by mc1322x transceiver + RCV_PKT_NATIVE, ///< packet was received by native transceiver /* Message types for transceiver <-> upper layer communication */ PKT_PENDING, ///< packet pending in transceiver buffer diff --git a/sys/shell/commands/Makefile b/sys/shell/commands/Makefile index 8ab148c8d93f..6e817f8ae100 100644 --- a/sys/shell/commands/Makefile +++ b/sys/shell/commands/Makefile @@ -13,6 +13,10 @@ ifneq (,$(findstring cc110x,$(USEMODULE))) INCLUDES += -I$(RIOTBASE)/drivers/cc110x/ SRC += sc_cc1100.c endif +ifneq (,$(findstring nativenet,$(USEMODULE))) + INCLUDES += -I$(RIOTBASE)/cpu/native/include + SRC += sc_nativenet.c +endif ifneq (,$(findstring mci,$(USEMODULE))) SRC += sc_disk.c endif diff --git a/sys/shell/commands/sc_nativenet.c b/sys/shell/commands/sc_nativenet.c new file mode 100644 index 000000000000..2fc1b5dbae7f --- /dev/null +++ b/sys/shell/commands/sc_nativenet.c @@ -0,0 +1,127 @@ +/** + * Shell commands for native transceiver + * + * Copyright (C) 2013 Ludwig Ortmann. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup shell_commands + * @{ + * @file sc_nativenet.c + * @brief provides shell commands to configure nativenet transceiver + * @author Ludwig Ortmann + * @} + */ + +#include +#include +#include +#include + +#include "transceiver.h" +#include "nativenet.h" +#include "msg.h" + +#define TEXT_SIZE (255) /* XXX: this aint enough for everybody */ + +char text_msg[TEXT_SIZE]; +msg_t mesg; +transceiver_command_t tcmd; + +void _nativenet_get_set_address_handler(char *addr) +{ + int16_t a; + + tcmd.transceivers = TRANSCEIVER_NATIVE; + tcmd.data = &a; + mesg.content.ptr = (char *) &tcmd; + a = (int16_t)atoi(addr + 5); + + if (strlen(addr) > 5) { + printf("[nativenet] trying to set address %" PRIi16 "\n", a); + mesg.type = SET_ADDRESS; + } + else { + mesg.type = GET_ADDRESS; + } + + msg_send_receive(&mesg, &mesg, transceiver_pid); + printf("[nativenet] got address: %i\n", a); +} + +void _nativenet_get_set_channel_handler(char *chan) +{ + int16_t c; + + tcmd.transceivers = TRANSCEIVER_NATIVE; + tcmd.data = &c; + mesg.content.ptr = (char *) &tcmd; + c = atoi(chan + 5); + + if (strlen(chan) > 5) { + printf("[nativenet] Trying to set channel %i\n", c); + mesg.type = SET_CHANNEL; + } + else { + mesg.type = GET_CHANNEL; + } + + msg_send_receive(&mesg, &mesg, transceiver_pid); + printf("[nativenet] Got channel: %i\n", c); +} + +void _nativenet_send_handler(char *pkt) +{ + radio_packet_t p; + uint32_t response; + uint16_t addr; + char *tok; + + tcmd.transceivers = TRANSCEIVER_NATIVE; + tcmd.data = &p; + + tok = strtok(pkt + 7, " "); + + if (tok) { + addr = atoi(tok); + tok = strtok(NULL, " "); + + if (tok) { + memset(text_msg, 0, TEXT_SIZE); + memcpy(text_msg, tok, strlen(tok)); + p.data = (uint8_t *) text_msg; + p.length = strlen(text_msg) + 1; + p.dst = addr; + mesg.type = SND_PKT; + mesg.content.ptr = (char *)&tcmd; + printf("[nativenet] Sending packet of length %u to %u: %s\n", p.length, p.dst, (char*) p.data); + msg_send_receive(&mesg, &mesg, transceiver_pid); + response = mesg.content.value; + printf("[nativenet] Packet sent: %" PRIu32 "\n", response); + return; + } + } + + puts("Usage:\ttxtsnd "); +} + +void _nativenet_monitor_handler(char *mode) +{ + unsigned int m; + + tcmd.transceivers = TRANSCEIVER_NATIVE; + tcmd.data = &m; + mesg.content.ptr = (char *) &tcmd; + m = atoi(mode + 8); + + if (strlen(mode) > 8) { + printf("Setting monitor mode: %u\n", m); + mesg.type = SET_MONITOR; + msg_send(&mesg, transceiver_pid, 1); + } + else { + puts("Usage:\nmonitor "); + } +} diff --git a/sys/shell/commands/shell_commands.c b/sys/shell/commands/shell_commands.c index e075bf36d581..b9bc83e5020d 100644 --- a/sys/shell/commands/shell_commands.c +++ b/sys/shell/commands/shell_commands.c @@ -70,6 +70,15 @@ extern void _cc2420_monitor_handler(char *mode); #endif #endif +#ifdef MODULE_TRANSCEIVER +#ifdef MODULE_NATIVENET +extern void _nativenet_get_set_address_handler(char *addr); +extern void _nativenet_get_set_channel_handler(char *chan); +extern void _nativenet_send_handler(char *pkt); +extern void _nativenet_monitor_handler(char *mode); +#endif +#endif + #ifdef MODULE_MCI extern void _get_sectorsize(char *unused); extern void _get_blocksize(char *unused); @@ -123,6 +132,14 @@ const shell_command_t _shell_command_list[] = { {"monitor", "Enables or disables address checking for the CC2420 transceiver", _cc2420_monitor_handler}, #endif #endif +#ifdef MODULE_TRANSCEIVER +#ifdef MODULE_NATIVENET + {"addr", "Gets or sets the address for the native transceiver", _nativenet_get_set_address_handler}, + {"chan", "Gets or sets the channel for the native transceiver", _nativenet_get_set_channel_handler}, + {"txtsnd", "Sends a text message to a given node via the native transceiver", _nativenet_send_handler}, + {"monitor", "Enables or disables address checking for the native transceiver", _nativenet_monitor_handler}, +#endif +#endif #ifdef MODULE_MCI {DISK_READ_SECTOR_CMD, "Reads the specified sector of inserted memory card", _read_sector}, {DISK_READ_BYTES_CMD, "Reads the specified bytes from inserted memory card", _read_bytes}, diff --git a/sys/transceiver/transceiver.c b/sys/transceiver/transceiver.c index 39108b22989f..8935e8f8b7fe 100644 --- a/sys/transceiver/transceiver.c +++ b/sys/transceiver/transceiver.c @@ -23,6 +23,7 @@ #include "thread.h" #include "msg.h" +#include "irq.h" #include "radio/types.h" @@ -47,6 +48,11 @@ #include "maca_packet.h" #endif +#ifdef MODULE_NATIVENET +#include "nativenet.h" +#include "nativenet_internal.h" +#endif + #define ENABLE_DEBUG (0) #if ENABLE_DEBUG #undef TRANSCEIVER_STACK_SIZE @@ -97,6 +103,8 @@ void cc1100_packet_monitor(void *payload, int payload_size, protocol_t protocol, void receive_cc1100_packet(radio_packet_t *trans_p); #elif MODULE_CC2420 static void receive_cc2420_packet(radio_packet_t *trans_p); +#elif MODULE_NATIVENET +static void receive_nativenet_packet(radio_packet_t *trans_p); #endif static uint8_t send_packet(transceiver_type_t t, void *pkt); static int16_t get_channel(transceiver_type_t t); @@ -134,7 +142,7 @@ void transceiver_init(transceiver_type_t t) reg[i].pid = 0; } /* check if a non defined bit is set */ - if (t & ~(TRANSCEIVER_CC1100 | TRANSCEIVER_CC2420 | TRANSCEIVER_MC1322X)) { + if (t & ~(TRANSCEIVER_CC1100 | TRANSCEIVER_CC2420 | TRANSCEIVER_MC1322X | TRANSCEIVER_NATIVE)) { puts("Invalid transceiver type"); } else { @@ -171,6 +179,11 @@ int transceiver_start(void) else if (transceivers & TRANSCEIVER_MC1322X) { maca_init(); } +#endif +#ifdef MODULE_NATIVENET + else if (transceivers & TRANSCEIVER_NATIVE) { + nativenet_init(transceiver_pid); + } #endif return transceiver_pid; } @@ -222,6 +235,7 @@ void run(void) case RCV_PKT_CC1100: case RCV_PKT_CC2420: case RCV_PKT_MC1322X: + case RCV_PKT_NATIVE: receive_packet(m.type, m.content.value); break; case SND_PKT: @@ -348,6 +362,12 @@ static void receive_packet(uint16_t type, uint8_t pos) #else trans_p = NULL; type = TRANSCEIVER_NONE; +#endif + } + else if (type == RCV_PKT_NATIVE) { +#ifdef MODULE_NATIVENET + receive_nativenet_packet(trans_p); + type = TRANSCEIVER_NATIVE; #endif } else { @@ -452,6 +472,26 @@ void receive_mc1322x_packet(radio_packet_t *trans_p) { #endif +#ifdef MODULE_NATIVENET +void receive_nativenet_packet(radio_packet_t *trans_p) { + unsigned state; + radio_packet_t *p = &_nativenet_rx_buffer[rx_buffer_pos].packet; + + /* disable interrupts while copying packet */ + state = disableIRQ(); + + DEBUG("Handling nativenet packet\n"); + + memcpy(trans_p, p, sizeof(radio_packet_t)); + memcpy((void*) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), p->data, p->length); + trans_p->data = (uint8_t*) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]); + + DEBUG("Packet %p was from %hu to %hu, size: %u\n", trans_p, trans_p->src, trans_p->dst, trans_p->length); + + /* reset interrupts */ + restoreIRQ(state); +} +#endif /*------------------------------------------------------------------------------------*/ /* * @brief Sends a radio packet to the receiver @@ -526,6 +566,11 @@ static uint8_t send_packet(transceiver_type_t t, void *pkt) maca_set_tx_packet( maca_pkt ); res = 1; break; +#endif +#ifdef MODULE_NATIVENET + case TRANSCEIVER_NATIVE: + res = nativenet_send(&p); + break; #endif default: puts("Unknown transceiver"); @@ -565,6 +610,10 @@ static int16_t set_channel(transceiver_type_t t, void *channel) case TRANSCEIVER_MC1322X: maca_set_channel(c); return c; ///< TODO: should be changed! implement get channel +#endif +#ifdef MODULE_NATIVENET + case TRANSCEIVER_NATIVE: + return nativenet_set_channel(c); #endif default: return -1; @@ -593,8 +642,14 @@ static int16_t get_channel(transceiver_type_t t) case TRANSCEIVER_CC2420: return cc2420_get_channel(); #endif +#ifdef MODULE_MC1322X case TRANSCEIVER_MC1322X: ///< TODO:implement return maca_get_channel(); +#endif +#ifdef MODULE_NATIVENET + case TRANSCEIVER_NATIVE: + return nativenet_get_channel(); +#endif default: return -1; } @@ -615,6 +670,10 @@ static uint16_t set_pan(transceiver_type_t t, void *pan) { #ifdef MODULE_CC2420 case TRANSCEIVER_CC2420: return cc2420_set_pan(c); +#endif +#ifdef MODULE_NATIVENET + case TRANSCEIVER_NATIVE: + return nativenet_set_pan(c); #endif default: /* get rid of compiler warning about unused variable */ @@ -635,6 +694,10 @@ static uint16_t get_pan(transceiver_type_t t) { #ifdef MODULE_CC2420 case TRANSCEIVER_CC2420: return cc2420_get_pan(); +#endif +#ifdef MODULE_NATIVENET + case TRANSCEIVER_NATIVE: + return nativenet_get_pan(); #endif default: return -1; @@ -666,6 +729,10 @@ static int16_t get_address(transceiver_type_t t) #ifdef MODULE_MC1322X case TRANSCEIVER_MC1322X: return maca_get_address(); +#endif +#ifdef MODULE_NATIVENET + case TRANSCEIVER_NATIVE: + return nativenet_get_address(); #endif default: return -1; @@ -700,6 +767,10 @@ static int16_t set_address(transceiver_type_t t, void *address) #ifdef MODULE_MC1322X case TRANSCEIVER_MC1322X: return maca_set_address(addr); +#endif +#ifdef MODULE_NATIVENET + case TRANSCEIVER_NATIVE: + return nativenet_set_address(addr); #endif default: return -1; @@ -724,6 +795,11 @@ static void set_monitor(transceiver_type_t t, void *mode) case TRANSCEIVER_CC2420: cc2420_set_monitor(*((uint8_t*) mode)); break; +#endif +#ifdef MODULE_NATIVENET + case TRANSCEIVER_NATIVE: + nativenet_set_monitor(*((uint8_t*) mode)); + break; #endif default: break; @@ -753,6 +829,11 @@ static void powerdown(transceiver_type_t t) case TRANSCEIVER_MC1322X: maca_off(); break; +#endif +#ifdef MODULE_NATIVENET + case TRANSCEIVER_NATIVE: + nativenet_powerdown(); + break; #endif default: break; @@ -772,6 +853,11 @@ static void switch_to_rx(transceiver_type_t t) case TRANSCEIVER_CC2420: cc2420_switch_to_rx(); break; +#endif +#ifdef MODULE_NATIVENET + case TRANSCEIVER_NATIVE: + nativenet_switch_to_rx(); + break; #endif default: break;