mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
coding conventions for drivers
This commit is contained in:
parent
201f593641
commit
e2130fbd47
@ -66,162 +66,195 @@ volatile static int cs_hwtimer_id = -1;
|
||||
volatile static int cs_timeout_flag = 0;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void cs_timeout_cb(void* ptr)
|
||||
static void cs_timeout_cb(void *ptr)
|
||||
{
|
||||
cs_timeout_flag = 1;
|
||||
cs_timeout_flag = 1;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int cc1100_send_csmaca(radio_address_t address, protocol_t protocol, int priority, char *payload, int payload_len)
|
||||
{
|
||||
uint16_t min_window_size;
|
||||
uint16_t max_window_size;
|
||||
uint16_t difs;
|
||||
uint16_t slottime;
|
||||
uint16_t min_window_size;
|
||||
uint16_t max_window_size;
|
||||
uint16_t difs;
|
||||
uint16_t slottime;
|
||||
|
||||
switch (priority)
|
||||
{
|
||||
case PRIORITY_ALARM:
|
||||
min_window_size = PRIO_ALARM_MIN_WINDOW_SIZE;
|
||||
max_window_size = PRIO_ALARM_MAX_WINDOW_SIZE;
|
||||
difs = PRIO_ALARM_DIFS;
|
||||
slottime = PRIO_ALARM_SLOTTIME;
|
||||
break;
|
||||
case PRIORITY_WARNING:
|
||||
min_window_size = PRIO_WARN_MIN_WINDOW_SIZE;
|
||||
max_window_size = PRIO_WARN_MAX_WINDOW_SIZE;
|
||||
difs = PRIO_WARN_DIFS;
|
||||
slottime = PRIO_WARN_SLOTTIME;
|
||||
break;
|
||||
default:
|
||||
min_window_size = PRIO_DATA_MIN_WINDOW_SIZE;
|
||||
max_window_size = PRIO_DATA_MAX_WINDOW_SIZE;
|
||||
difs = PRIO_DATA_DIFS;
|
||||
slottime = PRIO_DATA_SLOTTIME;
|
||||
}
|
||||
switch(priority) {
|
||||
case PRIORITY_ALARM:
|
||||
min_window_size = PRIO_ALARM_MIN_WINDOW_SIZE;
|
||||
max_window_size = PRIO_ALARM_MAX_WINDOW_SIZE;
|
||||
difs = PRIO_ALARM_DIFS;
|
||||
slottime = PRIO_ALARM_SLOTTIME;
|
||||
break;
|
||||
|
||||
// Calculate collisions per second
|
||||
if (collision_state == COLLISION_STATE_INITIAL) {
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
collision_measurement_start = now.microseconds;
|
||||
collision_count = 0;
|
||||
collisions_per_sec = 0;
|
||||
collision_state = COLLISION_STATE_MEASURE;
|
||||
} else if (collision_state == COLLISION_STATE_MEASURE) {
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
uint64_t timespan = now.microseconds - collision_measurement_start;
|
||||
if (timespan > 1000000) {
|
||||
collisions_per_sec = (collision_count * 1000000) / (double) timespan;
|
||||
if (collisions_per_sec > 0.5 && collisions_per_sec <= 2.2) {
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
collision_measurement_start = now.microseconds;
|
||||
collision_state = COLLISION_STATE_KEEP;
|
||||
} else if (collisions_per_sec > 2.2) {
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
collision_measurement_start = now.microseconds;
|
||||
collision_state = COLLISION_STATE_KEEP;
|
||||
} else {
|
||||
collision_state = COLLISION_STATE_INITIAL;
|
||||
}
|
||||
}
|
||||
} else if (collision_state == COLLISION_STATE_KEEP) {
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
case PRIORITY_WARNING:
|
||||
min_window_size = PRIO_WARN_MIN_WINDOW_SIZE;
|
||||
max_window_size = PRIO_WARN_MAX_WINDOW_SIZE;
|
||||
difs = PRIO_WARN_DIFS;
|
||||
slottime = PRIO_WARN_SLOTTIME;
|
||||
break;
|
||||
|
||||
default:
|
||||
min_window_size = PRIO_DATA_MIN_WINDOW_SIZE;
|
||||
max_window_size = PRIO_DATA_MAX_WINDOW_SIZE;
|
||||
difs = PRIO_DATA_DIFS;
|
||||
slottime = PRIO_DATA_SLOTTIME;
|
||||
}
|
||||
|
||||
/* Calculate collisions per second */
|
||||
if(collision_state == COLLISION_STATE_INITIAL) {
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
collision_measurement_start = now.microseconds;
|
||||
collision_count = 0;
|
||||
collisions_per_sec = 0;
|
||||
collision_state = COLLISION_STATE_MEASURE;
|
||||
}
|
||||
else if(collision_state == COLLISION_STATE_MEASURE) {
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
uint64_t timespan = now.microseconds - collision_measurement_start;
|
||||
if (timespan > 5000000) {
|
||||
collision_state = COLLISION_STATE_INITIAL;
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust initial window size according to collision rate
|
||||
if (collisions_per_sec > 0.5 && collisions_per_sec <= 2.2) {
|
||||
min_window_size *= 2;
|
||||
} else if (collisions_per_sec > 2.2) {
|
||||
min_window_size *= 4;
|
||||
}
|
||||
if(timespan > 1000000) {
|
||||
collisions_per_sec = (collision_count * 1000000) / (double) timespan;
|
||||
|
||||
uint16_t windowSize = min_window_size; // Start with window size of PRIO_XXX_MIN_WINDOW_SIZE
|
||||
uint16_t backoff = 0; // Backoff between 1 and windowSize
|
||||
uint32_t total; // Holds the total wait time before send try
|
||||
uint32_t cs_timeout; // Current carrier sense timeout value
|
||||
if(collisions_per_sec > 0.5 && collisions_per_sec <= 2.2) {
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
collision_measurement_start = now.microseconds;
|
||||
collision_state = COLLISION_STATE_KEEP;
|
||||
}
|
||||
else if(collisions_per_sec > 2.2) {
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
collision_measurement_start = now.microseconds;
|
||||
collision_state = COLLISION_STATE_KEEP;
|
||||
}
|
||||
else {
|
||||
collision_state = COLLISION_STATE_INITIAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(collision_state == COLLISION_STATE_KEEP) {
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
uint64_t timespan = now.microseconds - collision_measurement_start;
|
||||
|
||||
if (protocol == 0)
|
||||
{
|
||||
return RADIO_INVALID_PARAM; // Not allowed, protocol id must be greater zero
|
||||
}
|
||||
if(timespan > 5000000) {
|
||||
collision_state = COLLISION_STATE_INITIAL;
|
||||
}
|
||||
}
|
||||
|
||||
cc1100_phy_mutex_lock(); // Lock radio for exclusive access
|
||||
/* Adjust initial window size according to collision rate */
|
||||
if(collisions_per_sec > 0.5 && collisions_per_sec <= 2.2) {
|
||||
min_window_size *= 2;
|
||||
}
|
||||
else if(collisions_per_sec > 2.2) {
|
||||
min_window_size *= 4;
|
||||
}
|
||||
|
||||
// Get carrier sense timeout based on overall error rate till now
|
||||
send_csmaca_calls++;
|
||||
int fail_percentage = (send_csmaca_calls_cs_timeout * 100) / send_csmaca_calls;
|
||||
if (fail_percentage == 0) fail_percentage = 1;
|
||||
cs_timeout = CARRIER_SENSE_TIMEOUT / fail_percentage;
|
||||
if (cs_timeout < CARRIER_SENSE_TIMEOUT_MIN) cs_timeout = CARRIER_SENSE_TIMEOUT_MIN;
|
||||
uint16_t windowSize = min_window_size; /* Start with window size of PRIO_XXX_MIN_WINDOW_SIZE */
|
||||
uint16_t backoff = 0; /* Backoff between 1 and windowSize */
|
||||
uint32_t total; /* Holds the total wait time before send try */
|
||||
uint32_t cs_timeout; /* Current carrier sense timeout value */
|
||||
|
||||
cc1100_cs_init(); // Initialize carrier sensing
|
||||
if(protocol == 0) {
|
||||
return RADIO_INVALID_PARAM; /* Not allowed, protocol id must be greater zero */
|
||||
}
|
||||
|
||||
window:
|
||||
if (backoff != 0) goto cycle; // If backoff was 0
|
||||
windowSize *= 2; // ...double the current window size
|
||||
if (windowSize > max_window_size)
|
||||
{
|
||||
windowSize = max_window_size; // This is the maximum size allowed
|
||||
}
|
||||
backoff = rand() % windowSize; // ...and choose new backoff
|
||||
if (backoff < 0) backoff *= -1;
|
||||
backoff += (uint16_t) 1;
|
||||
cycle:
|
||||
cs_timeout_flag = 0; // Carrier sense timeout flag
|
||||
cs_hwtimer_id = hwtimer_set(cs_timeout, // Set hwtimer to set CS timeout flag
|
||||
cs_timeout_cb, NULL);
|
||||
while (cc1100_cs_read()) // Wait until air is free
|
||||
{
|
||||
if (cs_timeout_flag)
|
||||
{
|
||||
send_csmaca_calls_cs_timeout++;
|
||||
cc1100_phy_mutex_lock(); /* Lock radio for exclusive access */
|
||||
|
||||
/* Get carrier sense timeout based on overall error rate till now */
|
||||
send_csmaca_calls++;
|
||||
int fail_percentage = (send_csmaca_calls_cs_timeout * 100) / send_csmaca_calls;
|
||||
|
||||
if(fail_percentage == 0) {
|
||||
fail_percentage = 1;
|
||||
}
|
||||
|
||||
cs_timeout = CARRIER_SENSE_TIMEOUT / fail_percentage;
|
||||
|
||||
if(cs_timeout < CARRIER_SENSE_TIMEOUT_MIN) {
|
||||
cs_timeout = CARRIER_SENSE_TIMEOUT_MIN;
|
||||
}
|
||||
|
||||
cc1100_cs_init(); /* Initialize carrier sensing */
|
||||
|
||||
window:
|
||||
|
||||
if(backoff != 0) {
|
||||
goto cycle; /* If backoff was 0 */
|
||||
}
|
||||
|
||||
windowSize *= 2; /* ...double the current window size */
|
||||
|
||||
if(windowSize > max_window_size) {
|
||||
windowSize = max_window_size; /* This is the maximum size allowed */
|
||||
}
|
||||
|
||||
backoff = rand() % windowSize; /* ...and choose new backoff */
|
||||
|
||||
if(backoff < 0) {
|
||||
backoff *= -1;
|
||||
}
|
||||
|
||||
backoff += (uint16_t) 1;
|
||||
cycle:
|
||||
cs_timeout_flag = 0; /* Carrier sense timeout flag */
|
||||
cs_hwtimer_id = hwtimer_set(cs_timeout, /* Set hwtimer to set CS timeout flag */
|
||||
cs_timeout_cb, NULL);
|
||||
|
||||
while(cc1100_cs_read()) { /* Wait until air is free */
|
||||
if(cs_timeout_flag) {
|
||||
send_csmaca_calls_cs_timeout++;
|
||||
#ifndef CSMACA_MAC_AGGRESSIVE_MODE
|
||||
cc1100_phy_mutex_unlock();
|
||||
cc1100_go_after_tx(); // Go from RX to default mode
|
||||
return RADIO_CS_TIMEOUT; // Return immediately
|
||||
cc1100_phy_mutex_unlock();
|
||||
cc1100_go_after_tx(); /* Go from RX to default mode */
|
||||
return RADIO_CS_TIMEOUT; /* Return immediately */
|
||||
#endif
|
||||
#ifdef CSMACA_MAC_AGGRESSIVE_MODE
|
||||
goto send; // Send anyway
|
||||
goto send; /* Send anyway */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
hwtimer_remove(cs_hwtimer_id); // Remove hwtimer
|
||||
cc1100_cs_write_cca(1); // Air is free now
|
||||
cc1100_cs_set_enabled(true);
|
||||
if (cc1100_cs_read()) goto window; // GDO0 triggers on rising edge, so
|
||||
// test once after interrupt is enabled
|
||||
if (backoff > 0) backoff--; // Decrement backoff counter
|
||||
total = slottime; // Calculate total wait time
|
||||
total *= (uint32_t)backoff; // Slot vector set
|
||||
total += difs; // ...and standard DIFS wait time
|
||||
cs_timeout_flag = 0; // Carrier sense timeout flag
|
||||
cs_hwtimer_id = hwtimer_set(total, // Set hwtimer to set CS timeout flag
|
||||
cs_timeout_cb, NULL);
|
||||
while (!cs_timeout_flag
|
||||
|| !cc1100_cs_read_cca()) // Wait until timeout is finished
|
||||
{
|
||||
if (cc1100_cs_read_cca() == 0) // Is the air still free?
|
||||
{
|
||||
hwtimer_remove(cs_hwtimer_id);
|
||||
goto window; // No. Go back to new wait period.
|
||||
}
|
||||
}
|
||||
cc1100_cs_set_enabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
hwtimer_remove(cs_hwtimer_id); /* Remove hwtimer */
|
||||
cc1100_cs_write_cca(1); /* Air is free now */
|
||||
cc1100_cs_set_enabled(true);
|
||||
|
||||
if(cc1100_cs_read()) {
|
||||
goto window; /* GDO0 triggers on rising edge, so */
|
||||
}
|
||||
|
||||
/* test once after interrupt is enabled */
|
||||
if(backoff > 0) {
|
||||
backoff--; /* Decrement backoff counter */
|
||||
}
|
||||
|
||||
total = slottime; /* Calculate total wait time */
|
||||
total *= (uint32_t)backoff; /* Slot vector set */
|
||||
total += difs; /* ...and standard DIFS wait time */
|
||||
cs_timeout_flag = 0; /* Carrier sense timeout flag */
|
||||
cs_hwtimer_id = hwtimer_set(total, /* Set hwtimer to set CS timeout flag */
|
||||
cs_timeout_cb, NULL);
|
||||
|
||||
while(!cs_timeout_flag
|
||||
|| !cc1100_cs_read_cca()) { /* Wait until timeout is finished */
|
||||
if(cc1100_cs_read_cca() == 0) { /* Is the air still free? */
|
||||
hwtimer_remove(cs_hwtimer_id);
|
||||
goto window; /* No. Go back to new wait period. */
|
||||
}
|
||||
}
|
||||
|
||||
cc1100_cs_set_enabled(false);
|
||||
#ifdef CSMACA_MAC_AGGRESSIVE_MODE
|
||||
send:
|
||||
send:
|
||||
#endif
|
||||
int res = cc1100_send(address, protocol, priority, payload, payload_len);
|
||||
if (res < 0) {
|
||||
collision_count++;
|
||||
}
|
||||
return res;
|
||||
int res = cc1100_send(address, protocol, priority, payload, payload_len);
|
||||
|
||||
if(res < 0) {
|
||||
collision_count++;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -76,49 +76,49 @@ and the mailinglist (subscription via web site)
|
||||
* 24 | 240 | 917.61
|
||||
*/
|
||||
|
||||
// 400 kbps, MSK, X-tal: 26 MHz (Chip Revision F)
|
||||
/* 400 kbps, MSK, X-tal: 26 MHz (Chip Revision F) */
|
||||
char cc1100_conf[] = {
|
||||
0x06, // IOCFG2
|
||||
0x2E, // IOCFG1
|
||||
0x0E, // IOCFG0
|
||||
0x0F, // FIFOTHR
|
||||
0x9B, // SYNC1
|
||||
0xAD, // SYNC0
|
||||
0x3D, // PKTLEN (maximum value of packet length byte = 61)
|
||||
0x06, // PKTCTRL1
|
||||
0x45, // PKTCTRL0 (variable packet length)
|
||||
0xFF, // ADDR
|
||||
CC1100_DEFAULT_CHANNR*10, // CHANNR
|
||||
0x0B, // FSCTRL1
|
||||
0x00, // FSCTRL0
|
||||
0x21, // FREQ2
|
||||
0x71, // FREQ1
|
||||
0x7A, // FREQ0
|
||||
0x2D, // MDMCFG4
|
||||
0xF8, // MDMCFG3
|
||||
0x73, // MDMCFG2
|
||||
0x42, // MDMCFG1
|
||||
0xF8, // MDMCFG0
|
||||
0x00, // DEVIATN
|
||||
0x07, // MCSM2
|
||||
0x03, // MCSM1
|
||||
0x18, // MCSM0
|
||||
0x1D, // FOCCFG
|
||||
0x1C, // BSCFG
|
||||
0xC0, // AGCCTRL2
|
||||
0x49, // AGCCTRL1, (old value was 0x49 -> made carrier sense less sensitive!)
|
||||
// 0x47 - 7 dB above MAGN_TARGET setting
|
||||
0xB2, // AGCCTRL0
|
||||
0x87, // WOREVT1
|
||||
0x6B, // WOREVT0
|
||||
0xF8, // WORCTRL
|
||||
0xB6, // FREND1
|
||||
0x10, // FREND0
|
||||
0xEA, // FSCAL3
|
||||
0x2A, // FSCAL2
|
||||
0x00, // FSCAL1
|
||||
0x1F, // FSCAL0
|
||||
0x00 // padding to 4 bytes
|
||||
0x06, /* IOCFG2 */
|
||||
0x2E, /* IOCFG1 */
|
||||
0x0E, /* IOCFG0 */
|
||||
0x0F, /* FIFOTHR */
|
||||
0x9B, /* SYNC1 */
|
||||
0xAD, /* SYNC0 */
|
||||
0x3D, /* PKTLEN (maximum value of packet length byte = 61) */
|
||||
0x06, /* PKTCTRL1 */
|
||||
0x45, /* PKTCTRL0 (variable packet length) */
|
||||
0xFF, /* ADDR */
|
||||
CC1100_DEFAULT_CHANNR * 10, /* CHANNR */
|
||||
0x0B, /* FSCTRL1 */
|
||||
0x00, /* FSCTRL0 */
|
||||
0x21, /* FREQ2 */
|
||||
0x71, /* FREQ1 */
|
||||
0x7A, /* FREQ0 */
|
||||
0x2D, /* MDMCFG4 */
|
||||
0xF8, /* MDMCFG3 */
|
||||
0x73, /* MDMCFG2 */
|
||||
0x42, /* MDMCFG1 */
|
||||
0xF8, /* MDMCFG0 */
|
||||
0x00, /* DEVIATN */
|
||||
0x07, /* MCSM2 */
|
||||
0x03, /* MCSM1 */
|
||||
0x18, /* MCSM0 */
|
||||
0x1D, /* FOCCFG */
|
||||
0x1C, /* BSCFG */
|
||||
0xC0, /* AGCCTRL2 */
|
||||
0x49, /* AGCCTRL1, (old value was 0x49 -> made carrier sense less sensitive!)
|
||||
* 0x47 - 7 dB above MAGN_TARGET setting */
|
||||
0xB2, /* AGCCTRL0 */
|
||||
0x87, /* WOREVT1 */
|
||||
0x6B, /* WOREVT0 */
|
||||
0xF8, /* WORCTRL */
|
||||
0xB6, /* FREND1 */
|
||||
0x10, /* FREND0 */
|
||||
0xEA, /* FSCAL3 */
|
||||
0x2A, /* FSCAL2 */
|
||||
0x00, /* FSCAL1 */
|
||||
0x1F, /* FSCAL0 */
|
||||
0x00 /* padding to 4 bytes */
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
@ -66,7 +66,7 @@ and the mailinglist (subscription via web site)
|
||||
// Define default radio mode to constant RX if no
|
||||
// project specific setting is available.
|
||||
#ifndef CC1100_RADIO_MODE
|
||||
#define CC1100_RADIO_MODE CC1100_MODE_CONSTANT_RX
|
||||
#define CC1100_RADIO_MODE CC1100_MODE_CONSTANT_RX
|
||||
#endif
|
||||
|
||||
/// CC1100 radio interface
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -70,107 +70,106 @@ and the mailinglist (subscription via web site)
|
||||
|
||||
/** CC1100 register configuration */
|
||||
typedef struct cc1100_reg {
|
||||
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 */
|
||||
typedef struct cc1100_cfg_t {
|
||||
cc1100_reg_t reg_cfg; ///< CC1100 register configuration
|
||||
uint8_t pa_power; ///< Output power setting
|
||||
cc1100_reg_t reg_cfg; ///< CC1100 register configuration
|
||||
uint8_t pa_power; ///< Output power setting
|
||||
} cc1100_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief Radio Control Flags
|
||||
*/
|
||||
typedef struct cc1100_flags
|
||||
{
|
||||
uint32_t TOF; ///< Time of flight of the last packet and last ACK
|
||||
uint32_t TCP; ///< Time to compute packet
|
||||
unsigned RPS : 16; ///< Raw packets sent to transmit last packet
|
||||
unsigned RETC : 8; ///< Retransmission count of last send 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 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_STATE : 1; ///< The CRC status of last received packet (1 = OK, 0 = not OK)
|
||||
unsigned SEQ : 1; ///< Sequence number (toggles between 0 and 1)
|
||||
unsigned MAN_WOR : 1; ///< Manual WOR set (for randomized WOR times => no synch)
|
||||
unsigned KT_RES_ERR : 1; ///< A hwtimer resource error has occurred (no free timers available)
|
||||
unsigned TX : 1; ///< State machine TX lock, only ACKs will be received
|
||||
unsigned WOR_RST : 1; ///< Reset CC1100 real time clock (WOR) on next WOR strobe
|
||||
typedef struct cc1100_flags {
|
||||
uint32_t TOF; ///< Time of flight of the last packet and last ACK
|
||||
uint32_t TCP; ///< Time to compute packet
|
||||
unsigned RPS : 16; ///< Raw packets sent to transmit last packet
|
||||
unsigned RETC : 8; ///< Retransmission count of last send 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 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_STATE : 1; ///< The CRC status of last received packet (1 = OK, 0 = not OK)
|
||||
unsigned SEQ : 1; ///< Sequence number (toggles between 0 and 1)
|
||||
unsigned MAN_WOR : 1; ///< Manual WOR set (for randomized WOR times => no synch)
|
||||
unsigned KT_RES_ERR : 1; ///< A hwtimer resource error has occurred (no free timers available)
|
||||
unsigned TX : 1; ///< State machine TX lock, only ACKs will be received
|
||||
unsigned WOR_RST : 1; ///< Reset CC1100 real time clock (WOR) on next WOR strobe
|
||||
} cc1100_flags;
|
||||
|
||||
/**
|
||||
* @brief Statistic interface for debugging
|
||||
*/
|
||||
typedef struct cc1100_statistic {
|
||||
uint32_t packets_in;
|
||||
uint32_t packets_in_crc_fail;
|
||||
uint32_t packets_in_while_tx;
|
||||
uint32_t packets_in_dups;
|
||||
uint32_t packets_in_up;
|
||||
uint32_t packets_out;
|
||||
uint32_t packets_out_acked;
|
||||
uint32_t packets_out_broadcast;
|
||||
uint32_t raw_packets_out;
|
||||
uint32_t raw_packets_out_acked;
|
||||
uint32_t acks_send;
|
||||
uint32_t rx_buffer_max;
|
||||
uint32_t watch_dog_resets;
|
||||
uint32_t packets_in;
|
||||
uint32_t packets_in_crc_fail;
|
||||
uint32_t packets_in_while_tx;
|
||||
uint32_t packets_in_dups;
|
||||
uint32_t packets_in_up;
|
||||
uint32_t packets_out;
|
||||
uint32_t packets_out_acked;
|
||||
uint32_t packets_out_broadcast;
|
||||
uint32_t raw_packets_out;
|
||||
uint32_t raw_packets_out_acked;
|
||||
uint32_t acks_send;
|
||||
uint32_t rx_buffer_max;
|
||||
uint32_t watch_dog_resets;
|
||||
} cc1100_statistic_t;
|
||||
|
||||
enum radio_mode {
|
||||
RADIO_MODE_GET = -1, ///< leave mode unchanged
|
||||
RADIO_MODE_OFF = 0, ///< turn radio off
|
||||
RADIO_MODE_ON = 1 ///< turn radio on
|
||||
RADIO_MODE_GET = -1, ///< leave mode unchanged
|
||||
RADIO_MODE_OFF = 0, ///< turn radio off
|
||||
RADIO_MODE_ON = 1 ///< turn radio on
|
||||
};
|
||||
|
||||
enum radio_result {
|
||||
RADIO_PAYLOAD_TOO_LONG = -1, ///< payload too long
|
||||
RADIO_WRONG_MODE = -2, ///< operation not supported in current mode
|
||||
RADIO_ADDR_OUT_OF_RANGE = -3, ///< address out of range
|
||||
RADIO_OP_FAILED = -4, ///< operation failed
|
||||
RADIO_CS_TIMEOUT = -5, ///< Carrier Sense timeout: air was never free
|
||||
RADIO_INVALID_PARAM = -6 ///< Invalid parameters passed to radio
|
||||
RADIO_PAYLOAD_TOO_LONG = -1, ///< payload too long
|
||||
RADIO_WRONG_MODE = -2, ///< operation not supported in current mode
|
||||
RADIO_ADDR_OUT_OF_RANGE = -3, ///< address out of range
|
||||
RADIO_OP_FAILED = -4, ///< operation failed
|
||||
RADIO_CS_TIMEOUT = -5, ///< Carrier Sense timeout: air was never free
|
||||
RADIO_INVALID_PARAM = -6 ///< Invalid parameters passed to radio
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -207,7 +206,7 @@ void cc1100_set_idle(void);
|
||||
*
|
||||
* @return Textual representation of radio mode.
|
||||
*/
|
||||
char* cc1100_mode_to_text(uint8_t mode);
|
||||
char *cc1100_mode_to_text(uint8_t mode);
|
||||
|
||||
/**
|
||||
* @brief Convert radio state to textual representation.
|
||||
@ -216,21 +215,21 @@ char* cc1100_mode_to_text(uint8_t mode);
|
||||
*
|
||||
* @return Textual representation of radio state.
|
||||
*/
|
||||
char* cc1100_state_to_text(uint8_t state);
|
||||
char *cc1100_state_to_text(uint8_t state);
|
||||
|
||||
/**
|
||||
* @brief Convert current output power to textual representation.
|
||||
*
|
||||
* @return Textual representation of current output power in dBm.
|
||||
*/
|
||||
char* cc1100_get_output_power(char* buf);
|
||||
char *cc1100_get_output_power(char *buf);
|
||||
|
||||
/**
|
||||
* @brief Read out main radio control FSM state.
|
||||
*
|
||||
* @return Textual representation of current main radio control FSM state.
|
||||
*/
|
||||
char* cc1100_get_marc_state(void);
|
||||
char *cc1100_get_marc_state(void);
|
||||
|
||||
/**
|
||||
* @brief hwtimer wrapper function.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -75,23 +75,21 @@ Notes:
|
||||
\li Identification is increased is used to scan duplicates. It must be increased
|
||||
for each new packet and kept for packet retransmissions.
|
||||
*/
|
||||
typedef struct __attribute__ ((packed)) cc1100_packet_layer0_t
|
||||
{
|
||||
uint8_t length; ///< Length of the packet (without length byte)
|
||||
uint8_t address; ///< Destination address
|
||||
uint8_t phy_src; ///< Source address (physical source)
|
||||
uint8_t flags; ///< Flags
|
||||
uint8_t data[MAX_DATA_LENGTH]; ///< Data (high layer protocol)
|
||||
typedef struct __attribute__((packed)) cc1100_packet_layer0_t {
|
||||
uint8_t length; ///< Length of the packet (without length byte)
|
||||
uint8_t address; ///< Destination address
|
||||
uint8_t phy_src; ///< Source address (physical source)
|
||||
uint8_t flags; ///< Flags
|
||||
uint8_t data[MAX_DATA_LENGTH]; ///< Data (high layer protocol)
|
||||
} cc1100_packet_layer0_t;
|
||||
|
||||
typedef struct cc1100_wor_config_t
|
||||
{
|
||||
uint16_t rx_interval; ///< RX polling interval in milliseconds
|
||||
float rx_time_ms; ///< WOR_RX_TIME in milliseconds
|
||||
uint8_t rx_time_reg; ///< WOR_RX_TIME (CC1100 "MCSM2.RX_TIME" register value)
|
||||
uint8_t wor_evt_0; ///< CC1100 WOREVT0 register value
|
||||
uint8_t wor_evt_1; ///< CC1100 WOREVT1 register value
|
||||
uint8_t wor_ctrl; ///< CC1100 WORCTRL register value
|
||||
typedef struct cc1100_wor_config_t {
|
||||
uint16_t rx_interval; ///< RX polling interval in milliseconds
|
||||
float rx_time_ms; ///< WOR_RX_TIME in milliseconds
|
||||
uint8_t rx_time_reg; ///< WOR_RX_TIME (CC1100 "MCSM2.RX_TIME" register value)
|
||||
uint8_t wor_evt_0; ///< CC1100 WOREVT0 register value
|
||||
uint8_t wor_evt_1; ///< CC1100 WOREVT1 register value
|
||||
uint8_t wor_ctrl; ///< CC1100 WORCTRL register value
|
||||
} cc1100_wor_config_t;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -59,78 +59,82 @@ and the mailinglist (subscription via web site)
|
||||
uint8_t
|
||||
cc1100_spi_writeburst_reg(uint8_t addr, char *src, uint8_t count)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_WRITE_BURST);
|
||||
while (i < count) {
|
||||
cc110x_txrx(src[i]);
|
||||
i++;
|
||||
}
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return count;
|
||||
int i = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_WRITE_BURST);
|
||||
|
||||
while(i < count) {
|
||||
cc110x_txrx(src[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return count;
|
||||
}
|
||||
|
||||
void
|
||||
cc1100_spi_readburst_reg(uint8_t addr, char *buffer, uint8_t count)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_READ_BURST);
|
||||
while (i < count) {
|
||||
buffer[i] = cc110x_txrx(NOBYTE);
|
||||
i++;
|
||||
}
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
int i = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_READ_BURST);
|
||||
|
||||
while(i < count) {
|
||||
buffer[i] = cc110x_txrx(NOBYTE);
|
||||
i++;
|
||||
}
|
||||
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
}
|
||||
|
||||
void
|
||||
cc1100_spi_write_reg(uint8_t addr, uint8_t value)
|
||||
{
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr);
|
||||
cc110x_txrx(value);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr);
|
||||
cc110x_txrx(value);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
}
|
||||
|
||||
uint8_t cc1100_spi_read_reg(uint8_t addr)
|
||||
{
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_READ_SINGLE);
|
||||
result = cc110x_txrx(NOBYTE);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_READ_SINGLE);
|
||||
result = cc110x_txrx(NOBYTE);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t cc1100_spi_read_status(uint8_t addr)
|
||||
{
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_READ_BURST);
|
||||
result = cc110x_txrx(NOBYTE);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_READ_BURST);
|
||||
result = cc110x_txrx(NOBYTE);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t cc1100_spi_strobe(uint8_t c)
|
||||
{
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
result = cc110x_txrx(c);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
result = cc110x_txrx(c);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -1,28 +1,12 @@
|
||||
/******************************************************************************
|
||||
Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
|
||||
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
||||
and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
-------------------------------------------------------------------------------
|
||||
This file is part of RIOT.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
RIOT is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see http://www.gnu.org/licenses/ .
|
||||
--------------------------------------------------------------------------------
|
||||
For further information and questions please use the web site
|
||||
http://scatterweb.mi.fu-berlin.de
|
||||
and the mailinglist (subscription via web site)
|
||||
scatterweb@lists.spline.inf.fu-berlin.de
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* Default configuration for the cc110x chip
|
||||
*
|
||||
* Copyright (C) 2013 INRIA
|
||||
*
|
||||
* 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 dev_cc110x
|
||||
@ -34,9 +18,10 @@ and the mailinglist (subscription via web site)
|
||||
* @brief TI Chipcon CC110x default settings
|
||||
*
|
||||
* @author Freie Universität Berlin, Computer Systems & Telematics
|
||||
* @author INRIA
|
||||
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
|
||||
* @author Heiko Will <hwill@inf.fu-berlin.de>
|
||||
* @version $Revision: 2058 $
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*
|
||||
* @note $Id: cc110x-defaultSettings.c 2058 2010-03-31 08:59:31Z hillebra $
|
||||
*/
|
||||
@ -78,63 +63,63 @@ and the mailinglist (subscription via web site)
|
||||
|
||||
// 400 kbps, MSK, X-tal: 26 MHz (Chip Revision F)
|
||||
char cc110x_conf[] = {
|
||||
0x06, // IOCFG2
|
||||
0x2E, // IOCFG1
|
||||
0x0E, // IOCFG0
|
||||
0x0F, // FIFOTHR
|
||||
0x9B, // SYNC1
|
||||
0xAD, // SYNC0
|
||||
0x3D, // PKTLEN (maximum value of packet length byte = 61)
|
||||
0x06, // PKTCTRL1
|
||||
0x45, // PKTCTRL0 (variable packet length)
|
||||
0xFF, // ADDR
|
||||
CC1100_DEFAULT_CHANNR*10, // CHANNR
|
||||
0x0B, // FSCTRL1
|
||||
0x00, // FSCTRL0
|
||||
0x21, // FREQ2
|
||||
0x71, // FREQ1
|
||||
0x7A, // FREQ0
|
||||
0x2D, // MDMCFG4
|
||||
0xF8, // MDMCFG3
|
||||
0x73, // MDMCFG2
|
||||
0x42, // MDMCFG1
|
||||
0xF8, // MDMCFG0
|
||||
0x00, // DEVIATN
|
||||
0x07, // MCSM2
|
||||
0x03, // MCSM1
|
||||
0x18, // MCSM0
|
||||
0x1D, // FOCCFG
|
||||
0x1C, // BSCFG
|
||||
0xC0, // AGCCTRL2
|
||||
0x49, // AGCCTRL1, (old value was 0x49 -> made carrier sense less sensitive!)
|
||||
// 0x47 - 7 dB above MAGN_TARGET setting
|
||||
0xB2, // AGCCTRL0
|
||||
0x87, // WOREVT1
|
||||
0x6B, // WOREVT0
|
||||
0xF8, // WORCTRL
|
||||
0xB6, // FREND1
|
||||
0x10, // FREND0
|
||||
0xEA, // FSCAL3
|
||||
0x2A, // FSCAL2
|
||||
0x00, // FSCAL1
|
||||
0x1F, // FSCAL0
|
||||
0x00 // padding to 4 bytes
|
||||
0x06, // IOCFG2
|
||||
0x2E, // IOCFG1
|
||||
0x0E, // IOCFG0
|
||||
0x0F, // FIFOTHR
|
||||
0x9B, // SYNC1
|
||||
0xAD, // SYNC0
|
||||
0x3D, // PKTLEN (maximum value of packet length byte = 61)
|
||||
0x06, // PKTCTRL1
|
||||
0x45, // PKTCTRL0 (variable packet length)
|
||||
0xFF, // ADDR
|
||||
CC1100_DEFAULT_CHANNR * 10, // CHANNR
|
||||
0x0B, // FSCTRL1
|
||||
0x00, // FSCTRL0
|
||||
0x21, // FREQ2
|
||||
0x71, // FREQ1
|
||||
0x7A, // FREQ0
|
||||
0x2D, // MDMCFG4
|
||||
0xF8, // MDMCFG3
|
||||
0x73, // MDMCFG2
|
||||
0x42, // MDMCFG1
|
||||
0xF8, // MDMCFG0
|
||||
0x00, // DEVIATN
|
||||
0x07, // MCSM2
|
||||
0x03, // MCSM1
|
||||
0x18, // MCSM0
|
||||
0x1D, // FOCCFG
|
||||
0x1C, // BSCFG
|
||||
0xC0, // AGCCTRL2
|
||||
0x49, // AGCCTRL1, (old value was 0x49 -> made carrier sense less sensitive!)
|
||||
// 0x47 - 7 dB above MAGN_TARGET setting
|
||||
0xB2, // AGCCTRL0
|
||||
0x87, // WOREVT1
|
||||
0x6B, // WOREVT0
|
||||
0xF8, // WORCTRL
|
||||
0xB6, // FREND1
|
||||
0x10, // FREND0
|
||||
0xEA, // FSCAL3
|
||||
0x2A, // FSCAL2
|
||||
0x00, // FSCAL1
|
||||
0x1F, // FSCAL0
|
||||
0x00 // padding to 4 bytes
|
||||
};
|
||||
|
||||
uint8_t pa_table_index = PATABLE; ///< Current PATABLE Index
|
||||
uint8_t pa_table[] = { ///< PATABLE with available output powers
|
||||
0x00, ///< -52 dBm
|
||||
0x03, ///< -30 dBm
|
||||
0x0D, ///< -20 dBm
|
||||
0x1C, ///< -15 dBm
|
||||
0x34, ///< -10 dBm
|
||||
0x57, ///< - 5 dBm
|
||||
0x3F, ///< - 1 dBm
|
||||
0x8E, ///< 0 dBm
|
||||
0x85, ///< + 5 dBm
|
||||
0xCC, ///< + 7 dBm
|
||||
0xC6, ///< + 9 dBm
|
||||
0xC3 ///< +10 dBm
|
||||
0x00, ///< -52 dBm
|
||||
0x03, ///< -30 dBm
|
||||
0x0D, ///< -20 dBm
|
||||
0x1C, ///< -15 dBm
|
||||
0x34, ///< -10 dBm
|
||||
0x57, ///< - 5 dBm
|
||||
0x3F, ///< - 1 dBm
|
||||
0x8E, ///< 0 dBm
|
||||
0x85, ///< + 5 dBm
|
||||
0xCC, ///< + 7 dBm
|
||||
0xC6, ///< + 9 dBm
|
||||
0xC3 ///< +10 dBm
|
||||
}; // If PATABLE is changed in size, adjust MAX_OUTPUT_POWER definition in CC1100 interface!
|
||||
|
||||
|
||||
|
@ -1,3 +1,20 @@
|
||||
/**
|
||||
* Functions for packet reception on cc110x
|
||||
*
|
||||
* Copyright (C) 2009 Freie Universität Berlin
|
||||
* Copyright (C) 2013 INRIA
|
||||
*
|
||||
* 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 dev_cc110x_ng
|
||||
* @{
|
||||
* @file
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <cc110x_ng.h>
|
||||
#include <cc110x-internal.h>
|
||||
#include <cc110x-config.h>
|
||||
@ -27,174 +44,186 @@ static uint8_t receive_packet(uint8_t *rxBuffer, uint8_t length);
|
||||
rx_buffer_t cc110x_rx_buffer[RX_BUF_SIZE]; ///< RX buffer
|
||||
volatile uint8_t rx_buffer_next; ///< Next packet in RX queue
|
||||
|
||||
void cc110x_rx_handler(void) {
|
||||
void cc110x_rx_handler(void)
|
||||
{
|
||||
uint8_t res = 0;
|
||||
|
||||
// Possible packet received, RX -> IDLE (0.1 us)
|
||||
rflags.CAA = 0;
|
||||
rflags.MAN_WOR = 0;
|
||||
cc110x_statistic.packets_in++;
|
||||
/* Possible packet received, RX -> IDLE (0.1 us) */
|
||||
rflags.CAA = 0;
|
||||
rflags.MAN_WOR = 0;
|
||||
cc110x_statistic.packets_in++;
|
||||
|
||||
res = receive_packet((uint8_t*)&(cc110x_rx_buffer[rx_buffer_next].packet), sizeof(cc110x_packet_t));
|
||||
if (res) {
|
||||
// If we are sending a burst, don't accept packets.
|
||||
// Only ACKs are processed (for stopping the burst).
|
||||
// Same if state machine is in TX lock.
|
||||
if (radio_state == RADIO_SEND_BURST || rflags.TX)
|
||||
{
|
||||
cc110x_statistic.packets_in_while_tx++;
|
||||
return;
|
||||
}
|
||||
res = receive_packet((uint8_t *)&(cc110x_rx_buffer[rx_buffer_next].packet), sizeof(cc110x_packet_t));
|
||||
|
||||
if(res) {
|
||||
/* If we are sending a burst, don't accept packets.
|
||||
* Only ACKs are processed (for stopping the burst).
|
||||
* Same if state machine is in TX lock. */
|
||||
if(radio_state == RADIO_SEND_BURST || rflags.TX) {
|
||||
cc110x_statistic.packets_in_while_tx++;
|
||||
return;
|
||||
}
|
||||
|
||||
cc110x_rx_buffer[rx_buffer_next].rssi = rflags._RSSI;
|
||||
cc110x_rx_buffer[rx_buffer_next].lqi = rflags._LQI;
|
||||
cc110x_strobe(CC1100_SFRX); // ...for flushing the RX FIFO
|
||||
cc110x_strobe(CC1100_SFRX); /* ...for flushing the RX FIFO */
|
||||
|
||||
// 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).
|
||||
//cc110x_spi_write_reg(CC1100_MCSM0, 0x08); // Turn off FS-Autocal
|
||||
cc110x_write_reg(CC1100_MCSM2, 0x07); // Configure RX_TIME (until end of packet)
|
||||
/* 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). */
|
||||
//cc110x_spi_write_reg(CC1100_MCSM0, 0x08); /* Turn off FS-Autocal */
|
||||
cc110x_write_reg(CC1100_MCSM2, 0x07); /* Configure RX_TIME (until end of packet) */
|
||||
cc110x_strobe(CC1100_SRX);
|
||||
hwtimer_wait(IDLE_TO_RX_TIME);
|
||||
radio_state = RADIO_RX;
|
||||
|
||||
|
||||
#ifdef DBG_IGNORE
|
||||
if (is_ignored(cc110x_rx_buffer[rx_buffer_next].packet.phy_src)) {
|
||||
|
||||
if(is_ignored(cc110x_rx_buffer[rx_buffer_next].packet.phy_src)) {
|
||||
LED_RED_TOGGLE;
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* notify transceiver thread if any */
|
||||
if (transceiver_pid) {
|
||||
msg_t m;
|
||||
if(transceiver_pid) {
|
||||
msg_t m;
|
||||
m.type = (uint16_t) RCV_PKT_CC1100;
|
||||
m.content.value = rx_buffer_next;
|
||||
msg_send_int(&m, transceiver_pid);
|
||||
}
|
||||
|
||||
/* shift to next buffer element */
|
||||
if (++rx_buffer_next == RX_BUF_SIZE) {
|
||||
if(++rx_buffer_next == RX_BUF_SIZE) {
|
||||
rx_buffer_next = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No ACK received so TOF is unpredictable
|
||||
rflags.TOF = 0;
|
||||
else {
|
||||
/* No ACK received so TOF is unpredictable */
|
||||
rflags.TOF = 0;
|
||||
|
||||
// CRC false or RX buffer full -> clear RX FIFO in both cases
|
||||
cc110x_strobe(CC1100_SIDLE); // Switch to IDLE (should already be)...
|
||||
cc110x_strobe(CC1100_SFRX); // ...for flushing the RX FIFO
|
||||
/* CRC false or RX buffer full -> clear RX FIFO in both cases */
|
||||
cc110x_strobe(CC1100_SIDLE); /* Switch to IDLE (should already be)... */
|
||||
cc110x_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)
|
||||
{
|
||||
cc110x_strobe(CC1100_SRX);
|
||||
hwtimer_wait(IDLE_TO_RX_TIME);
|
||||
return;
|
||||
}
|
||||
// If currently sending, exit here (don't go to RX/WOR)
|
||||
if (radio_state == RADIO_SEND_BURST)
|
||||
{
|
||||
cc110x_statistic.packets_in_while_tx++;
|
||||
return;
|
||||
}
|
||||
/* If packet interrupted this nodes send call,
|
||||
* don't change anything after this point. */
|
||||
if(radio_state == RADIO_AIR_FREE_WAITING) {
|
||||
cc110x_strobe(CC1100_SRX);
|
||||
hwtimer_wait(IDLE_TO_RX_TIME);
|
||||
return;
|
||||
}
|
||||
|
||||
// No valid packet, so go back to RX/WOR as soon as possible
|
||||
cc110x_switch_to_rx();
|
||||
}
|
||||
/* If currently sending, exit here (don't go to RX/WOR) */
|
||||
if(radio_state == RADIO_SEND_BURST) {
|
||||
cc110x_statistic.packets_in_while_tx++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* No valid packet, so go back to RX/WOR as soon as possible */
|
||||
cc110x_switch_to_rx();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length) {
|
||||
uint8_t status[2];
|
||||
uint8_t packetLength = 0;
|
||||
static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length)
|
||||
{
|
||||
uint8_t status[2];
|
||||
uint8_t packetLength = 0;
|
||||
|
||||
/* Any bytes available in RX FIFO? */
|
||||
if ((cc110x_read_status(CC1100_RXBYTES) & BYTES_IN_RXFIFO)) {
|
||||
// Read length byte (first byte in RX FIFO)
|
||||
cc110x_read_fifo((char*) &packetLength, 1);
|
||||
// Read data from RX FIFO and store in rxBuffer
|
||||
if (packetLength <= length)
|
||||
{
|
||||
// Put length byte at first position in RX Buffer
|
||||
rxBuffer[0] = packetLength;
|
||||
/* Any bytes available in RX FIFO? */
|
||||
if((cc110x_read_status(CC1100_RXBYTES) & BYTES_IN_RXFIFO)) {
|
||||
/* Read length byte (first byte in RX FIFO) */
|
||||
cc110x_read_fifo((char *) &packetLength, 1);
|
||||
|
||||
// Read the rest of the packet
|
||||
//cc110x_readburst_reg(CC1100_RXFIFO, (char*)rxBuffer+1, packetLength);
|
||||
cc110x_read_fifo((char*) rxBuffer + 1, packetLength);
|
||||
/* Read data from RX FIFO and store in rxBuffer */
|
||||
if(packetLength <= length) {
|
||||
/* Put length byte at first position in RX Buffer */
|
||||
rxBuffer[0] = packetLength;
|
||||
|
||||
// Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI)
|
||||
cc110x_readburst_reg(CC1100_RXFIFO, (char*)status, 2);
|
||||
/* Read the rest of the packet */
|
||||
//cc110x_readburst_reg(CC1100_RXFIFO, (char*)rxBuffer+1, packetLength);
|
||||
cc110x_read_fifo((char *) rxBuffer + 1, packetLength);
|
||||
|
||||
// Store RSSI value of packet
|
||||
rflags._RSSI = status[I_RSSI];
|
||||
/* Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI) */
|
||||
cc110x_readburst_reg(CC1100_RXFIFO, (char *)status, 2);
|
||||
|
||||
// MSB of LQI is the CRC_OK bit
|
||||
rflags.CRC_STATE = (status[I_LQI] & CRC_OK) >> 7;
|
||||
if (!rflags.CRC_STATE) {
|
||||
/* Store RSSI value of packet */
|
||||
rflags._RSSI = status[I_RSSI];
|
||||
|
||||
/* MSB of LQI is the CRC_OK bit */
|
||||
rflags.CRC_STATE = (status[I_LQI] & CRC_OK) >> 7;
|
||||
|
||||
if(!rflags.CRC_STATE) {
|
||||
cc110x_statistic.packets_in_crc_fail++;
|
||||
}
|
||||
|
||||
// Bit 0-6 of LQI indicates the link quality (LQI)
|
||||
rflags._LQI = status[I_LQI] & LQI_EST;
|
||||
/* Bit 0-6 of LQI indicates the link quality (LQI) */
|
||||
rflags._LQI = status[I_LQI] & LQI_EST;
|
||||
|
||||
return rflags.CRC_STATE;
|
||||
return rflags.CRC_STATE;
|
||||
}
|
||||
/* too many bytes in FIFO */
|
||||
else {
|
||||
// RX FIFO get automatically flushed if return value is false
|
||||
else {
|
||||
/* RX FIFO get automatically flushed if return value is false */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* no bytes in RX FIFO */
|
||||
else {
|
||||
// RX FIFO get automatically flushed if return value is false
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
/* 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 = cc110x_read_reg(CC1100_PKTCTRL0) & PKT_LENGTH_CONFIG;
|
||||
if (pkt_len_cfg == VARIABLE_PKTLEN)
|
||||
{
|
||||
return receive_packet_variable(rxBuffer, length);
|
||||
}
|
||||
// Fixed packet length not supported.
|
||||
// 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 = cc110x_read_reg(CC1100_PKTCTRL0) & PKT_LENGTH_CONFIG;
|
||||
|
||||
if(pkt_len_cfg == VARIABLE_PKTLEN) {
|
||||
return receive_packet_variable(rxBuffer, length);
|
||||
}
|
||||
|
||||
/* Fixed packet length not supported. */
|
||||
/* RX FIFO get automatically flushed if return value is false */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DBG_IGNORE
|
||||
void cc110x_init_ignore(void) {
|
||||
memset(ignored_addr, 0, IGN_MAX*sizeof(radio_address_t));
|
||||
void cc110x_init_ignore(void)
|
||||
{
|
||||
memset(ignored_addr, 0, IGN_MAX * sizeof(radio_address_t));
|
||||
}
|
||||
|
||||
uint8_t cc110x_add_ignored(radio_address_t addr) {
|
||||
uint8_t i = 0;
|
||||
uint8_t cc110x_add_ignored(radio_address_t addr)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
while ((i < IGN_MAX) && ignored_addr[i++]) {
|
||||
printf("i: %hu\n", i);
|
||||
}
|
||||
if (i > IGN_MAX) {
|
||||
return 0;
|
||||
}
|
||||
ignored_addr[i-1] = addr;
|
||||
return 1;
|
||||
while((i < IGN_MAX) && ignored_addr[i++]) {
|
||||
printf("i: %hu\n", i);
|
||||
}
|
||||
|
||||
if(i > IGN_MAX) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ignored_addr[i - 1] = addr;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t is_ignored(radio_address_t addr) {
|
||||
static uint8_t is_ignored(radio_address_t addr)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < IGN_MAX; i++) {
|
||||
if (ignored_addr[i] == addr) {
|
||||
for(i = 0; i < IGN_MAX; i++) {
|
||||
if(ignored_addr[i] == addr) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -1,3 +1,20 @@
|
||||
/**
|
||||
* Functions for packet transmission on cc110x
|
||||
*
|
||||
* Copyright (C) 2009 Freie Universität Berlin
|
||||
* Copyright (C) 2013 INRIA
|
||||
*
|
||||
* 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 dev_cc110x_ng
|
||||
* @{
|
||||
* @file
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <cc110x_ng.h>
|
||||
@ -11,12 +28,13 @@
|
||||
|
||||
#include <board.h>
|
||||
|
||||
uint8_t cc110x_send(cc110x_packet_t *packet) {
|
||||
volatile uint32_t abort_count;
|
||||
uint8_t cc110x_send(cc110x_packet_t *packet)
|
||||
{
|
||||
volatile uint32_t abort_count;
|
||||
uint8_t size;
|
||||
/* TODO: burst sending */
|
||||
radio_state = RADIO_SEND_BURST;
|
||||
rflags.LL_ACK = 0;
|
||||
radio_state = RADIO_SEND_BURST;
|
||||
rflags.LL_ACK = 0;
|
||||
|
||||
/*
|
||||
* Number of bytes to send is:
|
||||
@ -25,54 +43,58 @@ uint8_t cc110x_send(cc110x_packet_t *packet) {
|
||||
*/
|
||||
size = packet->length + 1;
|
||||
|
||||
// The number of bytes to be transmitted must be smaller
|
||||
// or equal to PACKET_LENGTH (62 bytes). So the receiver
|
||||
// can put the whole packet in its RX-FIFO (with appended
|
||||
// packet status bytes).
|
||||
if (size > PACKET_LENGTH) {
|
||||
/* The number of bytes to be transmitted must be smaller
|
||||
* or equal to PACKET_LENGTH (62 bytes). So the receiver
|
||||
* can put the whole packet in its RX-FIFO (with appended
|
||||
* packet status bytes).*/
|
||||
if(size > PACKET_LENGTH) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
packet->phy_src = cc110x_get_address();
|
||||
|
||||
// Disables RX interrupt etc.
|
||||
cc110x_before_send();
|
||||
/* Disables RX interrupt etc. */
|
||||
cc110x_before_send();
|
||||
|
||||
// But CC1100 in IDLE mode to flush the FIFO
|
||||
/* But CC1100 in IDLE mode to flush the FIFO */
|
||||
cc110x_strobe(CC1100_SIDLE);
|
||||
// Flush TX FIFO to be sure it is empty
|
||||
/* Flush TX FIFO to be sure it is empty */
|
||||
cc110x_strobe(CC1100_SFTX);
|
||||
// Write packet into TX FIFO
|
||||
cc110x_writeburst_reg(CC1100_TXFIFO, (char*) packet, size);
|
||||
// Switch to TX mode
|
||||
/* Write packet into TX FIFO */
|
||||
cc110x_writeburst_reg(CC1100_TXFIFO, (char *) packet, size);
|
||||
/* Switch to TX mode */
|
||||
abort_count = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_strobe(CC1100_STX);
|
||||
// Wait for GDO2 to be set -> sync word transmitted
|
||||
while (cc110x_get_gdo2() == 0) {
|
||||
abort_count++;
|
||||
if (abort_count > CC1100_SYNC_WORD_TX_TIME) {
|
||||
// Abort waiting. CC1100 maybe in wrong mode
|
||||
// e.g. sending preambles for always
|
||||
puts("[CC1100 TX] fatal error\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
restoreIRQ(cpsr);
|
||||
// Wait for GDO2 to be cleared -> end of packet
|
||||
while (cc110x_get_gdo2() != 0);
|
||||
//LED_GREEN_TOGGLE;
|
||||
|
||||
// Experimental - TOF Measurement
|
||||
/* Wait for GDO2 to be set -> sync word transmitted */
|
||||
while(cc110x_get_gdo2() == 0) {
|
||||
abort_count++;
|
||||
|
||||
if(abort_count > CC1100_SYNC_WORD_TX_TIME) {
|
||||
/* Abort waiting. CC1100 maybe in wrong mode */
|
||||
/* e.g. sending preambles for always */
|
||||
puts("[CC1100 TX] fatal error\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
restoreIRQ(cpsr);
|
||||
|
||||
/* Wait for GDO2 to be cleared -> end of packet */
|
||||
while(cc110x_get_gdo2() != 0);
|
||||
|
||||
|
||||
/* Experimental - TOF Measurement */
|
||||
cc110x_after_send();
|
||||
cc110x_statistic.raw_packets_out++;
|
||||
|
||||
// Store number of transmission retries
|
||||
rflags.TX = 0;
|
||||
/* Store number of transmission retries */
|
||||
rflags.TX = 0;
|
||||
|
||||
// Go to mode after TX (CONST_RX -> RX, WOR -> WOR)
|
||||
cc110x_switch_to_rx();
|
||||
/* Go to mode after TX (CONST_RX -> RX, WOR -> WOR) */
|
||||
cc110x_switch_to_rx();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,19 @@
|
||||
/**
|
||||
* Basic functionality of cc110x driver
|
||||
*
|
||||
* Copyright (C) 2013 Freie Universität Berlin
|
||||
* Copyright (C) 2013 INRIA
|
||||
*
|
||||
* 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 dev_cc110x_ng
|
||||
* @{
|
||||
* @file
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
#include <cc110x_ng.h>
|
||||
#include <cc110x-arch.h>
|
||||
#include <cc110x-config.h>
|
||||
@ -34,107 +50,119 @@ static void reset(void);
|
||||
static void power_up_reset(void);
|
||||
static void write_register(uint8_t r, uint8_t value);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Radio Driver API
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void cc110x_init(int tpid) {
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Radio Driver API *
|
||||
*---------------------------------------------------------------------------*/
|
||||
void cc110x_init(int tpid)
|
||||
{
|
||||
transceiver_pid = tpid;
|
||||
DEBUG("Transceiver PID: %i\n", transceiver_pid);
|
||||
|
||||
rx_buffer_next = 0;
|
||||
rx_buffer_next = 0;
|
||||
|
||||
#ifdef MODULE_CC110X_SPI
|
||||
/* Initialize SPI */
|
||||
cc110x_spi_init();
|
||||
cc110x_spi_init();
|
||||
#endif
|
||||
|
||||
/* Load driver & reset */
|
||||
power_up_reset();
|
||||
/* Load driver & reset */
|
||||
power_up_reset();
|
||||
|
||||
/* Write configuration to configuration registers */
|
||||
cc110x_writeburst_reg(0x00, cc110x_conf, CC1100_CONF_SIZE);
|
||||
|
||||
/* Write PATABLE (power settings) */
|
||||
cc110x_write_reg(CC1100_PATABLE, pa_table[pa_table_index]);
|
||||
/* Write PATABLE (power settings) */
|
||||
cc110x_write_reg(CC1100_PATABLE, pa_table[pa_table_index]);
|
||||
|
||||
/* Initialize Radio Flags */
|
||||
rflags._RSSI = 0x00;
|
||||
rflags.LL_ACK = 0;
|
||||
rflags.CAA = 0;
|
||||
rflags.CRC_STATE = 0;
|
||||
rflags.SEQ = 0;
|
||||
rflags.MAN_WOR = 0;
|
||||
rflags.KT_RES_ERR = 0;
|
||||
rflags.TX = 0;
|
||||
rflags.WOR_RST = 0;
|
||||
/* Initialize Radio Flags */
|
||||
rflags._RSSI = 0x00;
|
||||
rflags.LL_ACK = 0;
|
||||
rflags.CAA = 0;
|
||||
rflags.CRC_STATE = 0;
|
||||
rflags.SEQ = 0;
|
||||
rflags.MAN_WOR = 0;
|
||||
rflags.KT_RES_ERR = 0;
|
||||
rflags.TX = 0;
|
||||
rflags.WOR_RST = 0;
|
||||
|
||||
/* Set default channel number */
|
||||
/* Set default channel number */
|
||||
#ifdef MODULE_CONFIG
|
||||
cc110x_set_config_channel(sysconfig.radio_channel);
|
||||
cc110x_set_config_channel(sysconfig.radio_channel);
|
||||
#else
|
||||
cc110x_set_channel(CC1100_DEFAULT_CHANNR);
|
||||
#endif
|
||||
DEBUG("CC1100 initialized and set to channel %i\n", radio_channel);
|
||||
|
||||
// Switch to desired mode (WOR or RX)
|
||||
rd_set_mode(RADIO_MODE_ON);
|
||||
/* Switch to desired mode (WOR or RX) */
|
||||
rd_set_mode(RADIO_MODE_ON);
|
||||
|
||||
#ifdef DBG_IGNORE
|
||||
cc110x_init_ignore();
|
||||
#endif
|
||||
}
|
||||
|
||||
void cc110x_disable_interrupts(void) {
|
||||
cc110x_gdo2_disable();
|
||||
cc110x_gdo0_disable();
|
||||
void cc110x_disable_interrupts(void)
|
||||
{
|
||||
cc110x_gdo2_disable();
|
||||
cc110x_gdo0_disable();
|
||||
}
|
||||
|
||||
void cc110x_gdo0_irq(void) {
|
||||
// Air was not free -> Clear CCA flag
|
||||
rflags.CAA = false;
|
||||
// Disable carrier sense detection (GDO0 interrupt)
|
||||
cc110x_gdo0_disable();
|
||||
void cc110x_gdo0_irq(void)
|
||||
{
|
||||
/* Air was not free -> Clear CCA flag */
|
||||
rflags.CAA = false;
|
||||
/* Disable carrier sense detection (GDO0 interrupt) */
|
||||
cc110x_gdo0_disable();
|
||||
}
|
||||
|
||||
void cc110x_gdo2_irq(void) {
|
||||
cc110x_rx_handler();
|
||||
void cc110x_gdo2_irq(void)
|
||||
{
|
||||
cc110x_rx_handler();
|
||||
}
|
||||
|
||||
uint8_t cc110x_get_buffer_pos(void) {
|
||||
return (rx_buffer_next-1);
|
||||
uint8_t cc110x_get_buffer_pos(void)
|
||||
{
|
||||
return (rx_buffer_next - 1);
|
||||
}
|
||||
|
||||
radio_address_t cc110x_get_address() {
|
||||
radio_address_t cc110x_get_address()
|
||||
{
|
||||
return radio_address;
|
||||
}
|
||||
|
||||
radio_address_t cc110x_set_address(radio_address_t address) {
|
||||
if ((address < MIN_UID) || (address > MAX_UID)) {
|
||||
return 0;
|
||||
}
|
||||
radio_address_t cc110x_set_address(radio_address_t address)
|
||||
{
|
||||
if((address < MIN_UID) || (address > MAX_UID)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t id = (uint8_t) address;
|
||||
if (radio_state != RADIO_UNKNOWN) {
|
||||
write_register(CC1100_ADDR, id);
|
||||
}
|
||||
uint8_t id = (uint8_t) address;
|
||||
|
||||
radio_address = id;
|
||||
return radio_address;
|
||||
if(radio_state != RADIO_UNKNOWN) {
|
||||
write_register(CC1100_ADDR, id);
|
||||
}
|
||||
|
||||
radio_address = id;
|
||||
return radio_address;
|
||||
}
|
||||
|
||||
#ifdef MODULE_CONFIG
|
||||
radio_address_t cc110x_set_config_address(radio_address_t address) {
|
||||
radio_address_t cc110x_set_config_address(radio_address_t address)
|
||||
{
|
||||
radio_address_t a = cc110x_set_address(address);
|
||||
if (a) {
|
||||
|
||||
if(a) {
|
||||
sysconfig.radio_address = a;
|
||||
}
|
||||
|
||||
config_save();
|
||||
return a;
|
||||
}
|
||||
#endif
|
||||
|
||||
void cc110x_set_monitor(uint8_t mode) {
|
||||
if (mode) {
|
||||
void cc110x_set_monitor(uint8_t mode)
|
||||
{
|
||||
if(mode) {
|
||||
write_register(CC1100_PKTCTRL1, (0x04));
|
||||
}
|
||||
else {
|
||||
@ -142,199 +170,259 @@ void cc110x_set_monitor(uint8_t mode) {
|
||||
}
|
||||
}
|
||||
|
||||
void cc110x_setup_rx_mode(void) {
|
||||
// Stay in RX mode until end of packet
|
||||
cc110x_write_reg(CC1100_MCSM2, 0x07);
|
||||
cc110x_switch_to_rx();
|
||||
void cc110x_setup_rx_mode(void)
|
||||
{
|
||||
/* Stay in RX mode until end of packet */
|
||||
cc110x_write_reg(CC1100_MCSM2, 0x07);
|
||||
cc110x_switch_to_rx();
|
||||
}
|
||||
|
||||
void cc110x_switch_to_rx(void) {
|
||||
radio_state = RADIO_RX;
|
||||
cc110x_strobe(CC1100_SRX);
|
||||
void cc110x_switch_to_rx(void)
|
||||
{
|
||||
radio_state = RADIO_RX;
|
||||
cc110x_strobe(CC1100_SRX);
|
||||
}
|
||||
|
||||
void cc110x_wakeup_from_rx(void) {
|
||||
if (radio_state != RADIO_RX) {
|
||||
void cc110x_wakeup_from_rx(void)
|
||||
{
|
||||
if(radio_state != RADIO_RX) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG("CC1100 going to idle\n");
|
||||
cc110x_strobe(CC1100_SIDLE);
|
||||
radio_state = RADIO_IDLE;
|
||||
cc110x_strobe(CC1100_SIDLE);
|
||||
radio_state = RADIO_IDLE;
|
||||
}
|
||||
|
||||
char* cc110x_get_marc_state(void) {
|
||||
uint8_t state;
|
||||
char *cc110x_get_marc_state(void)
|
||||
{
|
||||
uint8_t state;
|
||||
|
||||
// Save old radio state
|
||||
uint8_t old_state = radio_state;
|
||||
/* Save old radio state */
|
||||
uint8_t old_state = radio_state;
|
||||
|
||||
// Read content of status register
|
||||
state = cc110x_read_status(CC1100_MARCSTATE) & MARC_STATE;
|
||||
/* Read content of status register */
|
||||
state = cc110x_read_status(CC1100_MARCSTATE) & MARC_STATE;
|
||||
|
||||
// Make sure in IDLE state.
|
||||
// Only goes to IDLE if state was RX/WOR
|
||||
cc110x_wakeup_from_rx();
|
||||
/* Make sure in IDLE state.
|
||||
* Only goes to IDLE if state was RX/WOR */
|
||||
cc110x_wakeup_from_rx();
|
||||
|
||||
// Have to put radio back to WOR/RX if old radio state
|
||||
// was WOR/RX, otherwise no action is necessary
|
||||
if (old_state == RADIO_WOR || old_state == RADIO_RX) {
|
||||
cc110x_switch_to_rx();
|
||||
}
|
||||
/* Have to put radio back to WOR/RX if old radio state
|
||||
* was WOR/RX, otherwise no action is necessary */
|
||||
if(old_state == RADIO_WOR || old_state == RADIO_RX) {
|
||||
cc110x_switch_to_rx();
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
// Note: it is not possible to read back the SLEEP or XOFF state numbers
|
||||
// because setting CSn low will make the chip enter the IDLE mode from the
|
||||
// SLEEP (0) or XOFF (2) states.
|
||||
case 1: return "IDLE";
|
||||
case 3: case 4: case 5: return "MANCAL";
|
||||
case 6: case 7: return "FS_WAKEUP";
|
||||
case 8: case 12: return "CALIBRATE";
|
||||
case 9: case 10: case 11: return "SETTLING";
|
||||
case 13: case 14: case 15: return "RX";
|
||||
case 16: return "TXRX_SETTLING";
|
||||
case 17: return "RXFIFO_OVERFLOW";
|
||||
case 18: return "FSTXON";
|
||||
case 19: case 20: return "TX";
|
||||
case 21: return "RXTX_SETTLING";
|
||||
case 22: return "TXFIFO_UNDERFLOW";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
switch(state) {
|
||||
/* Note: it is not possible to read back the SLEEP or XOFF state numbers
|
||||
* because setting CSn low will make the chip enter the IDLE mode from the
|
||||
* SLEEP (0) or XOFF (2) states. */
|
||||
case 1:
|
||||
return "IDLE";
|
||||
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
return "MANCAL";
|
||||
|
||||
case 6:
|
||||
case 7:
|
||||
return "FS_WAKEUP";
|
||||
|
||||
case 8:
|
||||
case 12:
|
||||
return "CALIBRATE";
|
||||
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
return "SETTLING";
|
||||
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
return "RX";
|
||||
|
||||
case 16:
|
||||
return "TXRX_SETTLING";
|
||||
|
||||
case 17:
|
||||
return "RXFIFO_OVERFLOW";
|
||||
|
||||
case 18:
|
||||
return "FSTXON";
|
||||
|
||||
case 19:
|
||||
case 20:
|
||||
return "TX";
|
||||
|
||||
case 21:
|
||||
return "RXTX_SETTLING";
|
||||
|
||||
case 22:
|
||||
return "TXFIFO_UNDERFLOW";
|
||||
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
char* cc110x_state_to_text(uint8_t state) {
|
||||
switch (state)
|
||||
{
|
||||
case RADIO_UNKNOWN:
|
||||
return "Unknown";
|
||||
case RADIO_AIR_FREE_WAITING:
|
||||
return "CS";
|
||||
case RADIO_WOR:
|
||||
return "WOR";
|
||||
case RADIO_IDLE:
|
||||
return "IDLE";
|
||||
case RADIO_SEND_BURST:
|
||||
return "TX BURST";
|
||||
case RADIO_RX:
|
||||
return "RX";
|
||||
case RADIO_SEND_ACK:
|
||||
return "TX ACK";
|
||||
case RADIO_PWD:
|
||||
return "PWD";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
char *cc110x_state_to_text(uint8_t state)
|
||||
{
|
||||
switch(state) {
|
||||
case RADIO_UNKNOWN:
|
||||
return "Unknown";
|
||||
|
||||
case RADIO_AIR_FREE_WAITING:
|
||||
return "CS";
|
||||
|
||||
case RADIO_WOR:
|
||||
return "WOR";
|
||||
|
||||
case RADIO_IDLE:
|
||||
return "IDLE";
|
||||
|
||||
case RADIO_SEND_BURST:
|
||||
return "TX BURST";
|
||||
|
||||
case RADIO_RX:
|
||||
return "RX";
|
||||
|
||||
case RADIO_SEND_ACK:
|
||||
return "TX ACK";
|
||||
|
||||
case RADIO_PWD:
|
||||
return "PWD";
|
||||
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void cc110x_print_config(void) {
|
||||
printf("Current radio state: %s\r\n", cc110x_state_to_text(radio_state));
|
||||
printf("Current MARC state: %s\r\n", cc110x_get_marc_state());
|
||||
printf("Current channel number: %u\r\n", radio_channel);
|
||||
void cc110x_print_config(void)
|
||||
{
|
||||
printf("Current radio state: %s\r\n", cc110x_state_to_text(radio_state));
|
||||
printf("Current MARC state: %s\r\n", cc110x_get_marc_state());
|
||||
printf("Current channel number: %u\r\n", radio_channel);
|
||||
}
|
||||
|
||||
void cc110x_switch_to_pwd(void) {
|
||||
void cc110x_switch_to_pwd(void)
|
||||
{
|
||||
DEBUG("[cc110x_ng] switching to powerdown\n");
|
||||
cc110x_wakeup_from_rx();
|
||||
cc110x_strobe(CC1100_SPWD);
|
||||
radio_state = RADIO_PWD;
|
||||
cc110x_strobe(CC1100_SPWD);
|
||||
radio_state = RADIO_PWD;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int16_t cc110x_set_channel(uint8_t channr) {
|
||||
uint8_t state = cc110x_read_status(CC1100_MARCSTATE) & MARC_STATE;
|
||||
if ((state != 1) && (channr > MAX_CHANNR)) {
|
||||
int16_t cc110x_set_channel(uint8_t channr)
|
||||
{
|
||||
uint8_t state = cc110x_read_status(CC1100_MARCSTATE) & MARC_STATE;
|
||||
|
||||
if((state != 1) && (channr > MAX_CHANNR)) {
|
||||
return -1;
|
||||
}
|
||||
write_register(CC1100_CHANNR, channr*10);
|
||||
radio_channel = channr;
|
||||
return radio_channel;
|
||||
|
||||
write_register(CC1100_CHANNR, channr * 10);
|
||||
radio_channel = channr;
|
||||
return radio_channel;
|
||||
}
|
||||
|
||||
#ifdef MODULE_CONFIG
|
||||
int16_t cc110x_set_config_channel(uint8_t channr) {
|
||||
int16_t cc110x_set_config_channel(uint8_t channr)
|
||||
{
|
||||
int16_t c = cc110x_set_channel(channr);
|
||||
if (c) {
|
||||
|
||||
if(c) {
|
||||
sysconfig.radio_channel = c;
|
||||
}
|
||||
|
||||
config_save();
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
int16_t cc110x_get_channel(void) {
|
||||
int16_t cc110x_get_channel(void)
|
||||
{
|
||||
return radio_channel;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// CC1100 reset functionality
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------
|
||||
* CC1100 reset functionality
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
static void reset(void) {
|
||||
cc110x_wakeup_from_rx();
|
||||
static void reset(void)
|
||||
{
|
||||
cc110x_wakeup_from_rx();
|
||||
#ifdef MODULE_CC110x_SPI
|
||||
cc110x_spi_select();
|
||||
cc110x_spi_select();
|
||||
#endif
|
||||
cc110x_strobe(CC1100_SRES);
|
||||
hwtimer_wait(RTIMER_TICKS(100));
|
||||
cc110x_strobe(CC1100_SRES);
|
||||
hwtimer_wait(RTIMER_TICKS(100));
|
||||
}
|
||||
|
||||
static void power_up_reset(void) {
|
||||
static void power_up_reset(void)
|
||||
{
|
||||
#ifdef MODULE_CC110x_SPI
|
||||
cc110x_spi_unselect();
|
||||
cc110x_spi_cs();
|
||||
cc110x_spi_unselect();
|
||||
cc110x_spi_unselect();
|
||||
cc110x_spi_cs();
|
||||
cc110x_spi_unselect();
|
||||
#endif
|
||||
hwtimer_wait(RESET_WAIT_TIME);
|
||||
reset();
|
||||
radio_state = RADIO_IDLE;
|
||||
hwtimer_wait(RESET_WAIT_TIME);
|
||||
reset();
|
||||
radio_state = RADIO_IDLE;
|
||||
}
|
||||
|
||||
static void write_register(uint8_t r, uint8_t value) {
|
||||
// Save old radio state
|
||||
uint8_t old_state = radio_state;
|
||||
|
||||
/* Wake up from WOR/RX (if in WOR/RX, else no effect) */
|
||||
cc110x_wakeup_from_rx();
|
||||
cc110x_write_reg(r, value);
|
||||
static void write_register(uint8_t r, uint8_t value)
|
||||
{
|
||||
/* Save old radio state */
|
||||
uint8_t old_state = radio_state;
|
||||
|
||||
// Have to put radio back to WOR/RX if old radio state
|
||||
// was WOR/RX, otherwise no action is necessary
|
||||
if ((old_state == RADIO_WOR) || (old_state == RADIO_RX)) {
|
||||
cc110x_switch_to_rx();
|
||||
}
|
||||
/* Wake up from WOR/RX (if in WOR/RX, else no effect) */
|
||||
cc110x_wakeup_from_rx();
|
||||
cc110x_write_reg(r, value);
|
||||
|
||||
/* Have to put radio back to WOR/RX if old radio state
|
||||
* was WOR/RX, otherwise no action is necessary */
|
||||
if((old_state == RADIO_WOR) || (old_state == RADIO_RX)) {
|
||||
cc110x_switch_to_rx();
|
||||
}
|
||||
}
|
||||
|
||||
static int rd_set_mode(int mode) {
|
||||
int result;
|
||||
|
||||
// Get current radio mode
|
||||
if ((radio_state == RADIO_UNKNOWN) || (radio_state == RADIO_PWD)) {
|
||||
result = RADIO_MODE_OFF;
|
||||
}
|
||||
else {
|
||||
result = RADIO_MODE_ON;
|
||||
}
|
||||
static int rd_set_mode(int mode)
|
||||
{
|
||||
int result;
|
||||
|
||||
switch (mode) {
|
||||
case RADIO_MODE_ON:
|
||||
/* Get current radio mode */
|
||||
if((radio_state == RADIO_UNKNOWN) || (radio_state == RADIO_PWD)) {
|
||||
result = RADIO_MODE_OFF;
|
||||
}
|
||||
else {
|
||||
result = RADIO_MODE_ON;
|
||||
}
|
||||
|
||||
switch(mode) {
|
||||
case RADIO_MODE_ON:
|
||||
DEBUG("Enabling rx mode\n");
|
||||
cc110x_init_interrupts(); // Enable interrupts
|
||||
cc110x_setup_rx_mode(); // Set chip to desired mode
|
||||
break;
|
||||
case RADIO_MODE_OFF:
|
||||
cc110x_disable_interrupts(); // Disable interrupts
|
||||
cc110x_switch_to_pwd(); // Set chip to power down mode
|
||||
break;
|
||||
case RADIO_MODE_GET:
|
||||
// do nothing, just return current mode
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
cc110x_init_interrupts(); /* Enable interrupts */
|
||||
cc110x_setup_rx_mode(); /* Set chip to desired mode */
|
||||
break;
|
||||
|
||||
// Return previous mode
|
||||
return result;
|
||||
case RADIO_MODE_OFF:
|
||||
cc110x_disable_interrupts(); /* Disable interrupts */
|
||||
cc110x_switch_to_pwd(); /* Set chip to power down mode */
|
||||
break;
|
||||
|
||||
case RADIO_MODE_GET:
|
||||
|
||||
/* do nothing, just return current mode */
|
||||
default:
|
||||
/* do nothing */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Return previous mode */
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,3 +1,19 @@
|
||||
/**
|
||||
* Configuration parameters for the cc110x radio chip
|
||||
*
|
||||
* Copyright (C) 2009 Freie Universität Berlin
|
||||
* Copyright (C) 2013 INRIA
|
||||
*
|
||||
* 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 dev_cc110x_ng
|
||||
* @{
|
||||
* @file
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
#ifndef CC1100_CONFIG_H
|
||||
#define CC1100_CONFIG_H
|
||||
|
||||
@ -6,91 +22,90 @@
|
||||
|
||||
/** 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;
|
||||
} cc110x_reg_t;
|
||||
|
||||
/** CC1100 radio configuration */
|
||||
typedef struct {
|
||||
cc110x_reg_t reg_cfg; ///< CC1100 register configuration
|
||||
uint8_t pa_power; ///< Output power setting
|
||||
cc110x_reg_t reg_cfg; ///< CC1100 register configuration
|
||||
uint8_t pa_power; ///< Output power setting
|
||||
} cc110x_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief Radio Control Flags
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t TOF; ///< Time of flight of the last packet and last ACK
|
||||
typedef struct {
|
||||
uint32_t TOF; ///< Time of flight of the last packet and last ACK
|
||||
timex_t TOA; ///< Time of packet arriveal
|
||||
uint32_t TCP; ///< Time to compute packet
|
||||
unsigned RPS : 16; ///< Raw packets sent to transmit last packet
|
||||
unsigned RETC : 8; ///< Retransmission count of last send 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 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_STATE : 1; ///< The CRC status of last received packet (1 = OK, 0 = not OK)
|
||||
unsigned SEQ : 1; ///< Sequence number (toggles between 0 and 1)
|
||||
unsigned MAN_WOR : 1; ///< Manual WOR set (for randomized WOR times => no synch)
|
||||
unsigned KT_RES_ERR : 1; ///< A hwtimer resource error has occurred (no free timers available)
|
||||
unsigned TX : 1; ///< State machine TX lock, only ACKs will be received
|
||||
unsigned WOR_RST : 1; ///< Reset CC1100 real time clock (WOR) on next WOR strobe
|
||||
uint32_t TCP; ///< Time to compute packet
|
||||
unsigned RPS : 16; ///< Raw packets sent to transmit last packet
|
||||
unsigned RETC : 8; ///< Retransmission count of last send 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 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_STATE : 1; ///< The CRC status of last received packet (1 = OK, 0 = not OK)
|
||||
unsigned SEQ : 1; ///< Sequence number (toggles between 0 and 1)
|
||||
unsigned MAN_WOR : 1; ///< Manual WOR set (for randomized WOR times => no synch)
|
||||
unsigned KT_RES_ERR : 1; ///< A hwtimer resource error has occurred (no free timers available)
|
||||
unsigned TX : 1; ///< State machine TX lock, only ACKs will be received
|
||||
unsigned WOR_RST : 1; ///< Reset CC1100 real time clock (WOR) on next WOR strobe
|
||||
} cc110x_flags;
|
||||
|
||||
/**
|
||||
* @brief Statistic interface for debugging
|
||||
*/
|
||||
typedef struct cc110x_statistic {
|
||||
uint32_t packets_in;
|
||||
uint32_t packets_in_crc_fail;
|
||||
uint32_t packets_in_while_tx;
|
||||
uint32_t packets_in_dups;
|
||||
uint32_t packets_in_up;
|
||||
uint32_t packets_out;
|
||||
uint32_t packets_out_broadcast;
|
||||
uint32_t raw_packets_out;
|
||||
uint32_t acks_send;
|
||||
uint32_t rx_buffer_max;
|
||||
uint32_t watch_dog_resets;
|
||||
uint32_t packets_in;
|
||||
uint32_t packets_in_crc_fail;
|
||||
uint32_t packets_in_while_tx;
|
||||
uint32_t packets_in_dups;
|
||||
uint32_t packets_in_up;
|
||||
uint32_t packets_out;
|
||||
uint32_t packets_out_broadcast;
|
||||
uint32_t raw_packets_out;
|
||||
uint32_t acks_send;
|
||||
uint32_t rx_buffer_max;
|
||||
uint32_t watch_dog_resets;
|
||||
} cc110x_statistic_t;
|
||||
|
||||
#endif
|
||||
|
@ -1,28 +1,19 @@
|
||||
/******************************************************************************
|
||||
Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
|
||||
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
||||
and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
-------------------------------------------------------------------------------
|
||||
This file is part of RIOT.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
RIOT is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see http://www.gnu.org/licenses/ .
|
||||
--------------------------------------------------------------------------------
|
||||
For further information and questions please use the web site
|
||||
http://scatterweb.mi.fu-berlin.de
|
||||
and the mailinglist (subscription via web site)
|
||||
scatterweb@lists.spline.inf.fu-berlin.de
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* Driver internal constants for 110x chip configuration
|
||||
*
|
||||
* Copyright (C) 2008 Freie Universität Berlin
|
||||
* Copyright (C) 2013 INRIA
|
||||
*
|
||||
* 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 dev_cc110x_ng
|
||||
* @{
|
||||
* @file
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef CC1100_INTERNAL_H
|
||||
#define CC1100_INTERNAL_H
|
||||
|
@ -3,9 +3,8 @@
|
||||
* @ingroup dev_cc110x_ng
|
||||
* @brief Access to CC110X registers
|
||||
*
|
||||
* @author Freie Uniersität Berlin, Computer Systems & Telematics, RIOT
|
||||
* @author Oliver Hahm <oliver.hahm@fu-berlin.de
|
||||
* version $Revision$
|
||||
* @author INRIA
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
@ -39,7 +38,7 @@ void cc110x_readburst_reg(uint8_t addr, char *buffer, uint8_t count);
|
||||
*
|
||||
* @param buffer Buffer to store read data
|
||||
* @param count Size of data to be read
|
||||
*
|
||||
*
|
||||
* @note: Calls cc110x_readburst_reg if not dedicated fifo read command
|
||||
* available
|
||||
*/
|
||||
|
@ -1,3 +1,19 @@
|
||||
/**
|
||||
* Data structures and variables for the cc110x driver interface
|
||||
*
|
||||
* Copyright (C) 2009 Freie Universität Berlin
|
||||
* Copyright (C) 2013 INRIA
|
||||
*
|
||||
* 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 dev_cc110x_ng
|
||||
* @{
|
||||
* @file
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
#ifndef CC1100_H
|
||||
#define CC1100_H
|
||||
|
||||
@ -65,13 +81,15 @@ Notes:
|
||||
\li Identification is increased is used to scan duplicates. It must be increased
|
||||
for each new packet and kept for packet retransmissions.
|
||||
*/
|
||||
typedef struct __attribute__ ((packed)) {
|
||||
uint8_t length; ///< Length of the packet (without length byte)
|
||||
uint8_t address; ///< Destination address
|
||||
uint8_t phy_src; ///< Source address (physical source)
|
||||
uint8_t flags; ///< Flags
|
||||
uint8_t data[CC1100_MAX_DATA_LENGTH]; ///< Data (high layer protocol)
|
||||
} cc110x_packet_t;
|
||||
typedef struct __attribute__((packed))
|
||||
{
|
||||
uint8_t length; ///< Length of the packet (without length byte)
|
||||
uint8_t address; ///< Destination address
|
||||
uint8_t phy_src; ///< Source address (physical source)
|
||||
uint8_t flags; ///< Flags
|
||||
uint8_t data[CC1100_MAX_DATA_LENGTH]; ///< Data (high layer protocol)
|
||||
}
|
||||
cc110x_packet_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t rssi;
|
||||
@ -80,12 +98,12 @@ typedef struct {
|
||||
} rx_buffer_t;
|
||||
|
||||
enum radio_mode {
|
||||
RADIO_MODE_GET = -1, ///< leave mode unchanged
|
||||
RADIO_MODE_OFF = 0, ///< turn radio off
|
||||
RADIO_MODE_ON = 1 ///< turn radio on
|
||||
RADIO_MODE_GET = -1, ///< leave mode unchanged
|
||||
RADIO_MODE_OFF = 0, ///< turn radio off
|
||||
RADIO_MODE_ON = 1 ///< turn radio on
|
||||
};
|
||||
|
||||
extern rx_buffer_t cc110x_rx_buffer[];
|
||||
extern rx_buffer_t cc110x_rx_buffer[];
|
||||
|
||||
extern volatile uint8_t rx_buffer_next; ///< Next packet in RX queue
|
||||
|
||||
|
@ -58,76 +58,87 @@ and the mailinglist (subscription via web site)
|
||||
|
||||
#define NOBYTE 0xFF
|
||||
|
||||
uint8_t cc110x_writeburst_reg(uint8_t addr, char *src, uint8_t count) {
|
||||
int i = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_WRITE_BURST);
|
||||
while (i < count) {
|
||||
cc110x_txrx(src[i]);
|
||||
i++;
|
||||
}
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return count;
|
||||
uint8_t cc110x_writeburst_reg(uint8_t addr, char *src, uint8_t count)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_WRITE_BURST);
|
||||
|
||||
while(i < count) {
|
||||
cc110x_txrx(src[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return count;
|
||||
}
|
||||
|
||||
void cc110x_readburst_reg(uint8_t addr, char *buffer, uint8_t count) {
|
||||
int i = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_READ_BURST);
|
||||
while (i < count) {
|
||||
buffer[i] = cc110x_txrx(NOBYTE);
|
||||
i++;
|
||||
}
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
void cc110x_readburst_reg(uint8_t addr, char *buffer, uint8_t count)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_READ_BURST);
|
||||
|
||||
while(i < count) {
|
||||
buffer[i] = cc110x_txrx(NOBYTE);
|
||||
i++;
|
||||
}
|
||||
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
}
|
||||
|
||||
void cc110x_read_fifo(char *buffer, uint8_t count) {
|
||||
cc110x_readburst_reg(CC1100_RXFIFO, buffer,count);
|
||||
void cc110x_read_fifo(char *buffer, uint8_t count)
|
||||
{
|
||||
cc110x_readburst_reg(CC1100_RXFIFO, buffer, count);
|
||||
}
|
||||
|
||||
void cc110x_write_reg(uint8_t addr, uint8_t value) {
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr);
|
||||
cc110x_txrx(value);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
void cc110x_write_reg(uint8_t addr, uint8_t value)
|
||||
{
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr);
|
||||
cc110x_txrx(value);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
}
|
||||
|
||||
uint8_t cc110x_read_reg(uint8_t addr) {
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_READ_SINGLE);
|
||||
result = cc110x_txrx(NOBYTE);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
uint8_t cc110x_read_reg(uint8_t addr)
|
||||
{
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_READ_SINGLE);
|
||||
result = cc110x_txrx(NOBYTE);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t cc110x_read_status(uint8_t addr) {
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_READ_BURST);
|
||||
result = cc110x_txrx(NOBYTE);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
uint8_t cc110x_read_status(uint8_t addr)
|
||||
{
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
cc110x_txrx(addr | CC1100_READ_BURST);
|
||||
result = cc110x_txrx(NOBYTE);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t cc110x_strobe(uint8_t c) {
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
result = cc110x_txrx(c);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
uint8_t cc110x_strobe(uint8_t c)
|
||||
{
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc110x_spi_select();
|
||||
result = cc110x_txrx(c);
|
||||
cc110x_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef ADC_H
|
||||
#define ADC_H
|
||||
#define ADC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
||||
#endif
|
||||
|
||||
/* These functions are defined in asmfunc.S */
|
||||
void Copy_al2un (unsigned char *dst, const unsigned long *src, int count); /* Copy aligned to unaligned. */
|
||||
void Copy_un2al (unsigned long *dst, const unsigned char *src, int count); /* Copy unaligned to aligned. */
|
||||
void Copy_al2un(unsigned char *dst, const unsigned long *src, int count); /* Copy aligned to unaligned. */
|
||||
void Copy_un2al(unsigned long *dst, const unsigned char *src, int count); /* Copy unaligned to aligned. */
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
@ -29,22 +29,22 @@ typedef unsigned char DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
DSTATUS disk_initialize (unsigned char);
|
||||
DSTATUS disk_status (unsigned char);
|
||||
DRESULT disk_read (unsigned char, unsigned char*, unsigned long, unsigned char);
|
||||
DRESULT disk_write (unsigned char, const unsigned char*, unsigned long, unsigned char);
|
||||
DRESULT disk_ioctl (unsigned char, unsigned char, void*);
|
||||
DSTATUS disk_initialize(unsigned char);
|
||||
DSTATUS disk_status(unsigned char);
|
||||
DRESULT disk_read(unsigned char, unsigned char *, unsigned long, unsigned char);
|
||||
DRESULT disk_write(unsigned char, const unsigned char *, unsigned long, unsigned char);
|
||||
DRESULT disk_ioctl(unsigned char, unsigned char, void *);
|
||||
|
||||
|
||||
|
||||
@ -90,18 +90,18 @@ DRESULT disk_ioctl (unsigned char, unsigned char, void*);
|
||||
/* Prototypes for each physical disk functions */
|
||||
|
||||
|
||||
DSTATUS NAND_initialize (void);
|
||||
DSTATUS NAND_status (void);
|
||||
DRESULT NAND_read (unsigned char*, unsigned long, unsigned char);
|
||||
DRESULT NAND_write (const unsigned char*, unsigned long, unsigned char);
|
||||
DRESULT NAND_ioctl (unsigned char, void*);
|
||||
DSTATUS NAND_initialize(void);
|
||||
DSTATUS NAND_status(void);
|
||||
DRESULT NAND_read(unsigned char *, unsigned long, unsigned char);
|
||||
DRESULT NAND_write(const unsigned char *, unsigned long, unsigned char);
|
||||
DRESULT NAND_ioctl(unsigned char, void *);
|
||||
|
||||
DSTATUS MCI_initialize (void);
|
||||
DSTATUS MCI_status (void);
|
||||
DRESULT MCI_read (unsigned char*, unsigned long, unsigned char);
|
||||
DRESULT MCI_write (const unsigned char*, unsigned long, unsigned char);
|
||||
DRESULT MCI_ioctl (unsigned char, void*);
|
||||
void MCI_timerproc (void);
|
||||
DSTATUS MCI_initialize(void);
|
||||
DSTATUS MCI_status(void);
|
||||
DRESULT MCI_read(unsigned char *, unsigned long, unsigned char);
|
||||
DRESULT MCI_write(const unsigned char *, unsigned long, unsigned char);
|
||||
DRESULT MCI_ioctl(unsigned char, void *);
|
||||
void MCI_timerproc(void);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef FLASHROM_H
|
||||
#define FLASHROM_H
|
||||
#define FLASHROM_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef __LTC4150_H
|
||||
#define __LTC4150_H
|
||||
#define __LTC4150_H
|
||||
|
||||
#include <ltc4150_arch.h>
|
||||
|
||||
|
@ -25,7 +25,7 @@ and the mailinglist (subscription via web site)
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __LTC4150_ARCH_H
|
||||
#define __LTC4150_ARCH_H
|
||||
#define __LTC4150_ARCH_H
|
||||
|
||||
/**
|
||||
* @defgroup ltc4150 LTC4150 Coulomb Counter
|
||||
@ -53,7 +53,7 @@ void ltc4150_disable_int(void);
|
||||
/** board specific ltc4150 interrupt enable */
|
||||
void ltc4150_enable_int(void);
|
||||
/** board specific synchronization of ltc4150 */
|
||||
void ltc4150_sync_blocking(void);
|
||||
void ltc4150_sync_blocking(void);
|
||||
/** board specific ltc4150 initialization */
|
||||
void ltc4150_arch_init(void);
|
||||
|
||||
|
@ -56,13 +56,13 @@ void rtc_disable(void);
|
||||
* @brief Sets the current time in broken down format directly from to RTC
|
||||
* @param[in] localt Pointer to structure with time to set
|
||||
*/
|
||||
void rtc_set_localtime(struct tm* localt);
|
||||
void rtc_set_localtime(struct tm *localt);
|
||||
|
||||
/**
|
||||
* @brief Returns the current time in broken down format directly from the RTC
|
||||
* @param[out] localt Pointer to structure to receive time
|
||||
*/
|
||||
void rtc_get_localtime(struct tm* localt);
|
||||
void rtc_get_localtime(struct tm *localt);
|
||||
|
||||
extern int rtc_second_pid;
|
||||
|
||||
|
@ -44,7 +44,7 @@ and the mailinglist (subscription via web site)
|
||||
|
||||
#define SHT11_NO_ACK (0)
|
||||
#define SHT11_ACK (1)
|
||||
//adr command r/w
|
||||
//adr command r/w
|
||||
#define SHT11_STATUS_REG_W (0x06) //000 0011 0
|
||||
#define SHT11_STATUS_REG_R (0x07) //000 0011 1
|
||||
#define SHT11_MEASURE_TEMP (0x03) //000 0001 1
|
||||
@ -60,20 +60,20 @@ and the mailinglist (subscription via web site)
|
||||
#define SHT11_MEASURE_TIMEOUT (1000)
|
||||
|
||||
/**
|
||||
* @brief sht11 measureable data
|
||||
* @brief sht11 measureable data
|
||||
*/
|
||||
typedef struct {
|
||||
float temperature; /**< temperature value */
|
||||
float relhum; /**< linear relative humidity */
|
||||
float relhum_temp; /**< temperature compensated relative humidity */
|
||||
float temperature; /**< temperature value */
|
||||
float relhum; /**< linear relative humidity */
|
||||
float relhum_temp; /**< temperature compensated relative humidity */
|
||||
} sht11_val_t;
|
||||
|
||||
/**
|
||||
* @brief SHT11 modes that can be measured
|
||||
*/
|
||||
typedef enum {
|
||||
TEMPERATURE = 1,
|
||||
HUMIDITY = 2
|
||||
TEMPERATURE = 1,
|
||||
HUMIDITY = 2
|
||||
} sht11_mode_t;
|
||||
|
||||
/**
|
||||
@ -98,7 +98,7 @@ uint8_t sht11_read_sensor(sht11_val_t *value, sht11_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Write status register
|
||||
*
|
||||
*
|
||||
* @param p_value The value to write
|
||||
*
|
||||
* @return 1 on success, 0 otherwise
|
||||
|
@ -46,51 +46,63 @@ static unsigned int last_int_time;
|
||||
static unsigned int last_int_duration;
|
||||
static unsigned int start_time;
|
||||
|
||||
static double __attribute__((__no_instrument_function__)) int_to_coulomb(int ints) {
|
||||
static double __attribute__((__no_instrument_function__)) int_to_coulomb(int ints)
|
||||
{
|
||||
return ((double)ints) / (_GFH * _R_SENSE);
|
||||
}
|
||||
|
||||
static double __attribute__((__no_instrument_function__)) coulomb_to_mA(double coulomb){
|
||||
static double __attribute__((__no_instrument_function__)) coulomb_to_mA(double coulomb)
|
||||
{
|
||||
return (coulomb * 1000) / 3600;
|
||||
}
|
||||
|
||||
static double mAh_to_Joule(double mAh) {
|
||||
static double mAh_to_Joule(double mAh)
|
||||
{
|
||||
return (SUPPLY_VOLTAGE * mAh * 3600);
|
||||
}
|
||||
|
||||
uint32_t ltc4150_get_last_int_duration_us(void) {
|
||||
uint32_t ltc4150_get_last_int_duration_us(void)
|
||||
{
|
||||
return HWTIMER_TICKS_TO_US(last_int_duration);
|
||||
}
|
||||
|
||||
double ltc4150_get_current_mA(void) {
|
||||
return 1000000000/(ltc4150_get_last_int_duration_us()*(_GFH * _R_SENSE));
|
||||
double ltc4150_get_current_mA(void)
|
||||
{
|
||||
return 1000000000 / (ltc4150_get_last_int_duration_us() * (_GFH * _R_SENSE));
|
||||
}
|
||||
|
||||
double __attribute__((__no_instrument_function__)) ltc4150_get_total_mAh(void) {
|
||||
double __attribute__((__no_instrument_function__)) ltc4150_get_total_mAh(void)
|
||||
{
|
||||
return coulomb_to_mA(int_to_coulomb(int_count));
|
||||
}
|
||||
|
||||
double ltc4150_get_total_Joule(void) {
|
||||
double ltc4150_get_total_Joule(void)
|
||||
{
|
||||
return mAh_to_Joule(ltc4150_get_total_mAh());
|
||||
}
|
||||
|
||||
double ltc4150_get_avg_mA(void) {
|
||||
return (int_to_coulomb(int_count)*1000000000)/HWTIMER_TICKS_TO_US(last_int_time - start_time);
|
||||
double ltc4150_get_avg_mA(void)
|
||||
{
|
||||
return (int_to_coulomb(int_count) * 1000000000) / HWTIMER_TICKS_TO_US(last_int_time - start_time);
|
||||
}
|
||||
|
||||
int ltc4150_get_interval(void) {
|
||||
int ltc4150_get_interval(void)
|
||||
{
|
||||
return HWTIMER_TICKS_TO_US(last_int_time - start_time);
|
||||
}
|
||||
|
||||
unsigned long __attribute__((__no_instrument_function__)) ltc4150_get_intcount(void) {
|
||||
unsigned long __attribute__((__no_instrument_function__)) ltc4150_get_intcount(void)
|
||||
{
|
||||
return int_count;
|
||||
}
|
||||
|
||||
void ltc4150_init(void) {
|
||||
void ltc4150_init(void)
|
||||
{
|
||||
ltc4150_arch_init();
|
||||
}
|
||||
|
||||
void ltc4150_start(void) {
|
||||
void ltc4150_start(void)
|
||||
{
|
||||
ltc4150_disable_int();
|
||||
int_count = 0;
|
||||
uint32_t now = hwtimer_now();
|
||||
@ -100,17 +112,20 @@ void ltc4150_start(void) {
|
||||
ltc4150_enable_int();
|
||||
}
|
||||
|
||||
void ltc4150_stop(void) {
|
||||
void ltc4150_stop(void)
|
||||
{
|
||||
ltc4150_disable_int();
|
||||
}
|
||||
|
||||
void __attribute__((__no_instrument_function__)) ltc4150_interrupt(void)
|
||||
{
|
||||
uint32_t now = hwtimer_now();
|
||||
if (now >= last_int_time) {
|
||||
|
||||
if(now >= last_int_time) {
|
||||
last_int_duration = now - last_int_time;
|
||||
} else {
|
||||
last_int_duration = (0-1) - last_int_time + now + 1;
|
||||
}
|
||||
else {
|
||||
last_int_duration = (0 - 1) - last_int_time + now + 1;
|
||||
}
|
||||
|
||||
last_int_time = now;
|
||||
|
@ -53,7 +53,7 @@ float sht11_temperature_offset;
|
||||
|
||||
/**
|
||||
* @brief Perform measurement
|
||||
*
|
||||
*
|
||||
* @param p_value Measured value (14 or 12 bit -> 2 bytes)
|
||||
* @param p_checksum Checksum of measurement
|
||||
* @param mode The requestested measurement mode: temperature or humidity
|
||||
@ -62,7 +62,7 @@ float sht11_temperature_offset;
|
||||
*/
|
||||
static uint8_t measure(uint8_t *p_value, uint8_t *p_checksum, uint8_t mode);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Write one byte
|
||||
*
|
||||
* @param value The value to write
|
||||
@ -91,7 +91,7 @@ static void connection_reset(void);
|
||||
static void transmission_start(void);
|
||||
|
||||
/**
|
||||
* @brief Toggle the clock line
|
||||
* @brief Toggle the clock line
|
||||
*/
|
||||
static inline void clk_signal(void);
|
||||
|
||||
@ -99,7 +99,8 @@ static inline void clk_signal(void);
|
||||
mutex_t sht11_mutex;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static inline void clk_signal(void) {
|
||||
static inline void clk_signal(void)
|
||||
{
|
||||
SHT11_SCK_HIGH;
|
||||
hwtimer_wait(SHT11_CLK_WAIT);
|
||||
SHT11_SCK_LOW;
|
||||
@ -109,246 +110,264 @@ static inline void clk_signal(void) {
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t write_byte(uint8_t value)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t ack;
|
||||
uint8_t i;
|
||||
uint8_t ack;
|
||||
|
||||
SHT11_DATA_OUT;
|
||||
|
||||
/* send value bit by bit to sht11 */
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (value & BIT7) {
|
||||
SHT11_DATA_HIGH;
|
||||
for(i = 0; i < 8; i++) {
|
||||
if(value & BIT7) {
|
||||
SHT11_DATA_HIGH;
|
||||
hwtimer_wait(SHT11_DATA_WAIT);
|
||||
} else {
|
||||
SHT11_DATA_LOW;
|
||||
}
|
||||
else {
|
||||
SHT11_DATA_LOW;
|
||||
hwtimer_wait(SHT11_DATA_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
/* trigger clock signal */
|
||||
clk_signal();
|
||||
|
||||
/* shift value to write next bit */
|
||||
value = value << 1;
|
||||
}
|
||||
value = value << 1;
|
||||
}
|
||||
|
||||
/* wait for ack */
|
||||
SHT11_DATA_IN;
|
||||
SHT11_DATA_IN;
|
||||
hwtimer_wait(SHT11_CLK_WAIT);
|
||||
ack = SHT11_DATA;
|
||||
|
||||
ack = SHT11_DATA;
|
||||
|
||||
clk_signal();
|
||||
|
||||
return ack;
|
||||
return ack;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t read_byte (uint8_t ack)
|
||||
static uint8_t read_byte(uint8_t ack)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t value = 0;
|
||||
uint8_t i;
|
||||
uint8_t value = 0;
|
||||
|
||||
SHT11_DATA_IN;
|
||||
SHT11_DATA_IN;
|
||||
hwtimer_wait(SHT11_DATA_WAIT);
|
||||
|
||||
/* read value bit by bit */
|
||||
for (i = 0; i < 8; i++) {
|
||||
value = value << 1;
|
||||
SHT11_SCK_HIGH;
|
||||
for(i = 0; i < 8; i++) {
|
||||
value = value << 1;
|
||||
SHT11_SCK_HIGH;
|
||||
hwtimer_wait(SHT11_CLK_WAIT);
|
||||
|
||||
if (SHT11_DATA) {
|
||||
if(SHT11_DATA) {
|
||||
/* increase data by one when DATA is high */
|
||||
value++;
|
||||
}
|
||||
SHT11_SCK_LOW;
|
||||
|
||||
SHT11_SCK_LOW;
|
||||
hwtimer_wait(SHT11_CLK_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
/* send ack if necessary */
|
||||
SHT11_DATA_OUT;
|
||||
if (ack) {
|
||||
SHT11_DATA_LOW;
|
||||
SHT11_DATA_OUT;
|
||||
|
||||
if(ack) {
|
||||
SHT11_DATA_LOW;
|
||||
hwtimer_wait(SHT11_DATA_WAIT);
|
||||
} else {
|
||||
SHT11_DATA_HIGH;
|
||||
}
|
||||
else {
|
||||
SHT11_DATA_HIGH;
|
||||
hwtimer_wait(SHT11_DATA_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
clk_signal();
|
||||
|
||||
/* release data line */
|
||||
SHT11_DATA_IN;
|
||||
SHT11_DATA_IN;
|
||||
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void transmission_start(void)
|
||||
{
|
||||
/* _____ ________
|
||||
DATA: |_______|
|
||||
___ ___
|
||||
SCK : ___| |___| |______
|
||||
*/
|
||||
SHT11_DATA_OUT;
|
||||
|
||||
DATA: |_______|
|
||||
___ ___
|
||||
SCK : ___| |___| |______
|
||||
*/
|
||||
SHT11_DATA_OUT;
|
||||
|
||||
/* set initial state */
|
||||
SHT11_DATA_HIGH;
|
||||
SHT11_DATA_HIGH;
|
||||
hwtimer_wait(SHT11_DATA_WAIT);
|
||||
SHT11_SCK_LOW;
|
||||
SHT11_SCK_LOW;
|
||||
hwtimer_wait(SHT11_CLK_WAIT);
|
||||
|
||||
SHT11_SCK_HIGH;
|
||||
SHT11_SCK_HIGH;
|
||||
hwtimer_wait(SHT11_CLK_WAIT);
|
||||
|
||||
SHT11_DATA_LOW;
|
||||
SHT11_DATA_LOW;
|
||||
hwtimer_wait(SHT11_DATA_WAIT);
|
||||
|
||||
SHT11_SCK_LOW;
|
||||
SHT11_SCK_LOW;
|
||||
hwtimer_wait(SHT11_CLK_WAIT);
|
||||
|
||||
SHT11_SCK_HIGH;
|
||||
SHT11_SCK_HIGH;
|
||||
hwtimer_wait(SHT11_CLK_WAIT);
|
||||
|
||||
SHT11_DATA_HIGH;
|
||||
SHT11_DATA_HIGH;
|
||||
hwtimer_wait(SHT11_DATA_WAIT);
|
||||
|
||||
SHT11_SCK_LOW;
|
||||
SHT11_SCK_LOW;
|
||||
hwtimer_wait(SHT11_CLK_WAIT);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void connection_reset(void)
|
||||
{
|
||||
/* _____________________________________________________ ____
|
||||
DATA: |_______|
|
||||
_ _ _ _ _ _ _ _ _ ___ ___
|
||||
SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |__
|
||||
*/
|
||||
/* _____________________________________________________ ____
|
||||
DATA: |_______|
|
||||
_ _ _ _ _ _ _ _ _ ___ ___
|
||||
SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |__
|
||||
*/
|
||||
uint8_t i;
|
||||
SHT11_DATA_HIGH;
|
||||
SHT11_DATA_HIGH;
|
||||
hwtimer_wait(SHT11_DATA_WAIT);
|
||||
SHT11_SCK_LOW;
|
||||
hwtimer_wait(SHT11_CLK_WAIT);
|
||||
for (i = 0; i < 9; i++) {
|
||||
|
||||
for(i = 0; i < 9; i++) {
|
||||
clk_signal();
|
||||
}
|
||||
transmission_start();
|
||||
}
|
||||
|
||||
transmission_start();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t measure(uint8_t *p_value, uint8_t *p_checksum, uint8_t mode)
|
||||
{
|
||||
uint8_t error = 0;
|
||||
uint8_t ack = 1;
|
||||
uint16_t i;
|
||||
uint8_t error = 0;
|
||||
uint8_t ack = 1;
|
||||
uint16_t i;
|
||||
|
||||
transmission_start();
|
||||
error = write_byte(mode);
|
||||
error = write_byte(mode);
|
||||
|
||||
hwtimer_wait(HWTIMER_TICKS(1000));
|
||||
|
||||
/* wait untile sensor has finished measurement or timeout */
|
||||
for (i = 0; (i < SHT11_MEASURE_TIMEOUT) && (!error); i++) {
|
||||
ack = SHT11_DATA;
|
||||
for(i = 0; (i < SHT11_MEASURE_TIMEOUT) && (!error); i++) {
|
||||
ack = SHT11_DATA;
|
||||
|
||||
if (!ack) {
|
||||
break;
|
||||
if(!ack) {
|
||||
break;
|
||||
}
|
||||
|
||||
hwtimer_wait(HWTIMER_TICKS(1000));
|
||||
}
|
||||
error += ack;
|
||||
}
|
||||
|
||||
error += ack;
|
||||
|
||||
/* read MSB */
|
||||
*(p_value + 1) = read_byte(SHT11_ACK);
|
||||
*(p_value + 1) = read_byte(SHT11_ACK);
|
||||
/* read LSB */
|
||||
*(p_value) = read_byte(SHT11_ACK);
|
||||
*(p_value) = read_byte(SHT11_ACK);
|
||||
/* read checksum */
|
||||
*p_checksum = read_byte(SHT11_NO_ACK);
|
||||
|
||||
return (!error);
|
||||
return (!error);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void sht11_init(void) {
|
||||
sht11_temperature_offset = 0;
|
||||
mutex_init(&sht11_mutex);
|
||||
SHT11_INIT;
|
||||
void sht11_init(void)
|
||||
{
|
||||
sht11_temperature_offset = 0;
|
||||
mutex_init(&sht11_mutex);
|
||||
SHT11_INIT;
|
||||
hwtimer_wait(11 * HWTIMER_TICKS(1000));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t sht11_read_status(uint8_t *p_value, uint8_t *p_checksum) {
|
||||
uint8_t error = 0;
|
||||
uint8_t sht11_read_status(uint8_t *p_value, uint8_t *p_checksum)
|
||||
{
|
||||
uint8_t error = 0;
|
||||
|
||||
transmission_start();
|
||||
error |= write_byte(SHT11_STATUS_REG_R);
|
||||
*p_value = read_byte(SHT11_ACK);
|
||||
*p_checksum = read_byte(SHT11_NO_ACK);
|
||||
return (!error);
|
||||
transmission_start();
|
||||
error |= write_byte(SHT11_STATUS_REG_R);
|
||||
*p_value = read_byte(SHT11_ACK);
|
||||
*p_checksum = read_byte(SHT11_NO_ACK);
|
||||
return (!error);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t sht11_write_status(uint8_t *p_value) {
|
||||
uint8_t error = 0;
|
||||
uint8_t sht11_write_status(uint8_t *p_value)
|
||||
{
|
||||
uint8_t error = 0;
|
||||
|
||||
transmission_start();
|
||||
error += write_byte(SHT11_STATUS_REG_W);
|
||||
error += write_byte(*p_value);
|
||||
return (!error);
|
||||
transmission_start();
|
||||
error += write_byte(SHT11_STATUS_REG_W);
|
||||
error += write_byte(*p_value);
|
||||
return (!error);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t sht11_read_sensor(sht11_val_t *value, sht11_mode_t mode) {
|
||||
uint8_t error = 0;
|
||||
uint8_t checksum;
|
||||
uint16_t humi_int, temp_int;
|
||||
uint8_t sht11_read_sensor(sht11_val_t *value, sht11_mode_t mode)
|
||||
{
|
||||
uint8_t error = 0;
|
||||
uint8_t checksum;
|
||||
uint16_t humi_int, temp_int;
|
||||
|
||||
/* Temperature arithmetic where S0(T) is read value
|
||||
/* Temperature arithmetic where S0(T) is read value
|
||||
* T = D1 + D2 * S0(T) */
|
||||
const float D1 = -39.6;
|
||||
const float D2 = 0.01;
|
||||
const float D1 = -39.6;
|
||||
const float D2 = 0.01;
|
||||
|
||||
/* Arithmetic for linear humdity where S0(RH) is read value
|
||||
/* Arithmetic for linear humdity where S0(RH) is read value
|
||||
* HL = C1 + C2 * S0(RH) + C3 * SO(RH)^2 */
|
||||
const float C1 = -4.0;
|
||||
const float C2 = +0.0405;
|
||||
const float C3 = -0.0000028;
|
||||
const float C1 = -4.0;
|
||||
const float C2 = +0.0405;
|
||||
const float C3 = -0.0000028;
|
||||
|
||||
/* Arithmetic for temperature compesated relative humdity
|
||||
/* Arithmetic for temperature compesated relative humdity
|
||||
* HT = (T-25) * ( T1 + T2 * SO(RH) ) + HL */
|
||||
const float T1 = +0.01;
|
||||
const float T2 = +0.00008;
|
||||
const float T1 = +0.01;
|
||||
const float T2 = +0.00008;
|
||||
|
||||
/* check for valid buffer */
|
||||
if (value == NULL) {
|
||||
if(value == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
value->temperature = 0;
|
||||
value->relhum = 0;
|
||||
value->relhum_temp = 0;
|
||||
value->temperature = 0;
|
||||
value->relhum = 0;
|
||||
value->relhum_temp = 0;
|
||||
|
||||
mutex_lock(&sht11_mutex);
|
||||
connection_reset();
|
||||
mutex_lock(&sht11_mutex);
|
||||
connection_reset();
|
||||
|
||||
/* measure humidity */
|
||||
if (mode & HUMIDITY) {
|
||||
error += (!measure((uint8_t*) &humi_int, &checksum, SHT11_MEASURE_HUMI));
|
||||
}
|
||||
if(mode & HUMIDITY) {
|
||||
error += (!measure((uint8_t *) &humi_int, &checksum, SHT11_MEASURE_HUMI));
|
||||
}
|
||||
|
||||
/* measure temperature */
|
||||
if (mode & TEMPERATURE) {
|
||||
error += (!measure((uint8_t*) &temp_int, &checksum, SHT11_MEASURE_TEMP));
|
||||
}
|
||||
if(mode & TEMPERATURE) {
|
||||
error += (!measure((uint8_t *) &temp_int, &checksum, SHT11_MEASURE_TEMP));
|
||||
}
|
||||
|
||||
/* break on error */
|
||||
if (error != 0) {
|
||||
connection_reset();
|
||||
mutex_unlock(&sht11_mutex,0);
|
||||
return 0;
|
||||
}
|
||||
if(error != 0) {
|
||||
connection_reset();
|
||||
mutex_unlock(&sht11_mutex, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mode & TEMPERATURE) {
|
||||
value->temperature = D1 + (D2 * ((float) temp_int)) + sht11_temperature_offset;
|
||||
}
|
||||
if (mode & HUMIDITY) {
|
||||
value->relhum = C1 + (C2 * ((float) humi_int)) + (C3 * ((float) humi_int) * ((float) humi_int));
|
||||
if(mode & TEMPERATURE) {
|
||||
value->temperature = D1 + (D2 * ((float) temp_int)) + sht11_temperature_offset;
|
||||
}
|
||||
|
||||
if (mode & TEMPERATURE) {
|
||||
value->relhum_temp = (value->temperature - 25) * (T1 + (T2 * (float) humi_int)) + value->relhum;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&sht11_mutex,0);
|
||||
return 1;
|
||||
if(mode & HUMIDITY) {
|
||||
value->relhum = C1 + (C2 * ((float) humi_int)) + (C3 * ((float) humi_int) * ((float) humi_int));
|
||||
|
||||
if(mode & TEMPERATURE) {
|
||||
value->relhum_temp = (value->temperature - 25) * (T1 + (T2 * (float) humi_int)) + value->relhum;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&sht11_mutex, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
Loading…
Reference in New Issue
Block a user