mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
[drivers/cc110x_ng]
* added register interface (it is now possible to communicate with cc1100 via SPI (e.g. on MSB boards) or directly via registers like on eZ430-Chronos
This commit is contained in:
parent
1eec8e170e
commit
e1b3dcf40d
@ -29,5 +29,6 @@ SubDir TOP drivers cc110x_ng ;
|
||||
|
||||
HDRS += $(TOP)/drivers/cc110x_ng ;
|
||||
|
||||
Module cc110x_ng : cc1100.c cc1100-rx.c cc1100-tx.c cc1100-defaultSettings.c cc1100_spi.c : board_cc1100 swtimer ;
|
||||
|
||||
Module cc110x_ng : cc1100.c cc1100-rx.c cc1100-tx.c cc1100-defaultSettings.c : swtimer ;
|
||||
Module cc110x_spi : cc1100_spi.c : board_cc1100 ;
|
||||
Module cc110x_reg : cc1100-reg.c ;
|
||||
|
@ -2,48 +2,49 @@
|
||||
#define CC1100_CONFIG_H
|
||||
|
||||
#include <timex.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** CC1100 register configuration */
|
||||
typedef struct {
|
||||
uint8_t IOCFG2;
|
||||
uint8_t IOCFG1;
|
||||
uint8_t IOCFG0;
|
||||
uint8_t FIFOTHR;
|
||||
uint8_t SYNC1;
|
||||
uint8_t SYNC0;
|
||||
uint8_t PKTLEN;
|
||||
uint8_t PKTCTRL1;
|
||||
uint8_t PKTCTRL0;
|
||||
uint8_t ADDR;
|
||||
uint8_t CHANNR;
|
||||
uint8_t FSCTRL1;
|
||||
uint8_t FSCTRL0;
|
||||
uint8_t FREQ2;
|
||||
uint8_t FREQ1;
|
||||
uint8_t FREQ0;
|
||||
uint8_t MDMCFG4;
|
||||
uint8_t MDMCFG3;
|
||||
uint8_t MDMCFG2;
|
||||
uint8_t MDMCFG1;
|
||||
uint8_t MDMCFG0;
|
||||
uint8_t DEVIATN;
|
||||
uint8_t MCSM2;
|
||||
uint8_t MCSM1;
|
||||
uint8_t MCSM0;
|
||||
uint8_t FOCCFG;
|
||||
uint8_t BSCFG;
|
||||
uint8_t AGCCTRL2;
|
||||
uint8_t AGCCTRL1;
|
||||
uint8_t AGCCTRL0;
|
||||
uint8_t WOREVT1;
|
||||
uint8_t WOREVT0;
|
||||
uint8_t WORCTRL;
|
||||
uint8_t FREND1;
|
||||
uint8_t FREND0;
|
||||
uint8_t FSCAL3;
|
||||
uint8_t FSCAL2;
|
||||
uint8_t FSCAL1;
|
||||
uint8_t FSCAL0;
|
||||
uint8_t _IOCFG2;
|
||||
uint8_t _IOCFG1;
|
||||
uint8_t _IOCFG0;
|
||||
uint8_t _FIFOTHR;
|
||||
uint8_t _SYNC1;
|
||||
uint8_t _SYNC0;
|
||||
uint8_t _PKTLEN;
|
||||
uint8_t _PKTCTRL1;
|
||||
uint8_t _PKTCTRL0;
|
||||
uint8_t _ADDR;
|
||||
uint8_t _CHANNR;
|
||||
uint8_t _FSCTRL1;
|
||||
uint8_t _FSCTRL0;
|
||||
uint8_t _FREQ2;
|
||||
uint8_t _FREQ1;
|
||||
uint8_t _FREQ0;
|
||||
uint8_t _MDMCFG4;
|
||||
uint8_t _MDMCFG3;
|
||||
uint8_t _MDMCFG2;
|
||||
uint8_t _MDMCFG1;
|
||||
uint8_t _MDMCFG0;
|
||||
uint8_t _DEVIATN;
|
||||
uint8_t _MCSM2;
|
||||
uint8_t _MCSM1;
|
||||
uint8_t _MCSM0;
|
||||
uint8_t _FOCCFG;
|
||||
uint8_t _BSCFG;
|
||||
uint8_t _AGCCTRL2;
|
||||
uint8_t _AGCCTRL1;
|
||||
uint8_t _AGCCTRL0;
|
||||
uint8_t _WOREVT1;
|
||||
uint8_t _WOREVT0;
|
||||
uint8_t _WORCTRL;
|
||||
uint8_t _FREND1;
|
||||
uint8_t _FREND0;
|
||||
uint8_t _FSCAL3;
|
||||
uint8_t _FSCAL2;
|
||||
uint8_t _FSCAL1;
|
||||
uint8_t _FSCAL0;
|
||||
} cc1100_reg_t;
|
||||
|
||||
/** CC1100 radio configuration */
|
||||
@ -62,9 +63,9 @@ typedef struct
|
||||
uint32_t TCP; ///< Time to compute packet
|
||||
unsigned RPS : 16; ///< Raw packets sent to transmit last packet
|
||||
unsigned RTC : 8; ///< Retransmission count of last send packet
|
||||
unsigned RSSI : 8; ///< The RSSI value of last received packet
|
||||
unsigned _RSSI : 8; ///< The RSSI value of last received packet
|
||||
unsigned RSSI_SEND : 8; ///< The RSSI value of the last send unicast packet of this node
|
||||
unsigned LQI : 8; ///< The LQI value of the last received packet
|
||||
unsigned _LQI : 8; ///< The LQI value of the last received packet
|
||||
unsigned LL_ACK : 1; ///< Is set if Link-Level ACK is received, otherwise 0 (reset on new burst)
|
||||
unsigned CAA : 1; ///< The status of the air (1 = air free, 0 = air not free)
|
||||
unsigned CRC : 1; ///< The CRC status of last received packet (1 = OK, 0 = not OK)
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <cc1100-config.h>
|
||||
#include <cc1100-defaultSettings.h>
|
||||
#include <cc1100_spi.h>
|
||||
#include <cc1100-reg.h>
|
||||
|
||||
#include <hwtimer.h>
|
||||
#include <msg.h>
|
||||
@ -35,15 +36,15 @@ void cc1100_rx_handler(void) {
|
||||
cc1100_statistic.packets_in_while_tx++;
|
||||
return;
|
||||
}
|
||||
cc1100_rx_buffer[rx_buffer_next].rssi = rflags.RSSI;
|
||||
cc1100_rx_buffer[rx_buffer_next].lqi = rflags.LQI;
|
||||
cc1100_rx_buffer[rx_buffer_next].rssi = rflags._RSSI;
|
||||
cc1100_rx_buffer[rx_buffer_next].lqi = rflags._LQI;
|
||||
|
||||
// Valid packet. After a wake-up, the radio should be in IDLE.
|
||||
// So put CC1100 to RX for WOR_TIMEOUT (have to manually put
|
||||
// the radio back to sleep/WOR).
|
||||
//cc1100_spi_write_reg(CC1100_MCSM0, 0x08); // Turn off FS-Autocal
|
||||
cc1100_spi_write_reg(CC1100_MCSM2, 0x07); // Configure RX_TIME (until end of packet)
|
||||
cc1100_spi_strobe(CC1100_SRX);
|
||||
cc1100_write_reg(CC1100_MCSM2, 0x07); // Configure RX_TIME (until end of packet)
|
||||
cc1100_strobe(CC1100_SRX);
|
||||
hwtimer_wait(IDLE_TO_RX_TIME);
|
||||
radio_state = RADIO_RX;
|
||||
|
||||
@ -67,14 +68,14 @@ void cc1100_rx_handler(void) {
|
||||
rflags.TOF = 0;
|
||||
|
||||
// CRC false or RX buffer full -> clear RX FIFO in both cases
|
||||
cc1100_spi_strobe(CC1100_SIDLE); // Switch to IDLE (should already be)...
|
||||
cc1100_spi_strobe(CC1100_SFRX); // ...for flushing the RX FIFO
|
||||
cc1100_strobe(CC1100_SIDLE); // Switch to IDLE (should already be)...
|
||||
cc1100_strobe(CC1100_SFRX); // ...for flushing the RX FIFO
|
||||
|
||||
// If packet interrupted this nodes send call,
|
||||
// don't change anything after this point.
|
||||
if (radio_state == RADIO_AIR_FREE_WAITING)
|
||||
{
|
||||
cc1100_spi_strobe(CC1100_SRX);
|
||||
cc1100_strobe(CC1100_SRX);
|
||||
hwtimer_wait(IDLE_TO_RX_TIME);
|
||||
return;
|
||||
}
|
||||
@ -96,11 +97,11 @@ static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length) {
|
||||
uint8_t packetLength = 0;
|
||||
|
||||
/* Any bytes available in RX FIFO? */
|
||||
if ((cc1100_spi_read_status(CC1100_RXBYTES) & BYTES_IN_RXFIFO)) {
|
||||
if ((cc1100_read_status(CC1100_RXBYTES) & BYTES_IN_RXFIFO)) {
|
||||
//LED_GREEN_TOGGLE;
|
||||
LED_RED_TOGGLE;
|
||||
//LED_RED_TOGGLE;
|
||||
// Read length byte (first byte in RX FIFO)
|
||||
packetLength = cc1100_spi_read_reg(CC1100_RXFIFO);
|
||||
packetLength = cc1100_read_reg(CC1100_RXFIFO);
|
||||
// Read data from RX FIFO and store in rxBuffer
|
||||
if (packetLength <= length)
|
||||
{
|
||||
@ -108,13 +109,13 @@ static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length) {
|
||||
rxBuffer[0] = packetLength;
|
||||
|
||||
// Read the rest of the packet
|
||||
cc1100_spi_readburst_reg(CC1100_RXFIFO, (char*)rxBuffer+1, packetLength);
|
||||
cc1100_readburst_reg(CC1100_RXFIFO, (char*)rxBuffer+1, packetLength);
|
||||
|
||||
// Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI)
|
||||
cc1100_spi_readburst_reg(CC1100_RXFIFO, (char*)status, 2);
|
||||
cc1100_readburst_reg(CC1100_RXFIFO, (char*)status, 2);
|
||||
|
||||
// Store RSSI value of packet
|
||||
rflags.RSSI = status[I_RSSI];
|
||||
rflags._RSSI = status[I_RSSI];
|
||||
|
||||
// MSB of LQI is the CRC_OK bit
|
||||
rflags.CRC = (status[I_LQI] & CRC_OK) >> 7;
|
||||
@ -123,7 +124,7 @@ static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length) {
|
||||
}
|
||||
|
||||
// Bit 0-6 of LQI indicates the link quality (LQI)
|
||||
rflags.LQI = status[I_LQI] & LQI_EST;
|
||||
rflags._LQI = status[I_LQI] & LQI_EST;
|
||||
|
||||
return rflags.CRC;
|
||||
}
|
||||
@ -135,14 +136,14 @@ static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length) {
|
||||
}
|
||||
/* no bytes in RX FIFO */
|
||||
else {
|
||||
LED_RED_TOGGLE;
|
||||
//LED_RED_TOGGLE;
|
||||
// RX FIFO get automatically flushed if return value is false
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t receive_packet(uint8_t *rxBuffer, uint8_t length) {
|
||||
uint8_t pkt_len_cfg = cc1100_spi_read_reg(CC1100_PKTCTRL0) & PKT_LENGTH_CONFIG;
|
||||
uint8_t pkt_len_cfg = cc1100_read_reg(CC1100_PKTCTRL0) & PKT_LENGTH_CONFIG;
|
||||
if (pkt_len_cfg == VARIABLE_PKTLEN)
|
||||
{
|
||||
return receive_packet_variable(rxBuffer, length);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <cc1100-internal.h>
|
||||
#include <cc1100-arch.h>
|
||||
#include <cc1100_spi.h>
|
||||
#include <cc1100-reg.h>
|
||||
|
||||
#include <irq.h>
|
||||
|
||||
@ -38,15 +39,15 @@ uint8_t cc1100_send(cc1100_packet_t *packet) {
|
||||
cc1100_before_send();
|
||||
|
||||
// But CC1100 in IDLE mode to flush the FIFO
|
||||
cc1100_spi_strobe(CC1100_SIDLE);
|
||||
cc1100_strobe(CC1100_SIDLE);
|
||||
// Flush TX FIFO to be sure it is empty
|
||||
cc1100_spi_strobe(CC1100_SFTX);
|
||||
cc1100_strobe(CC1100_SFTX);
|
||||
// Write packet into TX FIFO
|
||||
cc1100_spi_writeburst_reg(CC1100_TXFIFO, (char*) packet, size);
|
||||
cc1100_writeburst_reg(CC1100_TXFIFO, (char*) packet, size);
|
||||
// Switch to TX mode
|
||||
abort_count = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_strobe(CC1100_STX);
|
||||
cc1100_strobe(CC1100_STX);
|
||||
// Wait for GDO2 to be set -> sync word transmitted
|
||||
while (cc1100_get_gdo2() == 0) {
|
||||
abort_count++;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <cc1100-defaultSettings.h>
|
||||
#include <cc1100-internal.h>
|
||||
#include <cc1100_spi.h>
|
||||
#include <cc1100-reg.h>
|
||||
|
||||
#include <hwtimer.h>
|
||||
#include <config.h>
|
||||
@ -39,20 +40,22 @@ void cc1100_init(int tpid) {
|
||||
|
||||
rx_buffer_next = 0;
|
||||
|
||||
#ifdef MODULE_CC110X_SPI
|
||||
/* Initialize SPI */
|
||||
cc1100_spi_init();
|
||||
#endif
|
||||
|
||||
/* Load driver & reset */
|
||||
power_up_reset();
|
||||
|
||||
/* Write configuration to configuration registers */
|
||||
cc1100_spi_writeburst_reg(0x00, cc1100_conf, CC1100_CONF_SIZE);
|
||||
cc1100_writeburst_reg(0x00, cc1100_conf, CC1100_CONF_SIZE);
|
||||
|
||||
/* Write PATABLE (power settings) */
|
||||
cc1100_spi_write_reg(CC1100_PATABLE, pa_table[pa_table_index]);
|
||||
cc1100_write_reg(CC1100_PATABLE, pa_table[pa_table_index]);
|
||||
|
||||
/* Initialize Radio Flags */
|
||||
rflags.RSSI = 0x00;
|
||||
rflags._RSSI = 0x00;
|
||||
rflags.LL_ACK = 0;
|
||||
rflags.CAA = 0;
|
||||
rflags.CRC = 0;
|
||||
@ -120,13 +123,13 @@ void cc1100_set_monitor(uint8_t mode) {
|
||||
|
||||
void cc1100_setup_rx_mode(void) {
|
||||
// Stay in RX mode until end of packet
|
||||
cc1100_spi_write_reg(CC1100_MCSM2, 0x07);
|
||||
cc1100_write_reg(CC1100_MCSM2, 0x07);
|
||||
cc1100_switch_to_rx();
|
||||
}
|
||||
|
||||
void cc1100_switch_to_rx(void) {
|
||||
radio_state = RADIO_RX;
|
||||
cc1100_spi_strobe(CC1100_SRX);
|
||||
cc1100_strobe(CC1100_SRX);
|
||||
}
|
||||
|
||||
void cc1100_wakeup_from_rx(void) {
|
||||
@ -134,7 +137,7 @@ void cc1100_wakeup_from_rx(void) {
|
||||
return;
|
||||
}
|
||||
DEBUG("CC1100 going to idle\n");
|
||||
cc1100_spi_strobe(CC1100_SIDLE);
|
||||
cc1100_strobe(CC1100_SIDLE);
|
||||
radio_state = RADIO_IDLE;
|
||||
}
|
||||
|
||||
@ -145,7 +148,7 @@ char* cc1100_get_marc_state(void) {
|
||||
uint8_t old_state = radio_state;
|
||||
|
||||
// Read content of status register
|
||||
state = cc1100_spi_read_status(CC1100_MARCSTATE) & MARC_STATE;
|
||||
state = cc1100_read_status(CC1100_MARCSTATE) & MARC_STATE;
|
||||
|
||||
// Make sure in IDLE state.
|
||||
// Only goes to IDLE if state was RX/WOR
|
||||
@ -211,13 +214,13 @@ void cc1100_print_config(void) {
|
||||
void cc1100_switch_to_pwd(void) {
|
||||
DEBUG("[cc110x_ng] switching to powerdown\n");
|
||||
cc1100_wakeup_from_rx();
|
||||
cc1100_spi_strobe(CC1100_SPWD);
|
||||
cc1100_strobe(CC1100_SPWD);
|
||||
radio_state = RADIO_PWD;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int16_t cc1100_set_channel(uint8_t channr) {
|
||||
uint8_t state = cc1100_spi_read_status(CC1100_MARCSTATE) & MARC_STATE;
|
||||
uint8_t state = cc1100_read_status(CC1100_MARCSTATE) & MARC_STATE;
|
||||
if ((state != 1) && (channr > MAX_CHANNR)) {
|
||||
return 0;
|
||||
}
|
||||
@ -238,15 +241,19 @@ int16_t cc1100_get_channel(void) {
|
||||
|
||||
static void reset(void) {
|
||||
cc1100_wakeup_from_rx();
|
||||
#ifdef MODULE_CC110x_SPI
|
||||
cc1100_spi_select();
|
||||
cc1100_spi_strobe(CC1100_SRES);
|
||||
#endif
|
||||
cc1100_strobe(CC1100_SRES);
|
||||
hwtimer_wait(RTIMER_TICKS(10));
|
||||
}
|
||||
|
||||
static void power_up_reset(void) {
|
||||
#ifdef MODULE_CC110x_SPI
|
||||
cc1100_spi_unselect();
|
||||
cc1100_spi_cs();
|
||||
cc1100_spi_unselect();
|
||||
#endif
|
||||
hwtimer_wait(RESET_WAIT_TIME);
|
||||
reset();
|
||||
radio_state = RADIO_IDLE;
|
||||
@ -258,7 +265,7 @@ static void write_register(uint8_t r, uint8_t value) {
|
||||
|
||||
/* Wake up from WOR/RX (if in WOR/RX, else no effect) */
|
||||
cc1100_wakeup_from_rx();
|
||||
cc1100_spi_write_reg(r, value);
|
||||
cc1100_write_reg(r, value);
|
||||
|
||||
// Have to put radio back to WOR/RX if old radio state
|
||||
// was WOR/RX, otherwise no action is necessary
|
||||
|
@ -48,6 +48,7 @@ and the mailinglist (subscription via web site)
|
||||
#include <cc1100-arch.h>
|
||||
#include <cc1100-internal.h>
|
||||
#include <cc1100_spi.h>
|
||||
#include <cc1100-reg.h>
|
||||
|
||||
#include <irq.h>
|
||||
|
||||
@ -57,7 +58,7 @@ and the mailinglist (subscription via web site)
|
||||
|
||||
#define NOBYTE 0xFF
|
||||
|
||||
uint8_t cc1100_spi_writeburst_reg(uint8_t addr, char *src, uint8_t count) {
|
||||
uint8_t cc1100_writeburst_reg(uint8_t addr, char *src, uint8_t count) {
|
||||
int i = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_select();
|
||||
@ -71,7 +72,7 @@ uint8_t cc1100_spi_writeburst_reg(uint8_t addr, char *src, uint8_t count) {
|
||||
return count;
|
||||
}
|
||||
|
||||
void cc1100_spi_readburst_reg(uint8_t addr, char *buffer, uint8_t count) {
|
||||
void cc1100_readburst_reg(uint8_t addr, char *buffer, uint8_t count) {
|
||||
int i = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_select();
|
||||
@ -84,7 +85,7 @@ void cc1100_spi_readburst_reg(uint8_t addr, char *buffer, uint8_t count) {
|
||||
restoreIRQ(cpsr);
|
||||
}
|
||||
|
||||
void cc1100_spi_write_reg(uint8_t addr, uint8_t value) {
|
||||
void cc1100_write_reg(uint8_t addr, uint8_t value) {
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_select();
|
||||
cc1100_txrx(addr);
|
||||
@ -93,7 +94,7 @@ void cc1100_spi_write_reg(uint8_t addr, uint8_t value) {
|
||||
restoreIRQ(cpsr);
|
||||
}
|
||||
|
||||
uint8_t cc1100_spi_read_reg(uint8_t addr) {
|
||||
uint8_t cc1100_read_reg(uint8_t addr) {
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_select();
|
||||
@ -104,7 +105,7 @@ uint8_t cc1100_spi_read_reg(uint8_t addr) {
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t cc1100_spi_read_status(uint8_t addr) {
|
||||
uint8_t cc1100_read_status(uint8_t addr) {
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_select();
|
||||
@ -115,7 +116,7 @@ uint8_t cc1100_spi_read_status(uint8_t addr) {
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t cc1100_spi_strobe(uint8_t c) {
|
||||
uint8_t cc1100_strobe(uint8_t c) {
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_select();
|
||||
|
@ -53,12 +53,5 @@ void cc1100_spi_cs(void);
|
||||
void cc1100_spi_select(void);
|
||||
void cc1100_spi_unselect(void);
|
||||
|
||||
uint8_t cc1100_spi_writeburst_reg(uint8_t addr, char *buffer, uint8_t count);
|
||||
void cc1100_spi_readburst_reg(uint8_t addr, char *buffer, uint8_t count);
|
||||
void cc1100_spi_write_reg(uint8_t addr, uint8_t value);
|
||||
uint8_t cc1100_spi_read_reg(uint8_t addr);
|
||||
uint8_t cc1100_spi_read_status(uint8_t addr);
|
||||
uint8_t cc1100_spi_strobe(uint8_t c);
|
||||
|
||||
/** @} */
|
||||
#endif /* CC1100_SPI_H_ */
|
||||
|
@ -1,5 +1,5 @@
|
||||
SubDir TOP projects test_cc110x_ng ;
|
||||
|
||||
Module test_cc110x_ng : main.c : cc110x_ng shell shell_commands transceiver ps rtc posix_io uart0 auto_init gpioint ;
|
||||
Module test_cc110x_ng : main.c : cc110x_ng shell shell_commands transceiver ps rtc posix_io uart0 auto_init gpioint cc110x_spi ;
|
||||
|
||||
UseModule test_cc110x_ng ;
|
||||
|
Loading…
Reference in New Issue
Block a user