From e2130fbd47d54ec79e01b4558be21c9419c9714a Mon Sep 17 00:00:00 2001 From: Oliver Hahm Date: Fri, 21 Jun 2013 22:36:48 +0200 Subject: [PATCH] coding conventions for drivers --- drivers/cc110x/cc1100-csmaca-mac.c | 305 ++--- drivers/cc110x/cc1100-defaultSettings.c | 84 +- drivers/cc110x/cc1100-interface.h | 2 +- drivers/cc110x/cc1100.c | 1069 +++++++++-------- drivers/cc110x/cc1100.h | 167 ++- drivers/cc110x/cc1100_phy.c | 1136 ++++++++++--------- drivers/cc110x/cc1100_phy.h | 28 +- drivers/cc110x/cc1100_spi.c | 104 +- drivers/cc110x_ng/cc110x-defaultSettings.c | 143 ++- drivers/cc110x_ng/cc110x-rx.c | 241 ++-- drivers/cc110x_ng/cc110x-tx.c | 94 +- drivers/cc110x_ng/cc110x.c | 468 ++++---- drivers/cc110x_ng/include/cc110x-config.h | 153 +-- drivers/cc110x_ng/include/cc110x-internal.h | 41 +- drivers/cc110x_ng/include/cc110x-reg.h | 7 +- drivers/cc110x_ng/include/cc110x_ng.h | 40 +- drivers/cc110x_ng/spi/cc110x_spi.c | 127 ++- drivers/include/adc.h | 2 +- drivers/include/diskio.h | 46 +- drivers/include/flashrom.h | 2 +- drivers/include/ltc4150.h | 2 +- drivers/include/ltc4150_arch.h | 4 +- drivers/include/rtc.h | 4 +- drivers/include/sht11.h | 16 +- drivers/ltc4150/ltc4150.c | 51 +- drivers/sht11/sht11.c | 281 ++--- 26 files changed, 2467 insertions(+), 2150 deletions(-) diff --git a/drivers/cc110x/cc1100-csmaca-mac.c b/drivers/cc110x/cc1100-csmaca-mac.c index 01822a7cb0..f04848e80d 100644 --- a/drivers/cc110x/cc1100-csmaca-mac.c +++ b/drivers/cc110x/cc1100-csmaca-mac.c @@ -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; } diff --git a/drivers/cc110x/cc1100-defaultSettings.c b/drivers/cc110x/cc1100-defaultSettings.c index 008e9d9393..b99c69e8d3 100644 --- a/drivers/cc110x/cc1100-defaultSettings.c +++ b/drivers/cc110x/cc1100-defaultSettings.c @@ -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 */ }; /** @} */ diff --git a/drivers/cc110x/cc1100-interface.h b/drivers/cc110x/cc1100-interface.h index cc54f0cc56..6919ea8311 100644 --- a/drivers/cc110x/cc1100-interface.h +++ b/drivers/cc110x/cc1100-interface.h @@ -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 diff --git a/drivers/cc110x/cc1100.c b/drivers/cc110x/cc1100.c index 74dc86a431..50a5574fd8 100644 --- a/drivers/cc110x/cc1100.c +++ b/drivers/cc110x/cc1100.c @@ -58,7 +58,7 @@ and the mailinglist (subscription via web site) #include "hwtimer.h" #include "core/include/bitarithm.h" -// TODO: cc1100 port timer +/* TODO: cc1100 port timer */ #ifdef FEUERWARE_CPU_LPC2387 //#include "cpu/lpc2387/lpc2387-timer2.h" #endif @@ -70,8 +70,8 @@ and the mailinglist (subscription via web site) #endif #define PACKET_LENGTH (0x3E) ///< Packet length = 62 Bytes. -#define CC1100_SYNC_WORD_TX_TIME (90000) // loop count (max. timeout ~ 15 ms) to wait for - // sync word to be transmitted (GDO2 from low to high) +#define CC1100_SYNC_WORD_TX_TIME (90000) /* loop count (max. timeout ~ 15 ms) to wait for */ + /* sync word to be transmitted (GDO2 from low to high) */ /** * @name Virtual Radio Device methods (see vdevice_radio_methods) @@ -100,7 +100,7 @@ static uint8_t pa_table[] = { ///< PATABLE with available output powers 0xCC, ///< + 7 dBm 0xC6, ///< + 9 dBm 0xC3 ///< +10 dBm -}; // If PATABLE is changed in size, adjust MAX_OUTPUT_POWER definition in CC1100 interface! +}; /* If PATABLE is changed in size, adjust MAX_OUTPUT_POWER definition in CC1100 interface! */ static int8_t pa_table_dBm[] = { ///< Values of the PATABLE in dBm -52, @@ -126,18 +126,18 @@ static uint8_t radio_address; ///< Radio address static uint8_t radio_channel; ///< Radio channel number const radio_t radio_cc1100 = { ///< Radio driver API - "CC1100", - CC1100_BROADCAST_ADDRESS, - MAX_OUTPUT_POWER, - cc1100_get_avg_transmission_duration, - cc1100_get_address, - cc1100_set_address, - cc1100_set_output_power, - cc1100_set_packet_monitor, - cc1100_set_packet_handler, - cc1100_send_csmaca, - cc1100_print_statistic, - cc1100_print_config + "CC1100", + CC1100_BROADCAST_ADDRESS, + MAX_OUTPUT_POWER, + cc1100_get_avg_transmission_duration, + cc1100_get_address, + cc1100_set_address, + cc1100_set_output_power, + cc1100_set_packet_monitor, + cc1100_set_packet_handler, + cc1100_send_csmaca, + cc1100_print_statistic, + cc1100_print_config }; /*---------------------------------------------------------------------------*/ @@ -155,132 +155,138 @@ volatile cc1100_mode_callback_t cc1100_setup_mode; ///< Function to set up selec volatile int wor_hwtimer_id = -1; /*---------------------------------------------------------------------------*/ -// Low-level hardware access +/* Low-level hardware access */ /*---------------------------------------------------------------------------*/ void cc1100_disable_interrupts(void) { - cc110x_gdo2_disable(); - cc110x_gdo0_disable(); + 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(); + /* Air was not free -> Clear CCA flag */ + rflags.CAA = false; + /* Disable carrier sense detection (GDO0 interrupt) */ + cc110x_gdo0_disable(); } void cc110x_gdo2_irq(void) { - cc1100_phy_rx_handler(); + cc1100_phy_rx_handler(); } /*---------------------------------------------------------------------------*/ -// High level CC1100 SPI functions for transferring packet out +/* High level CC1100 SPI functions for transferring packet out */ // of RX FIFO (don't call when in WOR mode) /*---------------------------------------------------------------------------*/ static bool spi_receive_packet_variable(uint8_t *rxBuffer, uint8_t length) { - // Needed here for statistics - extern cc1100_statistic_t cc1100_statistic; + /* Needed here for statistics */ + extern cc1100_statistic_t cc1100_statistic; - uint8_t status[2]; - uint8_t packetLength = 0; + uint8_t status[2]; + uint8_t packetLength = 0; - // Any bytes available in RX FIFO? - if ((cc1100_spi_read_status(CC1100_RXBYTES) & BYTES_IN_RXFIFO)) - { - // Read length byte (first byte in RX FIFO) + /* Any bytes available in RX FIFO? */ + if((cc1100_spi_read_status(CC1100_RXBYTES) & BYTES_IN_RXFIFO)) { + /* Read length byte (first byte in RX FIFO) */ packetLength = cc1100_spi_read_reg(CC1100_RXFIFO); - // 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 rest of the packet - cc1100_spi_readburst_reg(CC1100_RXFIFO, (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) - cc1100_spi_readburst_reg(CC1100_RXFIFO, (char*)status, 2); + /* Read the rest of the packet */ + cc1100_spi_readburst_reg(CC1100_RXFIFO, (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) */ + cc1100_spi_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) cc1100_statistic.packets_in_crc_fail++; + /* Store RSSI value of packet */ + rflags.RSSI = status[I_RSSI]; - // Bit 0-6 of LQI indicates the link quality (LQI) - rflags.LQI = status[I_LQI] & LQI_EST; + /* MSB of LQI is the CRC_OK bit */ + rflags.CRC_STATE = (status[I_LQI] & CRC_OK) >> 7; - return rflags.CRC_STATE; + if(!rflags.CRC_STATE) { + cc1100_statistic.packets_in_crc_fail++; + } + + /* Bit 0-6 of LQI indicates the link quality (LQI) */ + rflags.LQI = status[I_LQI] & LQI_EST; + + return rflags.CRC_STATE; } - else - { - // RX FIFO get automatically flushed if return value is false + else { + /* RX FIFO get automatically flushed if return value is false */ return false; } - } - else - { - // RX FIFO get automatically flushed if return value is false - return false; - } + } + else { + /* RX FIFO get automatically flushed if return value is false */ + return false; + } } bool cc1100_spi_receive_packet(uint8_t *rxBuffer, uint8_t length) { - uint8_t pkt_len_cfg = cc1100_spi_read_reg(CC1100_PKTCTRL0) & PKT_LENGTH_CONFIG; - if (pkt_len_cfg == VARIABLE_PKTLEN) - { - return spi_receive_packet_variable(rxBuffer, length); - } - // Fixed packet length not supported. - // RX FIFO get automatically flushed if return value is false - return false; + uint8_t pkt_len_cfg = cc1100_spi_read_reg(CC1100_PKTCTRL0) & PKT_LENGTH_CONFIG; + + if(pkt_len_cfg == VARIABLE_PKTLEN) { + return spi_receive_packet_variable(rxBuffer, length); + } + + /* Fixed packet length not supported. */ + /* RX FIFO get automatically flushed if return value is false */ + return false; } /*---------------------------------------------------------------------------*/ -// CC1100 mode functionality +/* CC1100 mode functionality */ /*---------------------------------------------------------------------------*/ -void cc1100_set_idle(void) { - if (radio_state == RADIO_WOR) { - // Wake up the chip from WOR/sleep - cc110x_spi_select(); - hwtimer_wait(RTIMER_TICKS(122)); - cc110x_spi_unselect(); - radio_state = RADIO_IDLE; - // XOSC startup + FS calibration (300 + 809 us ~ 1.38 ms) - hwtimer_wait(FS_CAL_TIME); - return; - } - cc1100_spi_strobe(CC1100_SIDLE); - radio_state = RADIO_IDLE; +void cc1100_set_idle(void) +{ + if(radio_state == RADIO_WOR) { + /* Wake up the chip from WOR/sleep */ + cc110x_spi_select(); + hwtimer_wait(RTIMER_TICKS(122)); + cc110x_spi_unselect(); + radio_state = RADIO_IDLE; + /* XOSC startup + FS calibration (300 + 809 us ~ 1.38 ms) */ + hwtimer_wait(FS_CAL_TIME); + return; + } + + cc1100_spi_strobe(CC1100_SIDLE); + radio_state = RADIO_IDLE; } static void wakeup_from_rx(void) { - if (radio_state != RADIO_RX) return; - cc1100_spi_strobe(CC1100_SIDLE); - radio_state = RADIO_IDLE; + if(radio_state != RADIO_RX) { + return; + } + + cc1100_spi_strobe(CC1100_SIDLE); + radio_state = RADIO_IDLE; } static void switch_to_rx(void) { - radio_state = RADIO_RX; - cc1100_spi_strobe(CC1100_SRX); + radio_state = RADIO_RX; + cc1100_spi_strobe(CC1100_SRX); } static void setup_rx_mode(void) { - // Stay in RX mode until end of packet - cc1100_spi_write_reg(CC1100_MCSM2, 0x07); - switch_to_rx(); + /* Stay in RX mode until end of packet */ + cc1100_spi_write_reg(CC1100_MCSM2, 0x07); + switch_to_rx(); } /** @@ -288,16 +294,17 @@ static void setup_rx_mode(void) */ static void wakeup_from_wor(void) { - if (radio_state != RADIO_WOR) { - return; - } - // Wake up the chip from WOR/sleep - cc110x_spi_select(); - hwtimer_wait(RTIMER_TICKS(122)); - cc110x_spi_unselect(); - radio_state = RADIO_IDLE; - // XOSC startup + FS calibration (300 + 809 us ~ 1.38 ms) - hwtimer_wait(FS_CAL_TIME); + if(radio_state != RADIO_WOR) { + return; + } + + /* Wake up the chip from WOR/sleep */ + cc110x_spi_select(); + hwtimer_wait(RTIMER_TICKS(122)); + cc110x_spi_unselect(); + radio_state = RADIO_IDLE; + /* XOSC startup + FS calibration (300 + 809 us ~ 1.38 ms) */ + hwtimer_wait(FS_CAL_TIME); } /** @@ -305,29 +312,35 @@ static void wakeup_from_wor(void) */ void switch_to_wor2(void) { -// if (cc110x_get_gdo2()) return; // If incoming packet, then don't go to WOR now - cc1100_spi_strobe(CC1100_SIDLE); // Put CC1100 to IDLE - radio_state = RADIO_IDLE; // Radio state now IDLE - cc1100_spi_write_reg(CC1100_MCSM2, - cc1100_wor_config.rx_time_reg); // Configure RX_TIME (for use in WOR) - cc1100_spi_write_reg(CC1100_MCSM0, 0x18); // Turn on FS-Autocal - if (rflags.WOR_RST) { - cc1100_spi_strobe(CC1100_SWORRST); // Resets the real time clock - rflags.WOR_RST = false; - } - cc1100_spi_strobe(CC1100_SWOR); // Put radio back to sleep/WOR (must be in IDLE when this is done) - radio_state = RADIO_WOR; // Radio state now WOR + // if (cc110x_get_gdo2()) return; /* If incoming packet, then don't go to WOR now */ + cc1100_spi_strobe(CC1100_SIDLE); /* Put CC1100 to IDLE */ + radio_state = RADIO_IDLE; /* Radio state now IDLE */ + cc1100_spi_write_reg(CC1100_MCSM2, + cc1100_wor_config.rx_time_reg); /* Configure RX_TIME (for use in WOR) */ + cc1100_spi_write_reg(CC1100_MCSM0, 0x18); /* Turn on FS-Autocal */ + + if(rflags.WOR_RST) { + cc1100_spi_strobe(CC1100_SWORRST); /* Resets the real time clock */ + rflags.WOR_RST = false; + } + + cc1100_spi_strobe(CC1100_SWOR); /* Put radio back to sleep/WOR (must be in IDLE when this is done) */ + radio_state = RADIO_WOR; /* Radio state now WOR */ } /** * Note: This code is executed in the hwtimer ISR! */ -static void hwtimer_switch_to_wor2_wrapper(void* ptr) +static void hwtimer_switch_to_wor2_wrapper(void *ptr) { - wor_hwtimer_id = -1; // kernel timer handler function called, clear timer id - if (rflags.TX) return; // Stability: don't allow WOR timers at this point - rflags.WOR_RST = true; - switch_to_wor2(); + wor_hwtimer_id = -1; /* kernel timer handler function called, clear timer id */ + + if(rflags.TX) { + return; /* Stability: don't allow WOR timers at this point */ + } + + rflags.WOR_RST = true; + switch_to_wor2(); } /** @@ -335,395 +348,454 @@ static void hwtimer_switch_to_wor2_wrapper(void* ptr) */ static void switch_to_wor(void) { - // Any incoming packet? - if (cc110x_get_gdo2()) - { - // Then don't go to WOR now - return; - } + /* Any incoming packet? */ + if(cc110x_get_gdo2()) { + /* Then don't go to WOR now */ + return; + } - // Step 1: Set chip for random interval (1..RX_INTERVAL) to power down mode - if (!rflags.MAN_WOR) - { - rflags.MAN_WOR = true; - radio_state = RADIO_WOR; - // Go to power down mode - cc1100_spi_strobe(CC1100_SIDLE); - cc1100_spi_strobe(CC1100_SPWD); + /* Step 1: Set chip for random interval (1..RX_INTERVAL) to power down mode */ + if(!rflags.MAN_WOR) { + rflags.MAN_WOR = true; + radio_state = RADIO_WOR; + /* Go to power down mode */ + cc1100_spi_strobe(CC1100_SIDLE); + cc1100_spi_strobe(CC1100_SPWD); - // Set timer to do second step of manual WOR - int r = (rand() / (double)(RAND_MAX + 1.0)) * (cc1100_wor_config.rx_interval * 100.0) + 20; - wor_hwtimer_id = hwtimer_set(r, cc1100_hwtimer_go_receive_wrapper, NULL); - if (wor_hwtimer_id == -1) - { - rflags.KT_RES_ERR = true; - // No hwtimer available, go immediately to WOR mode. - // Else never receiving packets again... - rflags.MAN_WOR = false; - switch_to_wor2(); - } - } - // Step 2: Go to RX and then to WOR mode again - else - { - rflags.MAN_WOR = false; - wakeup_from_wor(); - cc1100_spi_strobe(CC1100_SRX); - hwtimer_wait(IDLE_TO_RX_TIME); - radio_state = RADIO_RX; - // Register timer to go to WOR after RX timeout - wor_hwtimer_id = hwtimer_set((cc1100_wor_config.rx_time_ms * 100 + 150), - hwtimer_switch_to_wor2_wrapper, NULL); // add 1,5 ms secure time - if (wor_hwtimer_id == -1) - { - rflags.KT_RES_ERR = true; - } - } + /* Set timer to do second step of manual WOR */ + int r = (rand() / (double)(RAND_MAX + 1.0)) * (cc1100_wor_config.rx_interval * 100.0) + 20; + wor_hwtimer_id = hwtimer_set(r, cc1100_hwtimer_go_receive_wrapper, NULL); + + if(wor_hwtimer_id == -1) { + rflags.KT_RES_ERR = true; + /* No hwtimer available, go immediately to WOR mode. */ + /* Else never receiving packets again... */ + rflags.MAN_WOR = false; + switch_to_wor2(); + } + } + /* Step 2: Go to RX and then to WOR mode again */ + else { + rflags.MAN_WOR = false; + wakeup_from_wor(); + cc1100_spi_strobe(CC1100_SRX); + hwtimer_wait(IDLE_TO_RX_TIME); + radio_state = RADIO_RX; + /* Register timer to go to WOR after RX timeout */ + wor_hwtimer_id = hwtimer_set((cc1100_wor_config.rx_time_ms * 100 + 150), + hwtimer_switch_to_wor2_wrapper, NULL); /* add 1,5 ms secure time */ + + if(wor_hwtimer_id == -1) { + rflags.KT_RES_ERR = true; + } + } } static void setup_wor_mode(void) { - // Wake up from WOR (if in WOR, else no effect) - cc1100_go_idle(); + /* Wake up from WOR (if in WOR, else no effect) */ + cc1100_go_idle(); - // Make sure CC1100 is in IDLE state - cc1100_spi_strobe(CC1100_SIDLE); + /* Make sure CC1100 is in IDLE state */ + cc1100_spi_strobe(CC1100_SIDLE); - // Enable automatic initial calibration of RCosc. - // Set T_event1 ~ 1.4 ms, enough for XOSC stabilize and FS calibration before RX. - // Enable RC oscillator before starting with WOR (or else it will not wake up). - // Not using AUTO_SYNC function. - cc1100_spi_write_reg(CC1100_WORCTRL, cc1100_wor_config.wor_ctrl); + /* Enable automatic initial calibration of RCosc. */ + /* Set T_event1 ~ 1.4 ms, enough for XOSC stabilize and FS calibration before RX. */ + /* Enable RC oscillator before starting with WOR (or else it will not wake up). */ + /* Not using AUTO_SYNC function. */ + cc1100_spi_write_reg(CC1100_WORCTRL, cc1100_wor_config.wor_ctrl); - // Set Event0 timeout (RX polling interval) - cc1100_spi_write_reg(CC1100_WOREVT1, cc1100_wor_config.wor_evt_1); - cc1100_spi_write_reg(CC1100_WOREVT0, cc1100_wor_config.wor_evt_0); + /* Set Event0 timeout (RX polling interval) */ + cc1100_spi_write_reg(CC1100_WOREVT1, cc1100_wor_config.wor_evt_1); + cc1100_spi_write_reg(CC1100_WOREVT0, cc1100_wor_config.wor_evt_0); - // Set RX time in WOR mode - cc1100_spi_write_reg(CC1100_MCSM2, cc1100_wor_config.rx_time_reg); + /* Set RX time in WOR mode */ + cc1100_spi_write_reg(CC1100_MCSM2, cc1100_wor_config.rx_time_reg); - // Enable automatic FS calibration when going from IDLE to RX/TX/FSTXON (in between EVENT0 and EVENT1) - cc1100_spi_write_reg(CC1100_MCSM0, 0x18); + /* Enable automatic FS calibration when going from IDLE to RX/TX/FSTXON (in between EVENT0 and EVENT1) */ + cc1100_spi_write_reg(CC1100_MCSM0, 0x18); - // Put the radio to SLEEP by starting Wake-on-Radio. - cc1100_spi_strobe(CC1100_SWORRST); // Resets the real time clock - cc1100_spi_strobe(CC1100_SWOR); // Starts Wake-on-Radio - radio_state = RADIO_WOR; + /* Put the radio to SLEEP by starting Wake-on-Radio. */ + cc1100_spi_strobe(CC1100_SWORRST); /* Resets the real time clock */ + cc1100_spi_strobe(CC1100_SWOR); /* Starts Wake-on-Radio */ + radio_state = RADIO_WOR; } static void switch_to_pwd(void) { - cc1100_go_idle(); - cc1100_spi_strobe(CC1100_SPWD); - radio_state = RADIO_PWD; + cc1100_go_idle(); + cc1100_spi_strobe(CC1100_SPWD); + radio_state = RADIO_PWD; } uint8_t cc1100_get_mode(void) { - return radio_mode; + return radio_mode; } static bool cc1100_set_mode0(uint8_t mode, uint16_t opt_mode_data) { - int result; - switch (mode) - { - case CC1100_MODE_WOR: - // Calculate WOR settings, store result (new burst count) - result = cc1100_phy_calc_wor_settings(opt_mode_data); - // If settings can be applied, set new mode and burst count - if (result != -1) - { - radio_mode = mode; - cc1100_go_idle = wakeup_from_wor; - cc1100_go_receive = switch_to_wor; - cc1100_go_after_tx = switch_to_wor2; - cc1100_setup_mode = setup_wor_mode; - cc1100_burst_count = result; - cc1100_retransmission_count_uc = TRANSMISSION_RETRIES_WOR_UC; - cc1100_retransmission_count_bc = TRANSMISSION_RETRIES_WOR_BC; - return true; - } - break; - case CC1100_MODE_CONSTANT_RX: - radio_mode = mode; - cc1100_go_idle = wakeup_from_rx; - cc1100_go_receive = switch_to_rx; - cc1100_go_after_tx = switch_to_rx; - cc1100_setup_mode = setup_rx_mode; - cc1100_burst_count = 1; - cc1100_retransmission_count_uc = TRANSMISSION_RETRIES_CRX_UC; - cc1100_retransmission_count_bc = TRANSMISSION_RETRIES_CRX_BC; - return true; - } - return false; + int result; + + switch(mode) { + case CC1100_MODE_WOR: + /* Calculate WOR settings, store result (new burst count) */ + result = cc1100_phy_calc_wor_settings(opt_mode_data); + + /* If settings can be applied, set new mode and burst count */ + if(result != -1) { + radio_mode = mode; + cc1100_go_idle = wakeup_from_wor; + cc1100_go_receive = switch_to_wor; + cc1100_go_after_tx = switch_to_wor2; + cc1100_setup_mode = setup_wor_mode; + cc1100_burst_count = result; + cc1100_retransmission_count_uc = TRANSMISSION_RETRIES_WOR_UC; + cc1100_retransmission_count_bc = TRANSMISSION_RETRIES_WOR_BC; + return true; + } + + break; + + case CC1100_MODE_CONSTANT_RX: + radio_mode = mode; + cc1100_go_idle = wakeup_from_rx; + cc1100_go_receive = switch_to_rx; + cc1100_go_after_tx = switch_to_rx; + cc1100_setup_mode = setup_rx_mode; + cc1100_burst_count = 1; + cc1100_retransmission_count_uc = TRANSMISSION_RETRIES_CRX_UC; + cc1100_retransmission_count_bc = TRANSMISSION_RETRIES_CRX_BC; + return true; + } + + return false; } bool cc1100_set_mode(uint8_t mode, uint16_t opt_mode_data) { - // Wake up from WOR/RX (if in WOR/RX, else no effect) - cc1100_go_idle(); + /* Wake up from WOR/RX (if in WOR/RX, else no effect) */ + cc1100_go_idle(); - // Make sure CC1100 is in IDLE state - cc1100_spi_strobe(CC1100_SIDLE); + /* Make sure CC1100 is in IDLE state */ + cc1100_spi_strobe(CC1100_SIDLE); - // Set the new mode - bool result = cc1100_set_mode0(mode, opt_mode_data); + /* Set the new mode */ + bool result = cc1100_set_mode0(mode, opt_mode_data); - // If mode change was successful (mode is valid) - if (result) - { - // Setup new mode configuration - cc1100_setup_mode(); - // Reset statistics - cc1100_reset_statistic(); - return true; - } - else - { - // Still in old mode, go to receive mode again - cc1100_go_receive(); - return false; - } + /* If mode change was successful (mode is valid) */ + if(result) { + /* Setup new mode configuration */ + cc1100_setup_mode(); + /* Reset statistics */ + cc1100_reset_statistic(); + return true; + } + else { + /* Still in old mode, go to receive mode again */ + cc1100_go_receive(); + return false; + } } -char* cc1100_mode_to_text(uint8_t mode) +char *cc1100_mode_to_text(uint8_t mode) { - switch (mode) - { - case CC1100_MODE_WOR: - return "Wake-On-Radio"; - case CC1100_MODE_CONSTANT_RX: - return "Constant RX"; - default: - return "unknown"; - } + switch(mode) { + case CC1100_MODE_WOR: + return "Wake-On-Radio"; + + case CC1100_MODE_CONSTANT_RX: + return "Constant RX"; + + default: + return "unknown"; + } } -char* cc1100_state_to_text(uint8_t state) +char *cc1100_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"; - } + 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 cc1100_hwtimer_go_receive_wrapper(void *ptr) { - // kernel timer handler function called, clear timer id - wor_hwtimer_id = -1; - // Stability: don't allow WOR timers at this point - if (rflags.TX) return; - if (radio_state == RADIO_PWD) { - // Go to RX state, listen for packets as long as WOR_TIMEOUT_2 - cc1100_spi_strobe(CC1100_SRX); - hwtimer_wait(IDLE_TO_RX_TIME); - radio_state = RADIO_RX; - // Set hwtimer to put CC1100 back to WOR after WOR_TIMEOUT_2 - wor_hwtimer_id = hwtimer_set(WOR_TIMEOUT_2, cc1100_hwtimer_go_receive_wrapper, NULL); - if (wor_hwtimer_id == -1) - { - rflags.KT_RES_ERR = true; - // No hwtimer available, go immediately to WOR mode. - // Else never receiving packets again... - rflags.MAN_WOR = false; - switch_to_wor2(); - } - } else { - cc1100_go_receive(); - } + /* kernel timer handler function called, clear timer id */ + wor_hwtimer_id = -1; + + /* Stability: don't allow WOR timers at this point */ + if(rflags.TX) { + return; + } + + if(radio_state == RADIO_PWD) { + /* Go to RX state, listen for packets as long as WOR_TIMEOUT_2 */ + cc1100_spi_strobe(CC1100_SRX); + hwtimer_wait(IDLE_TO_RX_TIME); + radio_state = RADIO_RX; + /* Set hwtimer to put CC1100 back to WOR after WOR_TIMEOUT_2 */ + wor_hwtimer_id = hwtimer_set(WOR_TIMEOUT_2, cc1100_hwtimer_go_receive_wrapper, NULL); + + if(wor_hwtimer_id == -1) { + rflags.KT_RES_ERR = true; + /* No hwtimer available, go immediately to WOR mode. */ + /* Else never receiving packets again... */ + rflags.MAN_WOR = false; + switch_to_wor2(); + } + } + else { + cc1100_go_receive(); + } } /*---------------------------------------------------------------------------*/ -// CC1100 reset functionality +/* CC1100 reset functionality */ /*---------------------------------------------------------------------------*/ static void reset(void) { - cc1100_go_idle(); - cc110x_spi_select(); - cc1100_spi_strobe(CC1100_SRES); - hwtimer_wait(RTIMER_TICKS(10)); + cc1100_go_idle(); + cc110x_spi_select(); + cc1100_spi_strobe(CC1100_SRES); + hwtimer_wait(RTIMER_TICKS(10)); } static void power_up_reset(void) { - cc110x_spi_unselect(); - cc110x_spi_cs(); - cc110x_spi_unselect(); - hwtimer_wait(RESET_WAIT_TIME); - reset(); - radio_state = RADIO_IDLE; + cc110x_spi_unselect(); + cc110x_spi_cs(); + cc110x_spi_unselect(); + hwtimer_wait(RESET_WAIT_TIME); + reset(); + radio_state = RADIO_IDLE; } /*---------------------------------------------------------------------------*/ -// CC1100 low level send function +/* CC1100 low level send function */ /*---------------------------------------------------------------------------*/ void cc1100_send_raw(uint8_t *tx_buffer, uint8_t size) { - volatile uint32_t abort_count; - // 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; + volatile uint32_t abort_count; - // Disables RX interrupt etc. - cc110x_before_send(); + /* 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; + } - // But CC1100 in IDLE mode to flush the FIFO + /* Disables RX interrupt etc. */ + cc110x_before_send(); + + /* But CC1100 in IDLE mode to flush the FIFO */ cc1100_spi_strobe(CC1100_SIDLE); - // Flush TX FIFO to be sure it is empty + /* Flush TX FIFO to be sure it is empty */ cc1100_spi_strobe(CC1100_SFTX); - // Write packet into TX FIFO - cc1100_spi_writeburst_reg(CC1100_TXFIFO, (char*) tx_buffer, size); - // Switch to TX mode + /* Write packet into TX FIFO */ + cc1100_spi_writeburst_reg(CC1100_TXFIFO, (char *) tx_buffer, size); + /* Switch to TX mode */ abort_count = 0; unsigned int cpsr = disableIRQ(); cc1100_spi_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; - } + + /* 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 + + /* Wait for GDO2 to be cleared -> end of packet */ + while(cc110x_get_gdo2() != 0); + + /* Experimental - TOF Measurement */ cc110x_after_send(); } /*---------------------------------------------------------------------------*/ -// Various functions (mode safe - they can be called in any radio mode) +/* Various functions (mode safe - they can be called in any radio mode) */ /*---------------------------------------------------------------------------*/ uint8_t read_register(uint8_t r) { - uint8_t result; + uint8_t result; - // Save old radio state - uint8_t old_state = radio_state; + /* Save old radio state */ + uint8_t old_state = radio_state; - // Wake up from WOR/RX (if in WOR/RX, else no effect) - cc1100_go_idle(); - result = cc1100_spi_read_reg(r); - // 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) { - cc1100_go_receive(); - } + /* Wake up from WOR/RX (if in WOR/RX, else no effect) */ + cc1100_go_idle(); + result = cc1100_spi_read_reg(r); - return result; + /* 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) { + cc1100_go_receive(); + } + + return result; } static void write_register(uint8_t r, uint8_t value) { - // Save old radio state - uint8_t old_state = radio_state; + /* Save old radio state */ + uint8_t old_state = radio_state; - // Wake up from WOR/RX (if in WOR/RX, else no effect) - cc1100_go_idle(); - cc1100_spi_write_reg(r, value); + /* Wake up from WOR/RX (if in WOR/RX, else no effect) */ + cc1100_go_idle(); + cc1100_spi_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) { - cc1100_go_receive(); - } + /* 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) { + cc1100_go_receive(); + } } -char* cc1100_get_output_power(char* buf) +char *cc1100_get_output_power(char *buf) { - sprintf(buf, "%+i dBm", pa_table_dBm[pa_table_index]); - return buf; + sprintf(buf, "%+i dBm", pa_table_dBm[pa_table_index]); + return buf; } uint8_t cc1100_get_channel(void) { - return radio_channel; + return radio_channel; } bool cc1100_set_channel(uint8_t channr) { - if (channr > MAX_CHANNR) return false; - write_register(CC1100_CHANNR, channr*10); - radio_channel = channr; - return true; + if(channr > MAX_CHANNR) { + return false; + } + + write_register(CC1100_CHANNR, channr * 10); + radio_channel = channr; + return true; } bool cc1100_set_output_power(uint8_t pa_idx) { - if (pa_idx >= sizeof(pa_table)) return false; - write_register(CC1100_PATABLE, pa_table[pa_idx]); - pa_table_index = pa_idx; - return true; + if(pa_idx >= sizeof(pa_table)) { + return false; + } + + write_register(CC1100_PATABLE, pa_table[pa_idx]); + pa_table_index = pa_idx; + return true; } -char* cc1100_get_marc_state(void) +char *cc1100_get_marc_state(void) { - uint8_t state; + 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 = cc1100_spi_read_status(CC1100_MARCSTATE) & MARC_STATE; + /* Read content of status register */ + state = cc1100_spi_read_status(CC1100_MARCSTATE) & MARC_STATE; - // Make sure in IDLE state. - // Only goes to IDLE if state was RX/WOR - cc1100_go_idle(); + /* Make sure in IDLE state. */ + /* Only goes to IDLE if state was RX/WOR */ + cc1100_go_idle(); - // 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) { - cc1100_go_receive(); - } + /* 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) { + cc1100_go_receive(); + } - 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"; + } } /* @@ -737,169 +809,168 @@ rssi_2_dbm(uint8_t rssi) }*/ /*---------------------------------------------------------------------------*/ -// Radio Driver API +/* Radio Driver API */ /*---------------------------------------------------------------------------*/ void cc1100_init(void) { - // Initialize SPI - cc110x_spi_init(); + /* Initialize SPI */ + cc110x_spi_init(); - // Set default mode (with default (energy optimized) RX interval) - cc1100_set_mode0(CC1100_RADIO_MODE, T_RX_INTERVAL); + /* Set default mode (with default (energy optimized) RX interval) */ + cc1100_set_mode0(CC1100_RADIO_MODE, T_RX_INTERVAL); - // Load driver & reset - power_up_reset(); + /* Load driver & reset */ + power_up_reset(); - // Write configuration to configuration registers - extern char cc1100_conf[]; + /* Write configuration to configuration registers */ + extern char cc1100_conf[]; cc1100_spi_writeburst_reg(0x00, cc1100_conf, CC1100_CONF_SIZE); - // Write PATABLE (power settings) - cc1100_spi_write_reg(CC1100_PATABLE, pa_table[pa_table_index]); + /* Write PATABLE (power settings) */ + cc1100_spi_write_reg(CC1100_PATABLE, pa_table[pa_table_index]); - // Initialize Radio Flags - rflags.RSSI = 0x00; - rflags.LL_ACK = false; - rflags.CAA = false; - rflags.CRC_STATE = false; - rflags.SEQ = false; - rflags.MAN_WOR = false; - rflags.KT_RES_ERR = false; - rflags.TX = false; - rflags.WOR_RST = false; + /* Initialize Radio Flags */ + rflags.RSSI = 0x00; + rflags.LL_ACK = false; + rflags.CAA = false; + rflags.CRC_STATE = false; + rflags.SEQ = false; + rflags.MAN_WOR = false; + rflags.KT_RES_ERR = false; + rflags.TX = false; + rflags.WOR_RST = false; - // Initialize physical layer - cc1100_phy_init(); + /* Initialize physical layer */ + cc1100_phy_init(); - // Set radio address of CC1100 - cc1100_set_address(radio_address); + /* Set radio address of CC1100 */ + cc1100_set_address(radio_address); - // Set default channel number - radio_channel = CC1100_DEFAULT_CHANNR; + /* Set default channel number */ + radio_channel = CC1100_DEFAULT_CHANNR; - // 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); } int cc1100_get_avg_transmission_duration(void) { - if (radio_mode == CC1100_MODE_WOR) { - // Transmission duration ~ RX interval - // Double value because of MAC delay. - return 2 * cc1100_wor_config.rx_interval; - } else { - // Transmission duration ~ 32 ms - // Double value because of MAC delay. - return 2 * 32; - } + if(radio_mode == CC1100_MODE_WOR) { + /* Transmission duration ~ RX interval */ + /* Double value because of MAC delay. */ + return 2 * cc1100_wor_config.rx_interval; + } + else { + /* Transmission duration ~ 32 ms */ + /* Double value because of MAC delay. */ + return 2 * 32; + } } radio_address_t cc1100_get_address(void) { - return radio_address; + return radio_address; } bool cc1100_set_address(radio_address_t address) { - if (address < MIN_UID || address > MAX_UID) - { - return false; - } + if(address < MIN_UID || address > MAX_UID) { + return false; + } - 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 true; + if(radio_state != RADIO_UNKNOWN) { + write_register(CC1100_ADDR, id); + } + + radio_address = id; + return true; } static int rd_set_mode(int mode) { - int result; + int result; - // Get current radio mode - if (radio_state == RADIO_UNKNOWN || radio_state == RADIO_PWD) - { - result = RADIO_MODE_OFF; - } - else - { - result = 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: - cc110x_init_interrupts(); // Enable interrupts - cc1100_setup_mode(); // Set chip to desired mode - break; - case RADIO_MODE_OFF: - cc1100_disable_interrupts(); // Disable interrupts - switch_to_pwd(); // Set chip to power down mode - break; - case RADIO_MODE_GET: - // do nothing, just return current mode - default: - // do nothing - break; - } + switch(mode) { + case RADIO_MODE_ON: + cc110x_init_interrupts(); /* Enable interrupts */ + cc1100_setup_mode(); /* Set chip to desired mode */ + break; - // Return previous mode - return result; + case RADIO_MODE_OFF: + cc1100_disable_interrupts(); /* Disable interrupts */ + 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; } /*---------------------------------------------------------------------------*/ -// Carrier sense interface functions +/* Carrier sense interface functions */ /*---------------------------------------------------------------------------*/ void cc1100_cs_init(void) { - cc1100_go_idle(); // Wake CC1100 up from Wake-On-Radio mode - if (radio_state == RADIO_RX) // If radio in RX mode - { - cc1100_spi_strobe(CC1100_SIDLE); // Go back to IDLE for calibration - } - cc1100_spi_write_reg(CC1100_MCSM0, 0x08); // Turn off FS-Autocal - cc1100_spi_strobe(CC1100_SCAL); // Calibrate manually (721 us) - hwtimer_wait(MANUAL_FS_CAL_TIME); // Wait for calibration to finish before packet burst can start - radio_state = RADIO_AIR_FREE_WAITING; // Set status "waiting for air free" - cc1100_spi_write_reg(CC1100_MCSM2, 0x07); // Configure RX_TIME = Until end of packet (no timeout) - cc1100_spi_strobe(CC1100_SRX); // Switch to RX (88.4 us) (Carrier Sense) - hwtimer_wait(CS_READY_TIME); // Wait until CC1100 is in RX + carrier sense ready (GDO0 ready for readout -> data rate dependent!!!) + cc1100_go_idle(); /* Wake CC1100 up from Wake-On-Radio mode */ + + if(radio_state == RADIO_RX) { /* If radio in RX mode */ + cc1100_spi_strobe(CC1100_SIDLE); /* Go back to IDLE for calibration */ + } + + cc1100_spi_write_reg(CC1100_MCSM0, 0x08); /* Turn off FS-Autocal */ + cc1100_spi_strobe(CC1100_SCAL); /* Calibrate manually (721 us) */ + hwtimer_wait(MANUAL_FS_CAL_TIME); /* Wait for calibration to finish before packet burst can start */ + radio_state = RADIO_AIR_FREE_WAITING; /* Set status "waiting for air free" */ + cc1100_spi_write_reg(CC1100_MCSM2, 0x07); /* Configure RX_TIME = Until end of packet (no timeout) */ + cc1100_spi_strobe(CC1100_SRX); /* Switch to RX (88.4 us) (Carrier Sense) */ + hwtimer_wait(CS_READY_TIME); /* Wait until CC1100 is in RX + carrier sense ready (GDO0 ready for readout -> data rate dependent!!!) */ } void cc1100_cs_set_enabled(bool enabled) { - if (enabled) - { - // Enable carrier sense detection (GDO0 interrupt) - cc110x_gdo0_enable(); - } - else - { - // Disable carrier sense detection (GDO0 interrupt) - cc110x_gdo0_disable(); - } + if(enabled) { + /* Enable carrier sense detection (GDO0 interrupt) */ + cc110x_gdo0_enable(); + } + else { + /* Disable carrier sense detection (GDO0 interrupt) */ + cc110x_gdo0_disable(); + } } int cc1100_cs_read(void) { - /* GDO0 reflects CS (high: air not free, low: air free) */ - return cc110x_get_gdo0(); + /* GDO0 reflects CS (high: air not free, low: air free) */ + return cc110x_get_gdo0(); } int cc1100_cs_read_cca(void) { - return rflags.CAA; + return rflags.CAA; } void cc1100_cs_write_cca(const int cca) { - rflags.CAA = cca; + rflags.CAA = cca; } /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/drivers/cc110x/cc1100.h b/drivers/cc110x/cc1100.h index 86bc592195..5655133857 100644 --- a/drivers/cc110x/cc1100.h +++ b/drivers/cc110x/cc1100.h @@ -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. diff --git a/drivers/cc110x/cc1100_phy.c b/drivers/cc110x/cc1100_phy.c index 6bc27601bd..d643c9eebf 100644 --- a/drivers/cc110x/cc1100_phy.c +++ b/drivers/cc110x/cc1100_phy.c @@ -37,6 +37,7 @@ and the mailinglist (subscription via web site) * @author Freie Universität Berlin, Computer Systems & Telematics * @author Thomas Hillebrandt * @author Heiko Will + * @author Oliver Hahm * @version $Revision: 2130 $ * * @note $Id: cc1100_phy.c 2130 2010-05-12 13:19:07Z hillebra $ @@ -69,13 +70,12 @@ and the mailinglist (subscription via web site) #define W_FLAGS_PROTOCOL(x) ((x<<1) & 0x0E) ///< Macro for writing the protocol in the flags field /*---------------------------------------------------------------------------*/ -// RX/TX buffer data structures +/* RX/TX buffer data structures */ /*---------------------------------------------------------------------------*/ -typedef struct rx_buffer_t -{ - cc1100_packet_layer0_t packet; - packet_info_t info; +typedef struct { + cc1100_packet_layer0_t packet; + packet_info_t info; } rx_buffer_t; #define RX_BUFF_SIZE (10) ///< Size of RX queue @@ -86,7 +86,7 @@ static rx_buffer_t rx_buffer[RX_BUFF_SIZE]; ///< RX buffer static cc1100_packet_layer0_t tx_buffer; ///< TX buffer (for one packet) /*---------------------------------------------------------------------------*/ -// Process/Event management data structures +/* Process/Event management data structures */ /*---------------------------------------------------------------------------*/ #define MAX_PACKET_HANDLERS (5) @@ -105,7 +105,7 @@ static void cc1100_event_handler_function(void); static char event_handler_stack[KERNEL_CONF_STACKSIZE_MAIN]; /*---------------------------------------------------------------------------*/ -// Sequence number buffer management data structures +/* Sequence number buffer management data structures */ /*---------------------------------------------------------------------------*/ /** @@ -114,17 +114,16 @@ static char event_handler_stack[KERNEL_CONF_STACKSIZE_MAIN]; */ #define MAX_SEQ_BUFFER_SIZE (20) ///< Maximum size of the sequence number buffer -typedef struct -{ - uint64_t m_ticks; ///< 64-bit timestamp - uint8_t source; ///< Source address - uint8_t identification; ///< Identification (1-bit) +typedef struct { + uint64_t m_ticks; ///< 64-bit timestamp + uint8_t source; ///< Source address + uint8_t identification; ///< Identification (1-bit) } seq_buffer_entry_t; -/// Sequence number buffer for this layer +//* Sequence number buffer for this layer */ static seq_buffer_entry_t seq_buffer[MAX_SEQ_BUFFER_SIZE]; -/// Next position to enter a new value into ::seqBuffer +//* Next position to enter a new value into ::seqBuffer */ static uint8_t seq_buffer_pos = 0; /** @@ -151,10 +150,9 @@ uint16_t cc1100_burst_count; ///< Burst count, number of packets in a burst tr uint8_t cc1100_retransmission_count_uc; ///< Number of retransmissions for unicast uint8_t cc1100_retransmission_count_bc; ///< Number of retransmissions for broadcast -const static double duty_cycle[2][DUTY_CYCLE_SIZE] = ///< Duty cycle values from AN047 -{ - {12.5, 6.25, 3.125, 1.563, 0.781, 0.391, 0.195}, - {1.95, 0.9765, 0.4883, 0.2441, 0.1221, 0.061035, 0.030518} +const static double duty_cycle[2][DUTY_CYCLE_SIZE] = { ///< Duty cycle values from AN047 + {12.5, 6.25, 3.125, 1.563, 0.781, 0.391, 0.195}, + {1.95, 0.9765, 0.4883, 0.2441, 0.1221, 0.061035, 0.030518} }; /*---------------------------------------------------------------------------*/ @@ -169,59 +167,59 @@ cc1100_statistic_t cc1100_statistic; void cc1100_phy_init() { - int i; + int i; - rx_buffer_head = 0; - rx_buffer_tail = 0; - rx_buffer_size = 0; + rx_buffer_head = 0; + rx_buffer_tail = 0; + rx_buffer_size = 0; - // Initialize RX-Buffer (clear content) - for (i = 0; i < RX_BUFF_SIZE; i++) - { - rx_buffer->packet.length = 0; - } + /* Initialize RX-Buffer (clear content) */ + for(i = 0; i < RX_BUFF_SIZE; i++) { + rx_buffer->packet.length = 0; + } - // Initialize handler table & packet monitor - packet_monitor = NULL; - pm_init_table((pm_table_t*)&handler_table, MAX_PACKET_HANDLERS, handlers); + /* Initialize handler table & packet monitor */ + packet_monitor = NULL; + pm_init_table((pm_table_t *)&handler_table, MAX_PACKET_HANDLERS, handlers); - // Clear sequence number buffer - memset(seq_buffer, 0, sizeof(seq_buffer_entry_t) * MAX_SEQ_BUFFER_SIZE); + /* Clear sequence number buffer */ + memset(seq_buffer, 0, sizeof(seq_buffer_entry_t) * MAX_SEQ_BUFFER_SIZE); - // Initialize mutex - cc1100_mutex_pid = -1; - mutex_init(&cc1100_mutex); + /* Initialize mutex */ + cc1100_mutex_pid = -1; + mutex_init(&cc1100_mutex); - // Allocate event numbers and start cc1100 event process - cc1100_event_handler_pid = thread_create(event_handler_stack, sizeof(event_handler_stack), PRIORITY_CC1100, CREATE_STACKTEST, - cc1100_event_handler_function, cc1100_event_handler_name); + /* Allocate event numbers and start cc1100 event process */ + cc1100_event_handler_pid = thread_create(event_handler_stack, sizeof(event_handler_stack), PRIORITY_CC1100, CREATE_STACKTEST, + cc1100_event_handler_function, cc1100_event_handler_name); - // Active watchdog for the first time - if (radio_mode == CC1100_MODE_CONSTANT_RX) { - cc1100_watch_dog_period.microseconds = CC1100_WATCHDOG_PERIOD; - if (cc1100_watch_dog_period.microseconds != 0) { - timex_t temp = timex_set(0, 5000000L); + /* Active watchdog for the first time */ + if(radio_mode == CC1100_MODE_CONSTANT_RX) { + cc1100_watch_dog_period.microseconds = CC1100_WATCHDOG_PERIOD; + + if(cc1100_watch_dog_period.microseconds != 0) { + timex_t temp = timex_set(0, 5000000L); vtimer_set_msg(&cc1100_watch_dog, temp, cc1100_event_handler_pid, NULL); - } - } + } + } } /*---------------------------------------------------------------------------*/ -// CC1100 mutual exclusion +/* CC1100 mutual exclusion */ /*---------------------------------------------------------------------------*/ void cc1100_phy_mutex_lock(void) { - if (active_thread->pid != cc1100_mutex_pid) { - mutex_lock(&cc1100_mutex); - cc1100_mutex_pid = active_thread->pid; - } + if(active_thread->pid != cc1100_mutex_pid) { + mutex_lock(&cc1100_mutex); + cc1100_mutex_pid = active_thread->pid; + } } void cc1100_phy_mutex_unlock(void) { - cc1100_mutex_pid = -1; - mutex_unlock(&cc1100_mutex, 0); + cc1100_mutex_pid = -1; + mutex_unlock(&cc1100_mutex, 0); } /*---------------------------------------------------------------------------*/ @@ -230,61 +228,61 @@ void cc1100_phy_mutex_unlock(void) void cc1100_reset_statistic(void) { - cc1100_statistic.packets_in_up = 0; - cc1100_statistic.acks_send = 0; - cc1100_statistic.packets_out_acked = 0; - cc1100_statistic.packets_in = 0; - cc1100_statistic.packets_out = 0; - cc1100_statistic.packets_out_broadcast = 0; - cc1100_statistic.raw_packets_out_acked = 0; - cc1100_statistic.raw_packets_out = 0; - cc1100_statistic.packets_in_dups = 0; - cc1100_statistic.packets_in_crc_fail = 0; - cc1100_statistic.packets_in_while_tx = 0; - cc1100_statistic.rx_buffer_max = 0; - cc1100_statistic.watch_dog_resets = 0; + cc1100_statistic.packets_in_up = 0; + cc1100_statistic.acks_send = 0; + cc1100_statistic.packets_out_acked = 0; + cc1100_statistic.packets_in = 0; + cc1100_statistic.packets_out = 0; + cc1100_statistic.packets_out_broadcast = 0; + cc1100_statistic.raw_packets_out_acked = 0; + cc1100_statistic.raw_packets_out = 0; + cc1100_statistic.packets_in_dups = 0; + cc1100_statistic.packets_in_crc_fail = 0; + cc1100_statistic.packets_in_while_tx = 0; + cc1100_statistic.rx_buffer_max = 0; + cc1100_statistic.watch_dog_resets = 0; } void cc1100_print_statistic(void) { - printf("\nStatistic on CC1100 interface\n\n"); - printf("Total packets send on layer 0.5 (broadcast): %lu\n", cc1100_statistic.packets_out_broadcast); - printf("Total packets send on layer 0.5 (unicast): %lu\n", cc1100_statistic.packets_out); - printf("Total packets Acked on layer 0.5: %lu (%.2f%%)\n", cc1100_statistic.packets_out_acked, cc1100_statistic.packets_out_acked * (100.0f / (float)cc1100_statistic.packets_out)); - printf("Total packets send on layer 0: %lu\n", cc1100_statistic.raw_packets_out); - printf("Total packets send on layer 0 w. Ack on Layer 0.5: %lu (Avg. Ack after: %lu packets)\n", cc1100_statistic.raw_packets_out_acked, cc1100_statistic.raw_packets_out_acked / cc1100_statistic.packets_out_acked); - printf("Burst count on this node: %i (%.2f%%)\n", cc1100_burst_count, (100/(float)cc1100_burst_count) * (cc1100_statistic.raw_packets_out_acked / (float) cc1100_statistic.packets_out_acked)); - printf("Total packets In on layer 0: %lu\n", cc1100_statistic.packets_in); - printf("Duped packets In on layer 0: %lu\n", cc1100_statistic.packets_in_dups); - printf("Corrupted packets In on layer 0: %lu\n", cc1100_statistic.packets_in_crc_fail); - printf("Packets In on layer 0 while in TX: %lu\n", cc1100_statistic.packets_in_while_tx); - printf("Total packets In and up to layer 1: %lu (%.2f%%)\n", cc1100_statistic.packets_in_up, cc1100_statistic.packets_in_up * (100.0f / (float)cc1100_statistic.packets_in)); - printf("Total Acks send on layer 0.5: %lu\n", cc1100_statistic.acks_send); - printf("RX Buffer max: %lu (now: %u)\n", cc1100_statistic.rx_buffer_max, rx_buffer_size); - printf("State machine resets by cc1100 watchdog: %lu\n", cc1100_statistic.watch_dog_resets); + printf("\nStatistic on CC1100 interface\n\n"); + printf("Total packets send on layer 0.5 (broadcast): %lu\n", cc1100_statistic.packets_out_broadcast); + printf("Total packets send on layer 0.5 (unicast): %lu\n", cc1100_statistic.packets_out); + printf("Total packets Acked on layer 0.5: %lu (%.2f%%)\n", cc1100_statistic.packets_out_acked, cc1100_statistic.packets_out_acked * (100.0f / (float)cc1100_statistic.packets_out)); + printf("Total packets send on layer 0: %lu\n", cc1100_statistic.raw_packets_out); + printf("Total packets send on layer 0 w. Ack on Layer 0.5: %lu (Avg. Ack after: %lu packets)\n", cc1100_statistic.raw_packets_out_acked, cc1100_statistic.raw_packets_out_acked / cc1100_statistic.packets_out_acked); + printf("Burst count on this node: %i (%.2f%%)\n", cc1100_burst_count, (100 / (float)cc1100_burst_count) * (cc1100_statistic.raw_packets_out_acked / (float) cc1100_statistic.packets_out_acked)); + printf("Total packets In on layer 0: %lu\n", cc1100_statistic.packets_in); + printf("Duped packets In on layer 0: %lu\n", cc1100_statistic.packets_in_dups); + printf("Corrupted packets In on layer 0: %lu\n", cc1100_statistic.packets_in_crc_fail); + printf("Packets In on layer 0 while in TX: %lu\n", cc1100_statistic.packets_in_while_tx); + printf("Total packets In and up to layer 1: %lu (%.2f%%)\n", cc1100_statistic.packets_in_up, cc1100_statistic.packets_in_up * (100.0f / (float)cc1100_statistic.packets_in)); + printf("Total Acks send on layer 0.5: %lu\n", cc1100_statistic.acks_send); + printf("RX Buffer max: %lu (now: %u)\n", cc1100_statistic.rx_buffer_max, rx_buffer_size); + printf("State machine resets by cc1100 watchdog: %lu\n", cc1100_statistic.watch_dog_resets); } void cc1100_print_config(void) { - char buf[8]; - printf("Current radio mode: %s\r\n", cc1100_mode_to_text(radio_mode)); - printf("Current radio state: %s\r\n", cc1100_state_to_text(radio_state)); - printf("Current MARC state: %s\r\n", cc1100_get_marc_state()); - printf("Current channel number: %u\r\n", cc1100_get_channel()); - printf("Burst count: %u packet(s)\r\n", cc1100_burst_count); - printf("Retransmissions (unicast): %u - if no ACK\r\n", cc1100_retransmission_count_uc); - printf("Retransmissions (broadcast): %u - always\r\n", cc1100_retransmission_count_bc); - printf("Output power setting: %s\r\n", cc1100_get_output_power(buf)); - if (radio_mode == CC1100_MODE_WOR) - { - printf("RX polling interval: %u ms\r\n", cc1100_wor_config.rx_interval); - printf("WOR receive time: 0x%.2X (%f ms)\r\n", cc1100_wor_config.rx_time_reg, - cc1100_wor_config.rx_time_ms); - printf("CC1100 WOREVT0 register: 0x%.2X\r\n", cc1100_wor_config.wor_evt_0); - printf("CC1100 WOREVT1 register: 0x%.2X\r\n", cc1100_wor_config.wor_evt_1); - printf("CC1100 WOR_CTRL register: 0x%.2X\r\n", cc1100_wor_config.wor_ctrl); - printf("CC1100 MAN_WOR flag: %u\r\n", rflags.MAN_WOR); - } + char buf[8]; + printf("Current radio mode: %s\r\n", cc1100_mode_to_text(radio_mode)); + printf("Current radio state: %s\r\n", cc1100_state_to_text(radio_state)); + printf("Current MARC state: %s\r\n", cc1100_get_marc_state()); + printf("Current channel number: %u\r\n", cc1100_get_channel()); + printf("Burst count: %u packet(s)\r\n", cc1100_burst_count); + printf("Retransmissions (unicast): %u - if no ACK\r\n", cc1100_retransmission_count_uc); + printf("Retransmissions (broadcast): %u - always\r\n", cc1100_retransmission_count_bc); + printf("Output power setting: %s\r\n", cc1100_get_output_power(buf)); + + if(radio_mode == CC1100_MODE_WOR) { + printf("RX polling interval: %u ms\r\n", cc1100_wor_config.rx_interval); + printf("WOR receive time: 0x%.2X (%f ms)\r\n", cc1100_wor_config.rx_time_reg, + cc1100_wor_config.rx_time_ms); + printf("CC1100 WOREVT0 register: 0x%.2X\r\n", cc1100_wor_config.wor_evt_0); + printf("CC1100 WOREVT1 register: 0x%.2X\r\n", cc1100_wor_config.wor_evt_1); + printf("CC1100 WOR_CTRL register: 0x%.2X\r\n", cc1100_wor_config.wor_ctrl); + printf("CC1100 MAN_WOR flag: %u\r\n", rflags.MAN_WOR); + } } /*---------------------------------------------------------------------------*/ @@ -293,78 +291,82 @@ void cc1100_print_config(void) inline uint16_t iround(double d) { - return (uint16_t) d<0?d-.5:d+.5; + return (uint16_t) d < 0 ? d - .5 : d + .5; } int cc1100_phy_calc_wor_settings(uint16_t millis) { - // Get packet interval as milliseconds - double t_packet_interval = (double) ((T_PACKET_INTERVAL) / 1000.0); + /* Get packet interval as milliseconds */ + double t_packet_interval = (double)((T_PACKET_INTERVAL) / 1000.0); - // Calculate minimal T_EVENT0: - // - // (1) t_rx_time > t_packet_interval - // (2) t_rx_time = T_EVENT0 / 2 ^ (RX_TIME + 3 + WOR_RES) - // ------------------------------------------------------ - // with RX_TIME = 0 && WOR_RES = 0 => event0_min > t_packet_interval * 8 - // - // t_packet_interval = 3.8 ms (@400kbit/s) - // - // => event0_min = Math.ceil(3.8 * 8) + 10 - uint16_t event0_min = (uint16_t)(t_packet_interval * 8) + 1 + 10; + /* Calculate minimal T_EVENT0: + + (1) t_rx_time > t_packet_interval + (2) t_rx_time = T_EVENT0 / 2 ^ (RX_TIME + 3 + WOR_RES) + ------------------------------------------------------ + with RX_TIME = 0 && WOR_RES = 0 => event0_min > t_packet_interval * 8 + + t_packet_interval = 3.8 ms (@400kbit/s) + + => event0_min = Math.ceil(3.8 * 8) + 10 */ + uint16_t event0_min = (uint16_t)(t_packet_interval * 8) + 1 + 10; - // Check if given value is in allowed range - if (millis < event0_min || millis > EVENT0_MAX) - { - return -1; - } + /* Check if given value is in allowed range */ + if(millis < event0_min || millis > EVENT0_MAX) { + return -1; + } - // Time resolution for EVENT0 and other WOR parameters, - // possible values are 0 and 1 if WOR is used - uint8_t wor_res = millis < WOR_RES_SWITCH ? 0 : 1; + /* Time resolution for EVENT0 and other WOR parameters, */ + /* possible values are 0 and 1 if WOR is used */ + uint8_t wor_res = millis < WOR_RES_SWITCH ? 0 : 1; - // Calculate new value for EVENT0 - double tmp = (millis * 26) / (double) 750; - if (wor_res == 1) tmp /= 32; - tmp *= 1000; - uint16_t event0 = (uint16_t) iround(tmp); + /* Calculate new value for EVENT0 */ + double tmp = (millis * 26) / (double) 750; - // Calculate all possible RX timeouts - int i; - double rx_timeouts[DUTY_CYCLE_SIZE]; - for (i = 0; i < DUTY_CYCLE_SIZE; i++) - { - rx_timeouts[i] = (millis * duty_cycle[wor_res][i]) / 100; - } + if(wor_res == 1) { + tmp /= 32; + } - // Calculate index for optimal rx_timeout (MCSM2.RX_TIME) (if possible) - int idx = -1; - for (i = DUTY_CYCLE_SIZE - 1; i >= 0; i--) - { - if (rx_timeouts[i] > t_packet_interval) - { - idx = i; - break; - } - } + tmp *= 1000; + uint16_t event0 = (uint16_t) iround(tmp); - // If no index found, exit here (configuration with given value is not possible) - if (idx == -1) return -1; + /* Calculate all possible RX timeouts */ + int i; + double rx_timeouts[DUTY_CYCLE_SIZE]; - // Calculate burst count (secure burst calculation with 8 extra packets) - int burst_count = (int) iround(millis / t_packet_interval) + 8; + for(i = 0; i < DUTY_CYCLE_SIZE; i++) { + rx_timeouts[i] = (millis * duty_cycle[wor_res][i]) / 100; + } - // All calculations successful, now its safe to store - // final configuration values in global WOR configuration - cc1100_wor_config.rx_interval = millis; - cc1100_wor_config.wor_ctrl = (wor_res == 0) ? 0x78 : 0x79; - cc1100_wor_config.wor_evt_0 = (uint8_t) event0; - cc1100_wor_config.wor_evt_1 = (uint8_t) (event0 >> 8); - cc1100_wor_config.rx_time_reg = idx; - cc1100_wor_config.rx_time_ms = rx_timeouts[idx]; + /* Calculate index for optimal rx_timeout (MCSM2.RX_TIME) (if possible) */ + int idx = -1; - // If successful, return number of packets in a burst transfer - return burst_count; + for(i = DUTY_CYCLE_SIZE - 1; i >= 0; i--) { + if(rx_timeouts[i] > t_packet_interval) { + idx = i; + break; + } + } + + /* If no index found, exit here (configuration with given value is not possible) */ + if(idx == -1) { + return -1; + } + + /* Calculate burst count (secure burst calculation with 8 extra packets) */ + int burst_count = (int) iround(millis / t_packet_interval) + 8; + + /* All calculations successful, now its safe to store */ + /* final configuration values in global WOR configuration */ + cc1100_wor_config.rx_interval = millis; + cc1100_wor_config.wor_ctrl = (wor_res == 0) ? 0x78 : 0x79; + cc1100_wor_config.wor_evt_0 = (uint8_t) event0; + cc1100_wor_config.wor_evt_1 = (uint8_t)(event0 >> 8); + cc1100_wor_config.rx_time_reg = idx; + cc1100_wor_config.rx_time_ms = rx_timeouts[idx]; + + /* If successful, return number of packets in a burst transfer */ + return burst_count; } /*---------------------------------------------------------------------------*/ @@ -373,507 +375,525 @@ int cc1100_phy_calc_wor_settings(uint16_t millis) static bool contains_seq_entry(uint8_t src, uint8_t id) { - int i; - uint32_t cmp; - timex_t now_timex; - vtimer_now(&now_timex); - uint64_t now = now_timex.microseconds; + int i; + uint32_t cmp; + timex_t now_timex; + vtimer_now(&now_timex); + uint64_t now = now_timex.microseconds; - for (i = 0; i < MAX_SEQ_BUFFER_SIZE; i++) - { - if ((seq_buffer[i].source == src) && (seq_buffer[i].identification == id)) - { - // Check if time stamp is OK - cmp = (radio_mode == CC1100_MODE_WOR) ? cc1100_wor_config.rx_interval : 16000; // constant RX ~16ms - if ((now - seq_buffer[i].m_ticks) <= cmp) - { - return true; - } - else - { - seq_buffer[i].source = 0; // Reset - } - } - } - return false; + for(i = 0; i < MAX_SEQ_BUFFER_SIZE; i++) { + if((seq_buffer[i].source == src) && (seq_buffer[i].identification == id)) { + /* Check if time stamp is OK */ + cmp = (radio_mode == CC1100_MODE_WOR) ? cc1100_wor_config.rx_interval : 16000; /* constant RX ~16ms */ + + if((now - seq_buffer[i].m_ticks) <= cmp) { + return true; + } + else { + seq_buffer[i].source = 0; /* Reset */ + } + } + } + + return false; } static void add_seq_entry(uint8_t src, uint8_t id) { - // Remove all entries with given source to avoid short time overflow - // of one bit counter (of the source node). So a valid packet would get - // lost (especially important in constant RX mode). - int i; - for (i = 0; i < MAX_SEQ_BUFFER_SIZE; i++) - { - if (seq_buffer[i].source == src) - { - seq_buffer[i].source = 0; // Reset - } - } + /* Remove all entries with given source to avoid short time overflow + * of one bit counter (of the source node). So a valid packet would get + * lost (especially important in constant RX mode). */ + int i; - // Add new entry - seq_buffer[seq_buffer_pos].source = src; - seq_buffer[seq_buffer_pos].identification = id; - timex_t now; - vtimer_now(&now); + for(i = 0; i < MAX_SEQ_BUFFER_SIZE; i++) { + if(seq_buffer[i].source == src) { + seq_buffer[i].source = 0; /* Reset */ + } + } + + /* Add new entry */ + seq_buffer[seq_buffer_pos].source = src; + seq_buffer[seq_buffer_pos].identification = id; + timex_t now; + vtimer_now(&now); seq_buffer[seq_buffer_pos].m_ticks = now.microseconds; - // Store 16 bit sequence number of layer 0 for speedup - last_seq_num = src; - last_seq_num <<= 8; - last_seq_num += id; + /* Store 16 bit sequence number of layer 0 for speedup */ + last_seq_num = src; + last_seq_num <<= 8; + last_seq_num += id; - seq_buffer_pos++; - if (seq_buffer_pos == MAX_SEQ_BUFFER_SIZE) seq_buffer_pos = 0; + seq_buffer_pos++; + + if(seq_buffer_pos == MAX_SEQ_BUFFER_SIZE) { + seq_buffer_pos = 0; + } } /*---------------------------------------------------------------------------*/ -// CC1100 physical layer send functions +/* CC1100 physical layer send functions */ /*---------------------------------------------------------------------------*/ static void send_link_level_ack(uint8_t dest) { - uint8_t oldState = radio_state; // Save old state - cc1100_packet_layer0_t ack; // Local packet, don't overwrite + uint8_t oldState = radio_state; /* Save old state */ + cc1100_packet_layer0_t ack; /* Local packet, don't overwrite */ - radio_state = RADIO_SEND_ACK; // Set state to "Sending ACK" - cc1100_spi_write_reg(CC1100_MCSM0, 0x08); // Turn off FS-Autocal - cc1100_spi_write_reg(CC1100_MCSM1, 0x00); // TX_OFFMODE = IDLE - ack.length = 3; // possible packet in txBuffer! - ack.address = dest; - ack.phy_src = rflags.RSSI; - ack.flags = (LAYER_1_PROTOCOL_LL_ACK << 1); - cc1100_send_raw((uint8_t*)&ack, // IDLE -> TX (88.4 us) - ack.length+1); - cc1100_spi_write_reg(CC1100_MCSM0, 0x18); // Turn on FS-Autocal - cc1100_spi_write_reg(CC1100_MCSM1, 0x03); // TX_OFFMODE = RX - radio_state = oldState; // Restore state - cc1100_statistic.acks_send++; + radio_state = RADIO_SEND_ACK; /* Set state to "Sending ACK" */ + cc1100_spi_write_reg(CC1100_MCSM0, 0x08); /* Turn off FS-Autocal */ + cc1100_spi_write_reg(CC1100_MCSM1, 0x00); /* TX_OFFMODE = IDLE */ + ack.length = 3; /* possible packet in txBuffer! */ + ack.address = dest; + ack.phy_src = rflags.RSSI; + ack.flags = (LAYER_1_PROTOCOL_LL_ACK << 1); + cc1100_send_raw((uint8_t *)&ack, /* IDLE -> TX (88.4 us) */ + ack.length + 1); + cc1100_spi_write_reg(CC1100_MCSM0, 0x18); /* Turn on FS-Autocal */ + cc1100_spi_write_reg(CC1100_MCSM1, 0x03); /* TX_OFFMODE = RX */ + radio_state = oldState; /* Restore state */ + cc1100_statistic.acks_send++; } static bool send_burst(cc1100_packet_layer0_t *packet, uint8_t retries, uint8_t rtc) { - int i; - radio_state = RADIO_SEND_BURST; - rflags.LL_ACK = false; + int i; + radio_state = RADIO_SEND_BURST; + rflags.LL_ACK = false; - for (i = 1; i <= cc1100_burst_count; i++) - { - /* - * Number of bytes to send is: - * length of phy payload (packet->length) - * + size of length field (1 byte) - */ - extern unsigned long hwtimer_now(void); - timer_tick_t t = hwtimer_now() + RTIMER_TICKS(T_PACKET_INTERVAL); - cc1100_send_raw((uint8_t*)packet, packet->length + 1); // RX -> TX (9.6 us) + for(i = 1; i <= cc1100_burst_count; i++) { + /* + * Number of bytes to send is: + * length of phy payload (packet->length) + * + size of length field (1 byte) + */ + extern unsigned long hwtimer_now(void); + timer_tick_t t = hwtimer_now() + RTIMER_TICKS(T_PACKET_INTERVAL); + cc1100_send_raw((uint8_t *)packet, packet->length + 1); /* RX -> TX (9.6 us) */ - cc1100_statistic.raw_packets_out++; + cc1100_statistic.raw_packets_out++; - // Delay until predefined "send" interval has passed - timer_tick_t now = hwtimer_now(); - if (t > now) - { - hwtimer_wait(t - now); - } + /* Delay until predefined "send" interval has passed */ + timer_tick_t now = hwtimer_now(); - /** - * After sending the packet the CC1100 goes automatically - * into RX mode (21.5 us) (listening for an ACK). - * Do not interrupt burst if send to broadcast address (a node may - * have the broadcast address at startup and would stop the burst - * by sending an ACK). - */ - if (rflags.LL_ACK && packet->address != CC1100_BROADCAST_ADDRESS) - { - cc1100_statistic.raw_packets_out_acked += i; - break; - } - } + if(t > now) { + hwtimer_wait(t - now); + } - // No link level ACK -> do retry if retry counter greater zero - // Note: Event broadcast packets can be sent repeatedly if in - // constant RX mode. In WOR mode it is not necessary, so - // set retry count to zero. - if (!rflags.LL_ACK && retries > 0) - { - return send_burst(packet, retries - 1, rtc + 1); - } + /** + * After sending the packet the CC1100 goes automatically + * into RX mode (21.5 us) (listening for an ACK). + * Do not interrupt burst if send to broadcast address (a node may + * have the broadcast address at startup and would stop the burst + * by sending an ACK). + */ + if(rflags.LL_ACK && packet->address != CC1100_BROADCAST_ADDRESS) { + cc1100_statistic.raw_packets_out_acked += i; + break; + } + } - // Store number of transmission retries - rflags.RETC = rtc; - rflags.RPS = rtc * cc1100_burst_count + i; - if (i > cc1100_burst_count) rflags.RPS--; - rflags.TX = false; + /* No link level ACK -> do retry if retry counter greater zero + * Note: Event broadcast packets can be sent repeatedly if in + * constant RX mode. In WOR mode it is not necessary, so + * set retry count to zero.*/ + if(!rflags.LL_ACK && retries > 0) { + return send_burst(packet, retries - 1, rtc + 1); + } - // Go to mode after TX (CONST_RX -> RX, WOR -> WOR) - cc1100_go_after_tx(); + /* Store number of transmission retries */ + rflags.RETC = rtc; + rflags.RPS = rtc * cc1100_burst_count + i; - // Burst from any other node is definitely over - last_seq_num = 0; + if(i > cc1100_burst_count) { + rflags.RPS--; + } - if (packet->address != CC1100_BROADCAST_ADDRESS && !rflags.LL_ACK) - { - return false; - } + rflags.TX = false; - return true; + /* Go to mode after TX (CONST_RX -> RX, WOR -> WOR) */ + cc1100_go_after_tx(); + + /* Burst from any other node is definitely over */ + last_seq_num = 0; + + if(packet->address != CC1100_BROADCAST_ADDRESS && !rflags.LL_ACK) { + return false; + } + + return true; } int cc1100_send(radio_address_t addr, protocol_t protocol, int priority, char *payload, int payload_len) { - bool result; - int return_code; - uint8_t address; - uint8_t retries; + bool result; + int return_code; + uint8_t address; + uint8_t retries; - // Lock mutex, nobody else should send now - cc1100_phy_mutex_lock(); + /* Lock mutex, nobody else should send now */ + cc1100_phy_mutex_lock(); - // TX state machine lock -> no timers (WOR), no packets (only ACKs) - rflags.TX = true; + /* TX state machine lock -> no timers (WOR), no packets (only ACKs) */ + rflags.TX = true; - // Set chip to idle state - cc1100_set_idle(); + /* Set chip to idle state */ + cc1100_set_idle(); - // CC1100 radio layer only supports 8-bit addresses - address = addr; + /* CC1100 radio layer only supports 8-bit addresses */ + address = addr; - // Loopback not supported - if (address == cc1100_get_address()) - { - return_code = RADIO_ADDR_OUT_OF_RANGE; - goto mode_before_final; - } + /* Loopback not supported */ + if(address == cc1100_get_address()) { + return_code = RADIO_ADDR_OUT_OF_RANGE; + goto mode_before_final; + } - // Check address - if (address > MAX_UID) - { - return_code = RADIO_ADDR_OUT_OF_RANGE; - goto mode_before_final; - } + /* Check address */ + if(address > MAX_UID) { + return_code = RADIO_ADDR_OUT_OF_RANGE; + goto mode_before_final; + } - // Packet too long - if (payload_len > MAX_DATA_LENGTH) - { - return_code = RADIO_PAYLOAD_TOO_LONG; - goto mode_before_final; - } + /* Packet too long */ + if(payload_len > MAX_DATA_LENGTH) { + return_code = RADIO_PAYLOAD_TOO_LONG; + goto mode_before_final; + } - if (radio_state == RADIO_PWD) - { - return_code = RADIO_WRONG_MODE; - goto mode_before_final; - } + if(radio_state == RADIO_PWD) { + return_code = RADIO_WRONG_MODE; + goto mode_before_final; + } - // Set number of transmission retries - retries = (address == CC1100_BROADCAST_ADDRESS) ? - cc1100_retransmission_count_bc : cc1100_retransmission_count_uc; + /* Set number of transmission retries */ + retries = (address == CC1100_BROADCAST_ADDRESS) ? + cc1100_retransmission_count_bc : cc1100_retransmission_count_uc; - memset(tx_buffer.data, 0, MAX_DATA_LENGTH); // Clean data + memset(tx_buffer.data, 0, MAX_DATA_LENGTH); /* Clean data */ - /* TODO: If packets are shorter than max packet size, WOR interval is too long. + /* TODO: If packets are shorter than max packet size, WOR interval is too long. * This must be solved in some way. */ - tx_buffer.length = 3 + payload_len; // 3 bytes (A&PS&F) + data length - tx_buffer.address = address; // Copy destination address - tx_buffer.flags = 0x00; // Set clean state - tx_buffer.flags = W_FLAGS_PROTOCOL(protocol); // Copy protocol identifier - tx_buffer.phy_src = (uint8_t) cc1100_get_address(); // Copy sender address + tx_buffer.length = 3 + payload_len; /* 3 bytes (A&PS&F) + data length */ + tx_buffer.address = address; /* Copy destination address */ + tx_buffer.flags = 0x00; /* Set clean state */ + tx_buffer.flags = W_FLAGS_PROTOCOL(protocol); /* Copy protocol identifier */ + tx_buffer.phy_src = (uint8_t) cc1100_get_address(); /* Copy sender address */ - // Set identification number of packet - tx_buffer.flags |= rflags.SEQ; // Set flags.identification (bit 0) - rflags.SEQ = !rflags.SEQ; // Toggle value of layer 0 sequence number bit + /* Set identification number of packet */ + tx_buffer.flags |= rflags.SEQ; /* Set flags.identification (bit 0) */ + rflags.SEQ = !rflags.SEQ; /* Toggle value of layer 0 sequence number bit */ - memcpy(tx_buffer.data, payload, payload_len); // Copy data + memcpy(tx_buffer.data, payload, payload_len); /* Copy data */ - // Send the packet - cc1100_spi_write_reg(CC1100_MCSM0, 0x08); // Turn off FS-Autocal - result = send_burst(&tx_buffer, retries, 0); // Send raw burst - return_code = result ? payload_len : RADIO_OP_FAILED; + /* Send the packet */ + cc1100_spi_write_reg(CC1100_MCSM0, 0x08); /* Turn off FS-Autocal */ + result = send_burst(&tx_buffer, retries, 0); /* Send raw burst */ + return_code = result ? payload_len : RADIO_OP_FAILED; - // Collect statistics - if (address != CC1100_BROADCAST_ADDRESS) - { - cc1100_statistic.packets_out++; - if (result) cc1100_statistic.packets_out_acked++; - } - else cc1100_statistic.packets_out_broadcast++; + /* Collect statistics */ + if(address != CC1100_BROADCAST_ADDRESS) { + cc1100_statistic.packets_out++; - goto final; + if(result) { + cc1100_statistic.packets_out_acked++; + } + } + else { + cc1100_statistic.packets_out_broadcast++; + } - mode_before_final: - rflags.TX = false; - // Definitely set secure mode (CONST_RX -> RX, WOR -> WOR) - cc1100_go_after_tx(); + goto final; - final: - // Release mutex and return - cc1100_phy_mutex_unlock(); - return return_code; +mode_before_final: + rflags.TX = false; + /* Definitely set secure mode (CONST_RX -> RX, WOR -> WOR) */ + cc1100_go_after_tx(); + +final: + /* Release mutex and return */ + cc1100_phy_mutex_unlock(); + return return_code; } /*---------------------------------------------------------------------------*/ -// RX Event Handler +/* RX Event Handler */ /*---------------------------------------------------------------------------*/ bool cc1100_set_packet_monitor(packet_monitor_t monitor) { - packet_monitor = monitor; - return true; + packet_monitor = monitor; + return true; } int cc1100_set_packet_handler(protocol_t protocol, packet_handler_t handler) { - if (protocol > 7) return -1; // Only 3-bit value allowed - return pm_set_handler(&handler_table, protocol, handler); + if(protocol > 7) { + return -1; /* Only 3-bit value allowed */ + } + + return pm_set_handler(&handler_table, protocol, handler); } static void cc1100_event_handler_function(void) { msg_t m; - while (1) - { - if (cc1100_watch_dog_period.microseconds != 0) { - vtimer_remove(&cc1100_watch_dog); - } - // Test if any resource error has occurred - if (rflags.KT_RES_ERR) - { - rflags.KT_RES_ERR = false; - // possibly do something, e.g. log error condition - } - if (m.type == MSG_TIMER) - { - uint8_t state; - if (radio_mode == CC1100_MODE_CONSTANT_RX) { - state = cc1100_spi_read_status(CC1100_MARCSTATE) & MARC_STATE; - if ((state < 13 || state > 15) && radio_state == RADIO_RX && !rflags.TX) { - cc1100_statistic.watch_dog_resets++; - if (state != 1) { - cc1100_spi_strobe(CC1100_SIDLE); - } - cc1100_spi_strobe(CC1100_SFRX); - cc1100_go_receive(); - } - } else { - // Radio mode is WOR, cannot read current MARC state, will - // always be IDLE. So do nothing here, e.g. disable watchdog. - } - } - while (rx_buffer_size > 0) - { - rx_buffer_t* packet = &rx_buffer[rx_buffer_head]; - protocol_t p = R_FLAGS_PROTOCOL(packet->packet.flags); - if (packet_monitor != NULL) packet_monitor((void*)&packet->packet.data, packet->packet.length, p, &packet->info); - pm_invoke(&handler_table, p, (void*)&packet->packet.data, MAX_DATA_LENGTH, &packet->info); - dINT(); - rx_buffer_size--; - rx_buffer_head++; - if (rx_buffer_head == RX_BUFF_SIZE) rx_buffer_head = 0; - eINT(); - } - dINT(); - if (rx_buffer_size == 0) - { - if (cc1100_watch_dog_period.microseconds != 0) { - timex_t temp = timex_set(0, cc1100_watch_dog_period.microseconds * 1000000L); - vtimer_set_msg(&cc1100_watch_dog, temp, - cc1100_event_handler_pid, NULL); - } - msg_receive(&m); - } - eINT(); + while(1) { + if(cc1100_watch_dog_period.microseconds != 0) { + vtimer_remove(&cc1100_watch_dog); + } + + /* Test if any resource error has occurred */ + if(rflags.KT_RES_ERR) { + rflags.KT_RES_ERR = false; + /* possibly do something, e.g. log error condition */ + } + + if(m.type == MSG_TIMER) { + uint8_t state; + + if(radio_mode == CC1100_MODE_CONSTANT_RX) { + state = cc1100_spi_read_status(CC1100_MARCSTATE) & MARC_STATE; + + if((state < 13 || state > 15) && radio_state == RADIO_RX && !rflags.TX) { + cc1100_statistic.watch_dog_resets++; + + if(state != 1) { + cc1100_spi_strobe(CC1100_SIDLE); + } + + cc1100_spi_strobe(CC1100_SFRX); + cc1100_go_receive(); + } + } + else { + /* Radio mode is WOR, cannot read current MARC state, will */ + /* always be IDLE. So do nothing here, e.g. disable watchdog. */ + } + } + + while(rx_buffer_size > 0) { + rx_buffer_t *packet = &rx_buffer[rx_buffer_head]; + protocol_t p = R_FLAGS_PROTOCOL(packet->packet.flags); + + if(packet_monitor != NULL) { + packet_monitor((void *)&packet->packet.data, packet->packet.length, p, &packet->info); + } + + pm_invoke(&handler_table, p, (void *)&packet->packet.data, MAX_DATA_LENGTH, &packet->info); + dINT(); + rx_buffer_size--; + rx_buffer_head++; + + if(rx_buffer_head == RX_BUFF_SIZE) { + rx_buffer_head = 0; + } + + eINT(); + } + + dINT(); + + if(rx_buffer_size == 0) { + if(cc1100_watch_dog_period.microseconds != 0) { + timex_t temp = timex_set(0, cc1100_watch_dog_period.microseconds * 1000000L); + vtimer_set_msg(&cc1100_watch_dog, temp, + cc1100_event_handler_pid, NULL); + } + + msg_receive(&m); + } + + eINT(); } } /*---------------------------------------------------------------------------*/ -// CC1100 packet (RX) ISR +/* CC1100 packet (RX) ISR */ /*---------------------------------------------------------------------------*/ void cc1100_phy_rx_handler(void) { - msg_t m; - m.type = MSG_POLL; - bool dup = false; - bool res = false; + msg_t m; + m.type = MSG_POLL; + bool dup = false; + bool res = false; - // Possible packet received, RX -> IDLE (0.1 us) - rflags.CAA = false; - rflags.MAN_WOR = false; - cc1100_statistic.packets_in++; + /* Possible packet received, RX -> IDLE (0.1 us) */ + rflags.CAA = false; + rflags.MAN_WOR = false; + cc1100_statistic.packets_in++; - // If WOR timer set, delete it now (new one will be set at end of ISR) - if (wor_hwtimer_id != -1) - { - hwtimer_remove(wor_hwtimer_id); - wor_hwtimer_id = -1; - } + /* If WOR timer set, delete it now (new one will be set at end of ISR) */ + if(wor_hwtimer_id != -1) { + hwtimer_remove(wor_hwtimer_id); + wor_hwtimer_id = -1; + } - // Transfer packet into temporary buffer position - res = cc1100_spi_receive_packet((uint8_t*)&(rx_buffer[rx_buffer_tail].packet), sizeof(cc1100_packet_layer0_t)); + /* Transfer packet into temporary buffer position */ + res = cc1100_spi_receive_packet((uint8_t *) & (rx_buffer[rx_buffer_tail].packet), sizeof(cc1100_packet_layer0_t)); - if (res) - { - // Get packet pointer and store additional data in packet info structure - cc1100_packet_layer0_t* p = &(rx_buffer[rx_buffer_tail].packet); - rx_buffer[rx_buffer_tail].info.phy_src = p->phy_src; - rx_buffer[rx_buffer_tail].info.source = p->phy_src; - rx_buffer[rx_buffer_tail].info.destination = p->address; - rx_buffer[rx_buffer_tail].info.rssi = rflags.RSSI; - rx_buffer[rx_buffer_tail].info.lqi = rflags.LQI; - rx_buffer[rx_buffer_tail].info.promiscuous = false; + if(res) { + /* Get packet pointer and store additional data in packet info structure */ + cc1100_packet_layer0_t *p = &(rx_buffer[rx_buffer_tail].packet); + rx_buffer[rx_buffer_tail].info.phy_src = p->phy_src; + rx_buffer[rx_buffer_tail].info.source = p->phy_src; + rx_buffer[rx_buffer_tail].info.destination = p->address; + rx_buffer[rx_buffer_tail].info.rssi = rflags.RSSI; + rx_buffer[rx_buffer_tail].info.lqi = rflags.LQI; + rx_buffer[rx_buffer_tail].info.promiscuous = false; - // Get protocol and id field out of flags field - uint8_t protocol = R_FLAGS_PROTOCOL(p->flags); - uint8_t identification = (p->flags & FLAGS_IDENTIFICATION); + /* Get protocol and id field out of flags field */ + uint8_t protocol = R_FLAGS_PROTOCOL(p->flags); + uint8_t identification = (p->flags & FLAGS_IDENTIFICATION); - // If received packet was an ACK (here we must be in - // TX lock state, otherwise we don't expect an ACK) - if (protocol == LAYER_1_PROTOCOL_LL_ACK && rflags.TX) - { - // And packet was for us - if (p->address == cc1100_get_address()) - { - // Stop the burst - rflags.LL_ACK = true; - rflags.RSSI_SEND = p->phy_src; - rflags.TCP = (uint32_t)((uint16_t*)p->data)[0]; - } - return; - } - else - { - // No ACK received so TOF is unpredictable - rflags.TOF = 0; - } + /* If received packet was an ACK (here we must be in + * TX lock state, otherwise we don't expect an ACK) */ + if(protocol == LAYER_1_PROTOCOL_LL_ACK && rflags.TX) { + /* And packet was for us */ + if(p->address == cc1100_get_address()) { + /* Stop the burst */ + rflags.LL_ACK = true; + rflags.RSSI_SEND = p->phy_src; + rflags.TCP = (uint32_t)((uint16_t *)p->data)[0]; + } - // 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) - { - cc1100_statistic.packets_in_while_tx++; - return; - } + return; + } + else { + /* No ACK received so TOF is unpredictable */ + rflags.TOF = 0; + } - // If buffer is currently full -> don't check sequence numbers, send - // ACK and restore state (keep always one position free for temporary packets) - if (rx_buffer_size >= RX_BUFF_SIZE-1) goto send_ack; + /* 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) { + cc1100_statistic.packets_in_while_tx++; + return; + } - // Build 16 bit sequence number of layer 0 for fast check - uint16_t new_seq_num = p->phy_src; - new_seq_num <<= 8; - new_seq_num += identification; + /* If buffer is currently full -> don't check sequence numbers, send + * ACK and restore state (keep always one position free for temporary packets) */ + if(rx_buffer_size >= RX_BUFF_SIZE - 1) { + goto send_ack; + } - // Duplicate packet detection - dup = true; + /* Build 16 bit sequence number of layer 0 for fast check */ + uint16_t new_seq_num = p->phy_src; + new_seq_num <<= 8; + new_seq_num += identification; - // If new and last sequence number are the same, then discard packet - if (last_seq_num != new_seq_num) - { - // Do a more precise check (takes more time) with larger buffer - if (!contains_seq_entry(p->phy_src, identification)) - { - // Sequence number is new, no duplicate packet - dup = false; + /* Duplicate packet detection */ + dup = true; - // Store sequence number - add_seq_entry(p->phy_src, identification); + /* If new and last sequence number are the same, then discard packet */ + if(last_seq_num != new_seq_num) { + /* Do a more precise check (takes more time) with larger buffer */ + if(!contains_seq_entry(p->phy_src, identification)) { + /* Sequence number is new, no duplicate packet */ + dup = false; - // Make temporary packet in RX buffer to a "real" packet which is processed - rx_buffer_size++; - if (rx_buffer_size > cc1100_statistic.rx_buffer_max) cc1100_statistic.rx_buffer_max = rx_buffer_size; - rx_buffer_tail++; - if (rx_buffer_tail == RX_BUFF_SIZE) rx_buffer_tail = 0; - // Send empty message to wake up receiver process. - // Receiver process could already be running (triggered by previous message), - // so function would return 0 and assume the receiver is not waiting but indeed - // all is working fine. - msg_send_int(&m, cc1100_event_handler_pid); - cc1100_statistic.packets_in_up++; - } - } + /* Store sequence number */ + add_seq_entry(p->phy_src, identification); - send_ack: - // If packet was send directly to us, send an ACK packet back to sender. - // But only not if the packet itself was a LL-ACK! - if (p->address == cc1100_get_address() && protocol != LAYER_1_PROTOCOL_LL_ACK) - { - send_link_level_ack(p->phy_src); + /* Make temporary packet in RX buffer to a "real" packet which is processed */ + rx_buffer_size++; - // After LL-ACK burst is over, reset number - last_seq_num = 0; - } + if(rx_buffer_size > cc1100_statistic.rx_buffer_max) { + cc1100_statistic.rx_buffer_max = rx_buffer_size; + } - // If duplicate packet detected, clear rxBuffer position - if (dup) - { - cc1100_statistic.packets_in_dups++; - } + rx_buffer_tail++; - // If packet interrupted this nodes send call, - // don't change anything after this point. - if (radio_state == RADIO_AIR_FREE_WAITING) - { - cc1100_spi_strobe(CC1100_SRX); - hwtimer_wait(IDLE_TO_RX_TIME); - return; - } + if(rx_buffer_tail == RX_BUFF_SIZE) { + rx_buffer_tail = 0; + } - // Valid packet. After a wake-up, the radio should be in IDLE. - // So put CC1100 to RX for WOR_TIMEOUT (have to manually put - // the radio back to sleep/WOR). - cc1100_spi_write_reg(CC1100_MCSM0, 0x08); // Turn off FS-Autocal - cc1100_spi_write_reg(CC1100_MCSM2, 0x07); // Configure RX_TIME (until end of packet) - if (radio_mode == CC1100_MODE_CONSTANT_RX) { - cc1100_spi_strobe(CC1100_SRX); - hwtimer_wait(IDLE_TO_RX_TIME); - radio_state = RADIO_RX; - // Return here if mode is CONSTANT_RX_MODE - return; - } else { - cc1100_spi_strobe(CC1100_SPWD); - radio_state = RADIO_PWD; - } + /* Send empty message to wake up receiver process. + * Receiver process could already be running (triggered by previous message), + * so function would return 0 and assume the receiver is not waiting but indeed + * all is working fine.*/ + msg_send_int(&m, cc1100_event_handler_pid); + cc1100_statistic.packets_in_up++; + } + } - // Set hwtimer to put CC1100 back to RX after WOR_TIMEOUT_1 - wor_hwtimer_id = hwtimer_set(WOR_TIMEOUT_1, cc1100_hwtimer_go_receive_wrapper, NULL); - if (wor_hwtimer_id == -1) - { - // Signal hwtimer resource error, radio stays in RX, - // so no big problem, only energy is wasted. - rflags.KT_RES_ERR = true; - } - } - else - { - // No ACK received so TOF is unpredictable - rflags.TOF = 0; + send_ack: - // CRC false or RX buffer full -> clear RX FIFO in both cases - last_seq_num = 0; // Reset for correct burst detection - cc1100_spi_strobe(CC1100_SIDLE); // Switch to IDLE (should already be)... - cc1100_spi_strobe(CC1100_SFRX); // ...for flushing the RX FIFO + /* If packet was send directly to us, send an ACK packet back to sender. + * But only not if the packet itself was a LL-ACK! */ + if(p->address == cc1100_get_address() && protocol != LAYER_1_PROTOCOL_LL_ACK) { + send_link_level_ack(p->phy_src); - // If packet interrupted this nodes send call, - // don't change anything after this point. - if (radio_state == RADIO_AIR_FREE_WAITING) - { - cc1100_spi_strobe(CC1100_SRX); - hwtimer_wait(IDLE_TO_RX_TIME); - return; - } + /* After LL-ACK burst is over, reset number */ + last_seq_num = 0; + } - // If currently sending, exit here (don't go to RX/WOR) - if (radio_state == RADIO_SEND_BURST) - { - cc1100_statistic.packets_in_while_tx++; - return; - } + /* If duplicate packet detected, clear rxBuffer position */ + if(dup) { + cc1100_statistic.packets_in_dups++; + } - // No valid packet, so go back to RX/WOR as soon as possible - cc1100_go_receive(); - } + /* If packet interrupted this nodes send call, + * don't change anything after this point. */ + if(radio_state == RADIO_AIR_FREE_WAITING) { + cc1100_spi_strobe(CC1100_SRX); + hwtimer_wait(IDLE_TO_RX_TIME); + return; + } + + /* Valid packet. After a wake-up, the radio should be in IDLE. + * So put CC1100 to RX for WOR_TIMEOUT (have to manually put + * the radio back to sleep/WOR).*/ + cc1100_spi_write_reg(CC1100_MCSM0, 0x08); * Turn off FS-Autocal + cc1100_spi_write_reg(CC1100_MCSM2, 0x07); /* Configure RX_TIME (until end of packet) */ + + if(radio_mode == CC1100_MODE_CONSTANT_RX) { + cc1100_spi_strobe(CC1100_SRX); + hwtimer_wait(IDLE_TO_RX_TIME); + radio_state = RADIO_RX; + /* Return here if mode is CONSTANT_RX_MODE */ + return; + } + else { + cc1100_spi_strobe(CC1100_SPWD); + radio_state = RADIO_PWD; + } + + /* Set hwtimer to put CC1100 back to RX after WOR_TIMEOUT_1 */ + wor_hwtimer_id = hwtimer_set(WOR_TIMEOUT_1, cc1100_hwtimer_go_receive_wrapper, NULL); + + if(wor_hwtimer_id == -1) { + /* Signal hwtimer resource error, radio stays in RX, + * so no big problem, only energy is wasted. */ + rflags.KT_RES_ERR = true; + } + } + else { + /* No ACK received so TOF is unpredictable */ + rflags.TOF = 0; + + /* CRC false or RX buffer full -> clear RX FIFO in both cases */ + last_seq_num = 0; /* Reset for correct burst detection */ + cc1100_spi_strobe(CC1100_SIDLE); /* Switch to IDLE (should already be)... */ + cc1100_spi_strobe(CC1100_SFRX); /* ...for flushing the RX FIFO */ + + /* If packet interrupted this nodes send call, + * don't change anything after this point. */ + if(radio_state == RADIO_AIR_FREE_WAITING) { + cc1100_spi_strobe(CC1100_SRX); + hwtimer_wait(IDLE_TO_RX_TIME); + return; + } + + /* If currently sending, exit here (don't go to RX/WOR) */ + if(radio_state == RADIO_SEND_BURST) { + cc1100_statistic.packets_in_while_tx++; + return; + } + + /* No valid packet, so go back to RX/WOR as soon as possible */ + cc1100_go_receive(); + } } diff --git a/drivers/cc110x/cc1100_phy.h b/drivers/cc110x/cc1100_phy.h index 8459783add..edce736df8 100644 --- a/drivers/cc110x/cc1100_phy.h +++ b/drivers/cc110x/cc1100_phy.h @@ -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; /*---------------------------------------------------------------------------*/ diff --git a/drivers/cc110x/cc1100_spi.c b/drivers/cc110x/cc1100_spi.c index 04aa21d29b..5f4070ace8 100644 --- a/drivers/cc110x/cc1100_spi.c +++ b/drivers/cc110x/cc1100_spi.c @@ -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; } /** @} */ diff --git a/drivers/cc110x_ng/cc110x-defaultSettings.c b/drivers/cc110x_ng/cc110x-defaultSettings.c index fddfedcf89..3b295cbb38 100644 --- a/drivers/cc110x_ng/cc110x-defaultSettings.c +++ b/drivers/cc110x_ng/cc110x-defaultSettings.c @@ -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 * @author Heiko Will - * @version $Revision: 2058 $ + * @author Oliver Hahm * * @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! diff --git a/drivers/cc110x_ng/cc110x-rx.c b/drivers/cc110x_ng/cc110x-rx.c index 95ce073873..de7f102cd1 100644 --- a/drivers/cc110x_ng/cc110x-rx.c +++ b/drivers/cc110x_ng/cc110x-rx.c @@ -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 + * @} + */ + #include #include #include @@ -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 diff --git a/drivers/cc110x_ng/cc110x-tx.c b/drivers/cc110x_ng/cc110x-tx.c index bffb8339da..4330a80d8d 100644 --- a/drivers/cc110x_ng/cc110x-tx.c +++ b/drivers/cc110x_ng/cc110x-tx.c @@ -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 + * @} + */ + #include #include @@ -11,12 +28,13 @@ #include -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; } diff --git a/drivers/cc110x_ng/cc110x.c b/drivers/cc110x_ng/cc110x.c index 272bdb0b2b..d4f9f7f275 100644 --- a/drivers/cc110x_ng/cc110x.c +++ b/drivers/cc110x_ng/cc110x.c @@ -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 + * @} + */ #include #include #include @@ -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; } - - diff --git a/drivers/cc110x_ng/include/cc110x-config.h b/drivers/cc110x_ng/include/cc110x-config.h index 0344941b2d..9b959e8140 100644 --- a/drivers/cc110x_ng/include/cc110x-config.h +++ b/drivers/cc110x_ng/include/cc110x-config.h @@ -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 + * @} + */ #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 diff --git a/drivers/cc110x_ng/include/cc110x-internal.h b/drivers/cc110x_ng/include/cc110x-internal.h index 77ff43fbce..392b30626d 100644 --- a/drivers/cc110x_ng/include/cc110x-internal.h +++ b/drivers/cc110x_ng/include/cc110x-internal.h @@ -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 + * @} + */ #ifndef CC1100_INTERNAL_H #define CC1100_INTERNAL_H diff --git a/drivers/cc110x_ng/include/cc110x-reg.h b/drivers/cc110x_ng/include/cc110x-reg.h index 49943585f3..f34d1f1cc1 100644 --- a/drivers/cc110x_ng/include/cc110x-reg.h +++ b/drivers/cc110x_ng/include/cc110x-reg.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 * */ @@ -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 */ diff --git a/drivers/cc110x_ng/include/cc110x_ng.h b/drivers/cc110x_ng/include/cc110x_ng.h index 5774cd5aea..c3ca907474 100644 --- a/drivers/cc110x_ng/include/cc110x_ng.h +++ b/drivers/cc110x_ng/include/cc110x_ng.h @@ -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 + * @} + */ #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 diff --git a/drivers/cc110x_ng/spi/cc110x_spi.c b/drivers/cc110x_ng/spi/cc110x_spi.c index 9b2f8234ef..cf7b654ce2 100644 --- a/drivers/cc110x_ng/spi/cc110x_spi.c +++ b/drivers/cc110x_ng/spi/cc110x_spi.c @@ -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; } /** @} */ diff --git a/drivers/include/adc.h b/drivers/include/adc.h index c3151866c0..51ed971ef5 100644 --- a/drivers/include/adc.h +++ b/drivers/include/adc.h @@ -1,5 +1,5 @@ #ifndef ADC_H -#define ADC_H +#define ADC_H #include diff --git a/drivers/include/diskio.h b/drivers/include/diskio.h index 2dc672dfe2..0ed8b2b914 100644 --- a/drivers/include/diskio.h +++ b/drivers/include/diskio.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 diff --git a/drivers/include/flashrom.h b/drivers/include/flashrom.h index c4fafc9e78..dd798423de 100644 --- a/drivers/include/flashrom.h +++ b/drivers/include/flashrom.h @@ -1,5 +1,5 @@ #ifndef FLASHROM_H -#define FLASHROM_H +#define FLASHROM_H #include #include diff --git a/drivers/include/ltc4150.h b/drivers/include/ltc4150.h index e94e9d0059..38fc47d2b8 100644 --- a/drivers/include/ltc4150.h +++ b/drivers/include/ltc4150.h @@ -1,5 +1,5 @@ #ifndef __LTC4150_H -#define __LTC4150_H +#define __LTC4150_H #include diff --git a/drivers/include/ltc4150_arch.h b/drivers/include/ltc4150_arch.h index 90fe5de20e..89738fddae 100644 --- a/drivers/include/ltc4150_arch.h +++ b/drivers/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); diff --git a/drivers/include/rtc.h b/drivers/include/rtc.h index e1ade0c791..c6038d2c12 100644 --- a/drivers/include/rtc.h +++ b/drivers/include/rtc.h @@ -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; diff --git a/drivers/include/sht11.h b/drivers/include/sht11.h index cb615f7848..6e93d67995 100644 --- a/drivers/include/sht11.h +++ b/drivers/include/sht11.h @@ -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 diff --git a/drivers/ltc4150/ltc4150.c b/drivers/ltc4150/ltc4150.c index 2175c37b08..5562317687 100644 --- a/drivers/ltc4150/ltc4150.c +++ b/drivers/ltc4150/ltc4150.c @@ -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; diff --git a/drivers/sht11/sht11.c b/drivers/sht11/sht11.c index 872888a067..10914affa2 100644 --- a/drivers/sht11/sht11.c +++ b/drivers/sht11/sht11.c @@ -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; } /** @} */