1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-16 01:53:51 +01:00

native cc1100x_ng network

not properly passing received data to transceiver atm
This commit is contained in:
Ludwig Ortmann 2013-06-26 23:29:09 +02:00
parent 1411a0df0f
commit a634709c00
17 changed files with 1281 additions and 50 deletions

View File

@ -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

26
cpu/native/README Normal file
View File

@ -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.

View File

@ -0,0 +1,756 @@
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include <inttypes.h>
#include <string.h>
#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

View File

@ -1,44 +1,36 @@
#include <stdio.h>
#include <err.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <debug.h>
#include <arpa/inet.h>
#include <cc110x-arch.h>
#include <cc110x_ng.h>
#include <cc110x_spi.h>
#include <cc110x-internal.h> /* 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;
}

View File

@ -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);

View File

@ -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

View File

@ -18,15 +18,15 @@
#include <signal.h>
/* 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_ */

View File

@ -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 <sys/select.h>
extern fd_set _native_rfds;
#endif
#ifdef MODULE_CC110X_NG
int _native_set_cc110xng_fds(void);
#endif
/** @} */
#endif //_CPU_H

29
cpu/native/include/tap.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef _TAP_H
#define _TAP_H
#include <net/ethernet.h>
/**
* 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 */

View File

@ -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;
}

View File

@ -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) {

View File

@ -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
*/

View File

@ -15,17 +15,33 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <kernel_internal.h>
#include <cpu.h>
#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 <tap interface>\n", argv[0]);
exit(EXIT_FAILURE);
}
#endif
native_cpu_init();
native_interrupt_init();
#ifdef MODULE_CC110X_NG
tap_init(argv[1]);
#endif
board_init();

235
cpu/native/tap.c Normal file
View File

@ -0,0 +1,235 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <err.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <arpa/inet.h>
#ifdef __MACH__
#define _POSIX_C_SOURCE
#include <net/if.h>
#undef _POSIX_C_SOURCE
#include <ifaddrs.h>
#include <net/if_dl.h>
#else
#include <net/if.h>
#include <linux/if_tun.h>
#include <linux/if_ether.h>
#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

47
cpu/native/tapsetup-osx.sh Executable file
View File

@ -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) <create [count]|delete>"
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

50
cpu/native/tapsetup.sh Executable file
View File

@ -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) <create [count]|delete>"
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

View File

@ -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).
/** @} */
/**