Revert "cc2520: Rework reception logic"
This reverts commit bf77d902ac
.
The commit is reverted because it causes hangs in packet
reception. After transferring data a while, the chip stops
packet reception.
Change-Id: Icb94e978e3ba526314afd5e80f35c877febe8740
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
7795ec4435
commit
bf2c827dcf
1 changed files with 97 additions and 90 deletions
|
@ -54,12 +54,13 @@
|
|||
#include "cc2520.h"
|
||||
#include "cc2520_arch.h"
|
||||
|
||||
#define CC2520_CONF_AUTOACK 1
|
||||
#ifndef CC2520_CONF_AUTOACK
|
||||
#define CC2520_CONF_AUTOACK 0
|
||||
#endif /* CC2520_CONF_AUTOACK */
|
||||
|
||||
#define WITH_SEND_CCA 1
|
||||
|
||||
#define FOOTER_LEN 2
|
||||
/* Len + FCF + SEQ + FCS + PAN ID */
|
||||
#define MIN_LENGTH_BEFORE_ACCEPT 10
|
||||
|
||||
#define AUTOCRC (1 << 6)
|
||||
#define AUTOACK (1 << 5)
|
||||
|
@ -252,8 +253,6 @@ static inline void print_exceptions_1(void)
|
|||
DBG("DPU_DONE_H");
|
||||
}
|
||||
DBG("\n");
|
||||
|
||||
setreg(CC2520_EXCFLAG1, 0);
|
||||
}
|
||||
|
||||
static inline void print_errors(void)
|
||||
|
@ -283,7 +282,14 @@ static inline void print_errors(void)
|
|||
DBG("RFBUFMOV_TIMEOUT");
|
||||
}
|
||||
DBG("\n");
|
||||
}
|
||||
|
||||
static void clear_exceptions(void)
|
||||
{
|
||||
DBG("Clearing up exceptions & errors\n");
|
||||
|
||||
setreg(CC2520_EXCFLAG0, 0);
|
||||
setreg(CC2520_EXCFLAG1, 0);
|
||||
setreg(CC2520_EXCFLAG2, 0);
|
||||
}
|
||||
|
||||
|
@ -304,6 +310,7 @@ static void cc2520_print_gpio_config(void)
|
|||
#define print_exceptions_0()
|
||||
#define print_exceptions_1()
|
||||
#define print_errors()
|
||||
#define clear_exceptions()
|
||||
#define cc2520_print_gpio_config()
|
||||
#endif
|
||||
|
||||
|
@ -482,6 +489,7 @@ static radio_result_t cc2520_set_rx_mode(radio_value_t value)
|
|||
}
|
||||
old_value = value;
|
||||
|
||||
#if 1
|
||||
if (receive_on) {
|
||||
cc2520_strobe(CC2520_INS_SRXON);
|
||||
|
||||
|
@ -490,6 +498,7 @@ static radio_result_t cc2520_set_rx_mode(radio_value_t value)
|
|||
return RADIO_RESULT_ERROR;
|
||||
}
|
||||
}
|
||||
#endif /* 1/0 */
|
||||
|
||||
return RADIO_RESULT_OK;
|
||||
}
|
||||
|
@ -657,7 +666,7 @@ static int cc2520_transmit(struct net_buf *buf, unsigned short payload_len)
|
|||
*/
|
||||
BUSYWAIT_UNTIL(!(status() & BIT(CC2520_TX_ACTIVE)), WAIT_500ms);
|
||||
|
||||
DBG("Transmitted!\n");
|
||||
DBG("status 0x%x\n", status());
|
||||
|
||||
if (!receive_on) {
|
||||
/* We need to explicitly turn off the radio,
|
||||
|
@ -701,12 +710,18 @@ static int cc2520_prepare(const void *payload, unsigned short payload_len)
|
|||
|
||||
DBG("cc2520: sending %d bytes\n", payload_len);
|
||||
|
||||
clear_exceptions();
|
||||
|
||||
/* Write packet to TX FIFO. */
|
||||
strobe(CC2520_INS_SFLUSHTX);
|
||||
|
||||
total_len = payload_len + FOOTER_LEN;
|
||||
DBG("TX FIFO has %u bytes\n", getreg(CC2520_TXFIFOCNT));
|
||||
cc2520_write_fifo_buf(&total_len, 1);
|
||||
cc2520_write_fifo_buf(buf, payload_len);
|
||||
DBG("TX FIFO has %u bytes\n", getreg(CC2520_TXFIFOCNT));
|
||||
|
||||
print_errors();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -810,79 +825,65 @@ bool cc2520_set_pan_addr(unsigned pan, unsigned addr,
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline uint8_t rxcount(void)
|
||||
{
|
||||
return getreg(CC2520_RXFIFOCNT);
|
||||
}
|
||||
|
||||
static int cc2520_read(void *buf, unsigned short bufsize)
|
||||
{
|
||||
struct cc2520_config *info = cc2520_sgl_dev->config->config_info;
|
||||
uint8_t footer[2];
|
||||
uint8_t pkt_len;
|
||||
uint8_t len;
|
||||
uint8_t cnt;
|
||||
|
||||
if (!init_ok) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
cnt = rxcount();
|
||||
if (cnt < MIN_LENGTH_BEFORE_ACCEPT) {
|
||||
if (!cc2520_pending_packet()) {
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
getrxbyte(&pkt_len);
|
||||
len = pkt_len - FOOTER_LEN;
|
||||
|
||||
while (1) {
|
||||
if (cnt > len) {
|
||||
cnt = len;
|
||||
}
|
||||
|
||||
getrxdata(buf, cnt);
|
||||
|
||||
buf += cnt;
|
||||
len -= cnt;
|
||||
|
||||
if (len <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
while (!(cnt = rxcount())) {
|
||||
};
|
||||
}
|
||||
|
||||
while (rxcount() < FOOTER_LEN) {
|
||||
};
|
||||
|
||||
getrxdata(footer, FOOTER_LEN);
|
||||
if (footer[1] & FOOTER1_CRC_OK) {
|
||||
cc2520_last_rssi = footer[0];
|
||||
cc2520_last_correlation = footer[1] & FOOTER1_CORRELATION;
|
||||
} else {
|
||||
DBG("RX: Bad CRC\n");
|
||||
print_exceptions_0();
|
||||
print_exceptions_1();
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cc2520_pending_packet()) {
|
||||
/* Clean up in case of FIFO overflow!
|
||||
* This should not happen unless we were too slow to read
|
||||
* the previous packet. This is signaled by:
|
||||
* FIFOP = 1 and FIFO = 0
|
||||
*/
|
||||
if (!CC2520_FIFO_IS_1) {
|
||||
DBG("RX: Overflow\n");
|
||||
print_exceptions_0();
|
||||
flushrx();
|
||||
}
|
||||
}
|
||||
|
||||
cc2520_packets_read++;
|
||||
|
||||
return pkt_len - FOOTER_LEN;
|
||||
getrxbyte(&len);
|
||||
|
||||
DBG("%s: Incoming packet length: %d\n", __func__, len);
|
||||
|
||||
if ((len - FOOTER_LEN > bufsize) ||
|
||||
(len <= FOOTER_LEN)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
getrxdata(buf, len - FOOTER_LEN);
|
||||
getrxdata(footer, FOOTER_LEN);
|
||||
|
||||
if (footer[1] & FOOTER1_CRC_OK) {
|
||||
cc2520_last_rssi = footer[0];
|
||||
cc2520_last_correlation = footer[1] & FOOTER1_CORRELATION;
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (cc2520_pending_packet()) {
|
||||
if (!CC2520_FIFO_IS_1) {
|
||||
/* Clean up in case of FIFO overflow! This happens
|
||||
* for every full length frame and is signaled by
|
||||
* FIFOP = 1 and FIFO = 0
|
||||
*/
|
||||
flushrx();
|
||||
} else {
|
||||
/* Another packet might be waiting
|
||||
* Let's unlock reading_packet_fiber()
|
||||
*/
|
||||
nano_fiber_sem_give(&info->read_lock);
|
||||
}
|
||||
}
|
||||
|
||||
return len - FOOTER_LEN;
|
||||
|
||||
error:
|
||||
print_exceptions_0();
|
||||
print_exceptions_1();
|
||||
print_errors();
|
||||
|
||||
flushrx();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void read_packet(void)
|
||||
|
@ -890,34 +891,35 @@ static void read_packet(void)
|
|||
struct net_buf *buf;
|
||||
int len;
|
||||
|
||||
do {
|
||||
buf = l2_buf_get_reserve(0);
|
||||
if (!buf) {
|
||||
DBG("%s: Could not allocate buffer\n", __func__);
|
||||
break;
|
||||
}
|
||||
buf = l2_buf_get_reserve(0);
|
||||
if (!buf) {
|
||||
DBG("%s: Could not allocate buffer\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
packetbuf_set_attr(buf, PACKETBUF_ATTR_TIMESTAMP,
|
||||
last_packet_timestamp);
|
||||
packetbuf_set_attr(buf, PACKETBUF_ATTR_TIMESTAMP,
|
||||
last_packet_timestamp);
|
||||
|
||||
len = cc2520_read(packetbuf_dataptr(buf), PACKETBUF_SIZE);
|
||||
if (len < 0) {
|
||||
l2_buf_unref(buf);
|
||||
break;
|
||||
}
|
||||
len = cc2520_read(packetbuf_dataptr(buf), PACKETBUF_SIZE);
|
||||
if (len < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
packetbuf_set_attr(buf, PACKETBUF_ATTR_RSSI, cc2520_last_rssi);
|
||||
packetbuf_set_attr(buf, PACKETBUF_ATTR_LINK_QUALITY,
|
||||
cc2520_last_correlation);
|
||||
packetbuf_set_datalen(buf, len);
|
||||
packetbuf_set_attr(buf, PACKETBUF_ATTR_RSSI, cc2520_last_rssi);
|
||||
packetbuf_set_attr(buf, PACKETBUF_ATTR_LINK_QUALITY,
|
||||
cc2520_last_correlation);
|
||||
packetbuf_set_datalen(buf, len);
|
||||
|
||||
if (net_driver_15_4_recv_from_hw(buf) < 0) {
|
||||
l2_buf_unref(buf);
|
||||
}
|
||||
DBG("%s: received %d bytes\n", __func__, len);
|
||||
|
||||
last_packet_timestamp = cc2520_sfd_start_time;
|
||||
cc2520_packets_seen++;
|
||||
} while (len > 0);
|
||||
if (net_driver_15_4_recv_from_hw(buf) < 0) {
|
||||
DBG("%s: rdc input failed, packet discarded\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
return;
|
||||
out:
|
||||
l2_buf_unref(buf);
|
||||
}
|
||||
|
||||
/* Reading incoming packet, so through SPI, cannot be done directly
|
||||
|
@ -937,6 +939,9 @@ static void reading_packet_fiber(int unused1, int unused2)
|
|||
read_packet();
|
||||
cc2520_radio_unlock();
|
||||
|
||||
last_packet_timestamp = cc2520_sfd_start_time;
|
||||
cc2520_packets_seen++;
|
||||
|
||||
net_analyze_stack("CC2520 Rx Fiber stack", cc2520_read_stack,
|
||||
CC2520_READING_STACK_SIZE);
|
||||
}
|
||||
|
@ -946,6 +951,8 @@ static void cc2520_gpio_int_handler(struct device *port, uint32_t pin)
|
|||
{
|
||||
struct cc2520_config *info = cc2520_sgl_dev->config->config_info;
|
||||
|
||||
DBG("%s: RX interrupt in pin %lu\n", __func__, pin);
|
||||
|
||||
/* In order to make this driver available for 2+ instances
|
||||
* it would require this handler to get access to the concerned
|
||||
* instance
|
||||
|
@ -1140,7 +1147,7 @@ static void cc2520_configure(struct device *dev)
|
|||
/* Set auto CRC on frame. */
|
||||
#if CC2520_CONF_AUTOACK
|
||||
setreg(CC2520_FRMCTRL0, AUTOCRC | AUTOACK);
|
||||
setreg(CC2520_FRMFILT0, FRAME_MAX_VERSION | FRAME_FILTER_ENABLE);
|
||||
setreg(CC2520_FRMFILT0, FRAME_MAX_VERSION|FRAME_FILTER_ENABLE);
|
||||
#else
|
||||
/* setreg(CC2520_FRMCTRL0, 0x60); */
|
||||
setreg(CC2520_FRMCTRL0, AUTOCRC);
|
||||
|
@ -1150,7 +1157,7 @@ static void cc2520_configure(struct device *dev)
|
|||
/* SET_RXENMASK_ON_TX */
|
||||
setreg(CC2520_FRMCTRL1, 1);
|
||||
/* Set FIFOP threshold to maximum .*/
|
||||
setreg(CC2520_FIFOPCTRL, FIFOP_THR(MIN_LENGTH_BEFORE_ACCEPT));
|
||||
setreg(CC2520_FIFOPCTRL, FIFOP_THR(0x7F));
|
||||
|
||||
if (!cc2520_set_pan_addr(0xffff, 0x0000, NULL)) {
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue