From b3e788e11bbadae988ddf481ab45458051f20c65 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Aug 2017 09:55:30 -0600 Subject: [PATCH] Spirit: Fix typos in conditional compilation. Add debug output. Remove extra clear of pending interrupts, could cause missing interrupts. Add spirit_reg_modify() which is not currently used. --- .../wireless/spirit/drivers/spirit_netdev.c | 25 ++++--- drivers/wireless/spirit/include/spirit_spi.h | 23 ++++++ drivers/wireless/spirit/lib/spirit_irq.c | 3 +- drivers/wireless/spirit/lib/spirit_spi.c | 74 +++++++++++++++++++ 4 files changed, 115 insertions(+), 10 deletions(-) diff --git a/drivers/wireless/spirit/drivers/spirit_netdev.c b/drivers/wireless/spirit/drivers/spirit_netdev.c index 0d8f947ff7..f0b7674df6 100644 --- a/drivers/wireless/spirit/drivers/spirit_netdev.c +++ b/drivers/wireless/spirit/drivers/spirit_netdev.c @@ -271,11 +271,11 @@ static const struct spirit_csma_init_s g_csma_init = 8 /* BU prescaler */ }; -#ifdef CONFIG_SPIRIT_MULTICAST +#ifdef CONFIG_SPIRIT_PROMISICUOUS static struct pktbasic_addr_s g_addrinit = { S_DISABLE, /* Disable filtering on node address */ - SPIRIT_NODE_ADDR /* Note address (Temporary, until assigned) */ + SPIRIT_NODE_ADDR /* Node address (Temporary, until assigned) */ S_DISABLE, /* Disable filtering on multicast address */ 0xee, /* Multicast address */ S_DISABLE, /* Disable filtering on broadcast address */ @@ -285,7 +285,7 @@ static struct pktbasic_addr_s g_addrinit = static struct pktbasic_addr_s g_addrinit = { S_ENABLE, /* Enable filtering on node address */ - SPIRIT_NODE_ADDR, /* Note address (Temporary, until assigned) */ + SPIRIT_NODE_ADDR, /* Node address (Temporary, until assigned) */ #ifdef CONFIG_SPIRIT_MULTICAST S_ENABLE, /* Enable filtering on multicast address */ #else @@ -523,7 +523,7 @@ static int spirit_transmit(FAR struct spirit_driver_s *priv) goto errout_with_iob; } -#ifndef CONFIG_SPIRIT_PROMISCOUS +#ifndef CONFIG_SPIRIT_PROMISICUOUS /* Set the destination address */ DEBUGASSERT(pktmeta->pm_dest.pa_addrlen == 1); @@ -839,11 +839,14 @@ static void spirit_interrupt_work(FAR void *arg) DEBUGASSERT(priv != NULL); spirit = &priv->spirit; - /* Get the interrupt source from radio */ + /* Get the set of pending ineterrupts from the radio. + * NOTE: The pending interrupts are cleared as a side-effect of reading + * the IRQ status register. + */ spirit_lock(priv); DEBUGVERIFY(spirit_irq_get_pending(spirit, &irqstatus)); - DEBUGVERIFY(spirit_irq_clr_pending(spirit)); + wlinfo("Pending: %08lx\n", *(FAR unsigned long *)&irqstatus); /* Process the Spirit1 interrupt */ /* First check for errors */ @@ -1040,8 +1043,12 @@ static void spirit_interrupt_work(FAR void *arg) /* IRQ_RX_DATA_DISC indicates that Rx data was discarded */ - if (irqstatus.IRQ_RX_DATA_DISC) + if (irqstatus.IRQ_RX_DATA_DISC != 0) { + wlinfo("Data discarded: Node addr=%02x RX dest addr=%02x\n", + spirit_pktcommon_get_nodeaddress(spirit), + spirit_pktcommon_get_rxdestaddr(spirit)); + DEBUGVERIFY(spirit_command(spirit, CMD_FLUSHRXFIFO)); priv->state = DRIVER_STATE_IDLE; NETDEV_RXDROPPED(&priv->radio.r_dev); @@ -1057,7 +1064,7 @@ static void spirit_interrupt_work(FAR void *arg) DEBUGVERIFY(spirit_command(spirit, CMD_RX)); - /* Wait for Spirit to enter the Tx state (or timeut) */ + /* Wait for Spirit to enter the Rx state (or timeut) */ DEBUGVERIFY(spirit_waitstatus(spirit, MC_STATE_RX, 1)); } @@ -1364,7 +1371,7 @@ static int spirit_ifup(FAR struct net_driver_s *dev) goto error_with_ifalmostup; } -#ifndef CONFIG_SPIRIT_PROMISCOUS +#ifndef CONFIG_SPIRIT_PROMISICUOUS /* Instantiate the assigned node address in harsware*/ DEBUGASSERT(dev->d_mac.sixlowpan.nv_addrlen == 1); diff --git a/drivers/wireless/spirit/include/spirit_spi.h b/drivers/wireless/spirit/include/spirit_spi.h index 1ec9731de2..7cc891d603 100644 --- a/drivers/wireless/spirit/include/spirit_spi.h +++ b/drivers/wireless/spirit/include/spirit_spi.h @@ -121,6 +121,29 @@ int spirit_reg_read(FAR struct spirit_library_s *spirit, uint8_t regaddr, int spirit_reg_write(FAR struct spirit_library_s *spirit, uint8_t regaddr, FAR const uint8_t *buffer, unsigned int buflen); +/****************************************************************************** + * Name: spirit_reg_modify + * + * Description: + * Perform atomic read/modify/write on a single SPIRIT1 register. This is + * atomic only in the sense that other accesses to the SPI bus are + * prohibited throughout the operation. + * + * Input parameters: + * spirit - Reference to an instance of the driver state stucture. + * regaddr - Base register's address to write + * clrbits - Bits to clear in the register + * setbits - Bits to set in the regiser + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. On success, spirit->state is updated. + * + ******************************************************************************/ + +int spirit_reg_modify(FAR struct spirit_library_s *spirit, uint8_t regaddr, + uint8_t setbits, uint8_t clrbits); + /****************************************************************************** * Name: spirit_command * diff --git a/drivers/wireless/spirit/lib/spirit_irq.c b/drivers/wireless/spirit/lib/spirit_irq.c index 1663790d83..56ebd07b29 100644 --- a/drivers/wireless/spirit/lib/spirit_irq.c +++ b/drivers/wireless/spirit/lib/spirit_irq.c @@ -219,7 +219,8 @@ int spirit_irt_get_mask(FAR struct spirit_library_s *spirit, * * Description: * Fills a pointer to a structure of struct spirit_irqset_s type with the - * content of the IRQ_STATUS registers. + * content of the IRQ_STATUS registers. NOTE: Status bits will be cleared + * after they are read. * * Input Parameters: * spirit - Reference to a Spirit library state structure instance diff --git a/drivers/wireless/spirit/lib/spirit_spi.c b/drivers/wireless/spirit/lib/spirit_spi.c index 1266492472..96b7d72c08 100644 --- a/drivers/wireless/spirit/lib/spirit_spi.c +++ b/drivers/wireless/spirit/lib/spirit_spi.c @@ -357,6 +357,80 @@ int spirit_reg_write(FAR struct spirit_library_s *spirit, uint8_t regaddr, return OK; } +/****************************************************************************** + * Name: spirit_reg_modify + * + * Description: + * Perform atomic read/modify/write on a single SPIRIT1 register. + * + * Input parameters: + * spirit - Reference to an instance of the driver state stucture. + * regaddr - Base register's address to write + * clrbits - Bits to clear in the register + * setbits - Bits to set in the regiser + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. On success, spirit->state is updated. + * + ******************************************************************************/ + +int spirit_reg_modify(FAR struct spirit_library_s *spirit, uint8_t regaddr, + uint8_t setbits, uint8_t clrbits) +{ + uint8_t header[2]; + uint8_t status[2]; + uint8_t regval; + + /* Setup the header byte to read the register */ + + header[0] = READ_HEADER; + header[1] = regaddr; + + /* Lock the SPI bus and select the Spirit device */ + + spirit_lock(spirit->spi); + SPI_SELECT(spirit->spi, SPIDEV_WIRELESS(0), true); + + /* Write the header bytes (ignoring the returned SPIRIT1 status bytes) */ + + SPI_SNDBLOCK(spirit->spi, header, 2); + + /* Read the register value */ + + regval = SPI_SEND(spirit->spi, 0xff); + spirit_regdebug("READ", header, ®val, 1); + + /* Modify the register value */ + + regval &= ~clrbits; + regval |= ~setbits; + + /* Setup the header byte for the write operation */ + + header[0] = WRITE_HEADER; + header[1] = regaddr; + spirit_regdebug("WRITE", header, ®val, 1); + + /* Write the header bytes and read the SPIRIT1 status bytes */ + + SPI_EXCHANGE(spirit->spi, header, status, 2); + + /* Update Spirit status. 16-bit status is returned MS bit first */ + + spirit->u.u16 = ((uint16_t)status[0] << 8) | (uint16_t)status[1]; + + /* Write the register value */ + + (void)SPI_SEND(spirit->spi, regval); + + /* Deselect the Spirit device and return the result */ + + SPI_SELECT(spirit->spi, SPIDEV_WIRELESS(0), false); + spirit_unlock(spirit->spi); + return OK; +} + /****************************************************************************** * Name: spirit_command *