nuttx/include/nuttx/wireless/cc1101.h
anjiahao d1d46335df Replace nxsem API when used as a lock with nxmutex API
Signed-off-by: anjiahao <anjiahao@xiaomi.com>
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2022-10-17 15:59:46 +09:00

624 lines
21 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/****************************************************************************
* include/nuttx/wireless/cc1101.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_WIRELESS_CC1101_H
#define __INCLUDE_NUTTX_WIRELESS_CC1101_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <poll.h>
#include <nuttx/wqueue.h>
#include <nuttx/mutex.h>
#include <nuttx/semaphore.h>
#include <nuttx/spi/spi.h>
/****************************************************************************
* Pre-Processor Declarations
****************************************************************************/
/* Present maximum packet length */
#define CC1101_FIFO_SIZE 64
#define CC1101_PACKET_MAXTOTALLEN 63
#define CC1101_PACKET_MAXDATALEN 61
/* General Purpose, Test Output Pin Options */
/* CC1101 General Purpose Pins */
#define CC1101_PIN_GDO0 2
#define CC1101_PIN_GDO1 1
#define CC1101_PIN_GDO2 0
/* Associated to the RX FIFO: Asserts when RX FIFO is filled at or above
* the RX FIFO threshold. De-asserts when RX FIFO is drained below the
* same threshold.
*/
#define CC1101_GDO_RXFIFO_THR 0x00
/* Associated to the RX FIFO: Asserts when RX FIFO is filled at or above
* the RX FIFO threshold or the end of packet is reached. De-asserts when
* the RX FIFO is empty.
*/
#define CC1101_GDO_RXFIFO_THREND 0x01
/* Associated to the TX FIFO: Asserts when the TX FIFO is filled at or
* above the TX FIFO threshold. De-asserts when the TX FIFO is below the
* same threshold.
*/
#define CC1101_GDO_TXFIFO_THR 0x02
/* Associated to the TX FIFO: Asserts when TX FIFO is full. De-asserts
* when the TX FIFO is drained below theTX FIFO threshold.
*/
#define CC1101_GDO_TXFIFO_FULL 0x03
/* Asserts when the RX FIFO has overflowed. De-asserts when the FIFO has
* been flushed.
*/
#define CC1101_GDO_RXFIFO_OVR 0x04
/* Asserts when the TX FIFO has underflowed. De-asserts when the FIFO is
* flushed.
*/
#define CC1101_GDO_TXFIFO_UNR 0x05
/* Asserts when sync word has been sent / received, and de-asserts at the
* end of the packet. In RX, the pin will de-assert when the optional
* address check fails or the RX FIFO overflows. In TX the pin will
* de-assert if the TX FIFO underflows.
*/
#define CC1101_GDO_SYNC 0x06
/* Asserts when a packet has been received with CRC OK. De-asserts when
* the first byte is read from the RX FIFO.
*/
#define CC1101_GDO_PKTRCV_CRCOK 0x07
/* Preamble Quality Reached. Asserts when the PQI is above the programmed
* PQT value.
*/
#define CC1101_GDO_PREAMBLE 0x08
/* Clear channel assessment. High when RSSI level is below threshold
* (dependent on the current CCA_MODE setting).
*/
#define CC1101_GDO_CHCLEAR 0x09
/* Lock detector output. The PLL is in lock if the lock detector output
* has a positive transition or is constantly logic high. To check for
* PLL lock the lock detector output should be used as an interrupt for
* the MCU.
*/
#define CC1101_GDO_LOCK 0x0A
/* Serial Clock. Synchronous to the data in synchronous serial mode.
* In RX mode, data is set up on the falling edge by CC1101 when GDOx_INV=0.
* In TX mode, data is sampled by CC1101 on the rising edge of the serial
* clock when GDOx_INV=0.
*/
#define CC1101_GDO_SSCLK 0x0B
/* Serial Synchronous Data Output. Used for synchronous serial mode. */
#define CC1101_GDO_SSDO 0x0C
/* Serial Data Output. Used for asynchronous serial mode. */
#define CC1101_GDO_ASDO 0x0D
/* Carrier sense. High if RSSI level is above threshold. */
#define CC1101_GDO_CARRIER 0x0E
/* CRC_OK. The last CRC comparison matched. Cleared when entering or
* restarting RX mode.
*/
#define CC1101_GDO_CRCOK 0x0F
/* RX_HARD_DATA[1]. Can be used together with RX_SYMBOL_TICK for
* alternative serial RX output.
*/
#define CC1101_GDO_RXOUT1 0x16
/* RX_HARD_DATA[0]. Can be used together with RX_SYMBOL_TICK for
* alternative serial RX output.
*/
#define CC1101_GDO_RXOUT0 0x17
/* PA_PD. Note: PA_PD will have the same signal level in SLEEP and TX
* states. To control an external PA or RX/TX switch in applications
* where the SLEEP state is used it is recommended to use GDOx_CFGx=0x2F
* instead.
*/
#define CC1101_GDO_PA_PD 0x1b
/* LNA_PD. Note: LNA_PD will have the same signal level in SLEEP and RX
* states. To control an external LNA or RX/TX switch in applications
* where the SLEEP state is used it is recommended to use GDOx_CFGx=0x2F
* instead.
*/
#define CC1101_GDO_LNA_PD 0x1c
/* RX_SYMBOL_TICK. Can be used together with RX_HARD_DATA for alternative
* serial RX output.
*/
#define CC1101_GDO_RXSYMTICK 0x1d
#define CC1101_GDO_WOR_EVNT0 0x24
#define CC1101_GDO_WOR_EVNT1 0x25
#define CC1101_GDO_CLK32K 0x27
#define CC1101_GDO_CHIP_RDYn 0x29
#define CC1101_GDO_XOSC_STABLE 0x2B
/* GDO0_Z_EN_N. When this output is 0, GDO0 is configured as input
* (for serial TX data).
*/
#define CC1101_GDO_GDO0_Z_EN_N 0x2D
/* High impedance (3-state). */
#define CC1101_GDO_HIZ 0x2e
/* HW to 0 (HW1 achieved by setting GDOx_INV=1). Can be used to control
* an external LNA/PA or RX/TX switch.
*/
#define CC1101_GDO_HW 0x2f
/* There are 3 GDO pins, but only one CLK_XOSC/n can be selected as an
* output at any time. If CLK_XOSC/n is to be monitored on one of the
* GDO pins, the other two GDO pins must be configured to values less
* than 0x30. The GDO0 default value is CLK_XOSC/192. To optimize RF
* performance, these signals should not be used while the radio is
* in RX or TX mode.
*/
#define CC1101_GDO_CLK_XOSC1 0x30
#define CC1101_GDO_CLK_XOSC1_5 0x31
#define CC1101_GDO_CLK_XOSC2 0x32
#define CC1101_GDO_CLK_XOSC3 0x33
#define CC1101_GDO_CLK_XOSC4 0x34
#define CC1101_GDO_CLK_XOSC6 0x35
#define CC1101_GDO_CLK_XOSC8 0x36
#define CC1101_GDO_CLK_XOSC12 0x37
#define CC1101_GDO_CLK_XOSC16 0x38
#define CC1101_GDO_CLK_XOSC24 0x39
#define CC1101_GDO_CLK_XOSC32 0x3a
#define CC1101_GDO_CLK_XOSC48 0x3b
#define CC1101_GDO_CLK_XOSC64 0x3c
#define CC1101_GDO_CLK_XOSC96 0x3d
#define CC1101_GDO_CLK_XOSC128 0x3e
#define CC1101_GDO_CLK_XOSC192 0x3f
/****************************************************************************
* Public Data Types
****************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
# define EXTERN extern "C"
extern "C"
{
#else
# define EXTERN extern
#endif
typedef CODE int (*wait_cc1101_ready)(FAR struct cc1101_dev_s *dev,
uint32_t);
struct cc1101_dev_s;
struct cc1101_ops_s
{
CODE void (*wait)(FAR struct cc1101_dev_s *dev, uint32_t);
CODE void (*irq)(FAR struct cc1101_dev_s *dev, bool enable);
CODE void (*pwr)(FAR struct cc1101_dev_s *dev, bool enable);
};
enum cc1101_status
{
CC1101_INIT,
CC1101_IDLE,
CC1101_SEND,
CC1101_RECV,
CC1101_SLEEP,
CC1101_SXOFF
};
struct cc1101_dev_s
{
const struct c1101_rfsettings_s *rfsettings;
struct spi_dev_s *spi;
struct cc1101_ops_s ops;
enum cc1101_status status;
uint8_t flags;
uint8_t channel;
uint8_t power;
uint32_t dev_id; /* SPI device Id */
uint32_t gdo; /* GDO for interrupt */
uint32_t isr_pin; /* ISR Pin */
uint32_t miso_pin; /* MISO Pin */
struct work_s irq_work; /* Interrupt handling "bottom half" */
uint8_t nopens; /* The number of times the device has been opened */
mutex_t devlock; /* Ensures exclusive access to this structure */
uint8_t *rx_buffer; /* Circular RX buffer. [pipe# / pkt_len] [packet data...] */
uint16_t fifo_len; /* Number of bytes stored in fifo */
uint16_t nxt_read; /* Next read index */
uint16_t nxt_write; /* Next write index */
mutex_t lock_rx_buffer; /* Protect access to rx fifo */
sem_t sem_rx; /* Wait for availability of received data */
sem_t sem_tx; /* Wait for availability of send data */
FAR struct pollfd *pfd; /* Polled file descr (or NULL if any) */
};
/* The RF Settings includes only those fields required to configure
* the RF radio. Other configuration fields depended on this driver
* are configured by the cc1101_init().
*
* REVISIT: Upper case field names violates the NuttX coding standard.
*/
struct c1101_rfsettings_s
{
uint8_t FIFOTHR; /* FIFOTHR */
uint8_t SYNC1; /* SYNC1 */
uint8_t SYNC0; /* SYNC0 */
uint8_t PKTLEN; /* PKTLEN */
uint8_t PKTCTRL0; /* Packet Automation Control */
uint8_t PKTCTRL1; /* Packet Automation Control */
uint8_t ADDR; /* ADDR */
uint8_t CHANNR; /* CHANNR */
uint8_t FSCTRL1; /* Frequency synthesizer control. */
uint8_t FSCTRL0; /* Frequency synthesizer control. */
uint8_t FREQ2; /* Frequency control word, high byte. */
uint8_t FREQ1; /* Frequency control word, middle byte. */
uint8_t FREQ0; /* Frequency control word, low byte. */
uint8_t MDMCFG4; /* Modem configuration. */
uint8_t MDMCFG3; /* Modem configuration. */
uint8_t MDMCFG2; /* Modem configuration. */
uint8_t MDMCFG1; /* Modem configuration. */
uint8_t MDMCFG0; /* Modem configuration. */
uint8_t DEVIATN; /* Modem deviation setting (when FSK modulation is enabled). */
/* GAP */
uint8_t FOCCFG; /* Frequency Offset Compensation Configuration. */
uint8_t BSCFG; /* Bit synchronization Configuration. */
uint8_t AGCCTRL2; /* AGC control. */
uint8_t AGCCTRL1; /* AGC control. */
uint8_t AGCCTRL0; /* AGC control. */
/* GAP */
uint8_t FREND1; /* Front end RX configuration. */
uint8_t FREND0; /* Front end RX configuration. */
uint8_t FSCAL3; /* Frequency synthesizer calibration. */
uint8_t FSCAL2; /* Frequency synthesizer calibration. */
uint8_t FSCAL1; /* Frequency synthesizer calibration. */
uint8_t FSCAL0; /* Frequency synthesizer calibration. */
/* REGULATORY LIMITS */
uint8_t CHMIN; /* Channel Range definition MIN .. */
uint8_t CHMAX; /* .. and MAX */
uint8_t PAMAX; /* at given maximum output power */
/* Power Table, for ramp-up/down and ASK modulation defined for
* output power values as:
* PA = {-30, -20, -15, -10, -5, 0, 5, 10} [dBm]
*/
uint8_t PA[8];
};
/****************************************************************************
* RF Configuration Database
****************************************************************************/
/* TODO Recalculate ERP in maximum power level */
/* 868 MHz, GFSK, 100 kbps, ISM Region 1 (Europe only)
*
* ISM Region 1 (Europe) only, Band 868870 MHz
*
* Frequency bands for non-specific short range devices in Europe:
*
* Frequency ERP Duty Cycle Bandwidth Remarks
* 868 868.6 MHz +14 dBm < 1% No limits
* 868.7 869.2 MHz +14 dBm < 0.1% No limits
* 869.3 869.4 MHz +10 dBm No limits < 25 kHz Appropriate access
* protocol required 869.4 869.65 MHz +27 dBm < 10% < 25 kHz
* Channels may be combined to one high speed channel 869.7 -870 MHz +7
* dBm No limits No limits
*
* Frequency Band For License-Free Specific Applications in Europe
*
* Frequency Application ERP Duty Cycle Bandwidth
* 868.6 868.7 MHz Alarms +10 dBm < 0.1% 25 kHz(1)
* 869.2 869.25 MHz Social Alarms +10 dBm < 0.1% 25 kHz
* 869.25 869.3 MHz Alarms +10 dBm < 0.1% 25 kHz
* 869.65 -869.7 MHz Alarms +14 dBm < 10% 25 kHz
* 863 865 MHz Radio Microphones +10 dBm No limits 200 kHz
* 863 -865 MHz Wireless Audio Applications +10 dBm No limits 300 kHz
*
* Duty Cycle Limit Total On Time Maximum On Time of Minimum
* Off Time of Within One Hour One Transmission Two Transmission <
* 0.1% 3.6 seconds 0.72 seconds 0.72 seconds < 1% 36
* seconds 3.6 seconds 1.8 seconds < 10% 360
* seconds 36 seconds 3.6 seconds
*
* Reference: TI Application Report: swra048.pdf, May 2005
* ISM-Band and Short Range Device Regulatory Compliance Overview
*/
EXTERN const struct c1101_rfsettings_s
cc1101_rfsettings_ISM1_868MHzGFSK100kbps;
/* 905 MHz, GFSK, 250 kbps, ISM Region 2 (America only)
*
* ISM Region 2 (America) only, Band 902928 MHz
*
* Cordless phones 1 W
* Microwave ovens 750 W
* Industrial heaters 100 kW
* Military radar 1000 kW
*/
EXTERN const struct c1101_rfsettings_s
cc1101_rfsettings_ISM2_905MHzGFSK250kbps;
EXTERN const struct c1101_rfsettings_s
cc1101_rfsettings_ISM2_433MHzMSK500kbps;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
FAR int cc1101_init2(FAR struct cc1101_dev_s *dev);
/****************************************************************************
* Initialize Chipcon CC1101 Chip.
* After initialization CC1101 is ready to listen, receive and transmit
* messages on the default channel 0 at given RF configuration.
*
* Input Parameters:
* spi SPI Device Structure
* isrpin Select the CC1101_PIN_GDOx used to signal interrupts
* rfsettings Pointer to default RF Settings loaded at boot time.
*
* Returned Value:
* Pointer to newly allocated CC1101 structure or NULL on error with errno
* set.
*
* Possible errno as set by this function on error:
* - ENODEV: When device addressed is not compatible or it is not a CC1101
* - EFAULT: When there is no device
* - ENOMEM: Out of kernel memory to allocate the device
* - EBUSY: When device is already addressed by other device driver (not yet
* supported by low-level driver)
*
****************************************************************************/
struct cc1101_dev_s *cc1101_init(
FAR struct spi_dev_s *spi, uint32_t isr_pin, uint32_t miso_pin,
FAR const struct c1101_rfsettings_s *rfsettings, wait_cc1101_ready wait);
/****************************************************************************
** Deinitialize Chipcon CC1101 Chip
*
* Input Parameters:
* dev Device to CC1101 device structure, as returned by the cc1101_init()
*
* Returned Value:
* OK On success
*
****************************************************************************/
int cc1101_deinit(FAR struct cc1101_dev_s *dev);
/****************************************************************************
* Power up device, start conversion. Returns zero on success.
****************************************************************************/
int cc1101_powerup(FAR struct cc1101_dev_s *dev);
/****************************************************************************
* Power down device, stop conversion. Returns zero on success.
****************************************************************************/
int cc1101_powerdown(FAR struct cc1101_dev_s *dev);
/****************************************************************************
* Set Multi Purpose Output Function. Returns zero on success.
****************************************************************************/
int cc1101_setgdo(FAR struct cc1101_dev_s *dev,
uint8_t pin,
uint8_t function);
/****************************************************************************
* Set RF settings. Use one from the database above.
****************************************************************************/
int cc1101_setrf(FAR struct cc1101_dev_s *dev,
FAR const struct c1101_rfsettings_s *settings);
/****************************************************************************
* Set Channel.
* Note that regulatory check is made and sending may be prohibited.
*
* Returned Value:
* 0 On success, sending and receiving is allowed.
* 1 Only receive mode is allowed.
* <0 On error.
*
****************************************************************************/
int cc1101_setchannel(FAR struct cc1101_dev_s *dev, uint8_t channel);
/****************************************************************************
* Set Output Power
*
* Input Parameters:
* power Value from 0 - 8, where 0 means power off, and values
* from 1 .. 8 denote the following output power in dBm:
* {-30, -20, -15, -10, -5, 0, 5, 10} [dBm]
*
* If power is above the regulatory limit (defined by the RF settings)
* it is limited.
*
* Returned Value:
* Actual output power in range from 0..8.
*
****************************************************************************/
uint8_t cc1101_setpower(FAR struct cc1101_dev_s *dev, uint8_t power);
/****************************************************************************
* Convert RSSI as obtained from CC1101 to [dBm]
*
****************************************************************************/
int cc1101_calc_rssi_dbm(int rssi);
/****************************************************************************
* Enter receive mode and wait for a packet.
* If transmission is in progress, receive mode is entered upon its
* completion. As long cc1101_idle() is not called, each transmission
* returns to receive mode.
*
* Input Parameters:
* dev Device to CC1101 structure
*
* Returned Value:
* Zero on success.
*
****************************************************************************/
int cc1101_receive(FAR struct cc1101_dev_s *dev);
/****************************************************************************
* Read received packet
*
* If size of buffer is too small then the remaining part of data can
* be discarded by the driver.
*
* Packet contains raw data, including the two bytes:
* - RSSI and
* - LQI
* appended at the end of the message.
*
* To inquery about the data pending size you the following:
* - pass buf=NULL and size > 0, returns pending data packet size
* - pass buf=NULL and size = 0, returns maximum data packet size
*
* NOTE: messages length are typically defined by the MAC, transmit/
* receive windows at some rate.
*
****************************************************************************/
int cc1101_read(FAR struct cc1101_dev_s *dev, FAR uint8_t *buf, size_t size);
/****************************************************************************
* Write data to be send, using the cc1101_send()
*
* Input Parameters:
* dev Device to CC1101 structure
* buf Pointer to data.
* size Size must be within limits, otherwise data is truncated.
* Present driver limitation supports a single cc1101_write()
* prioer cc1101_send() is called.
*
****************************************************************************/
int cc1101_write(FAR struct cc1101_dev_s *dev, FAR const uint8_t *buf,
size_t size);
/****************************************************************************
* Send data previously written using cc1101_write()
*
* Input Parameters:
* dev Device to CC1101 structure
*
* Returned Value:
* Zero on success.
*
****************************************************************************/
int cc1101_send(FAR struct cc1101_dev_s *dev);
/****************************************************************************
* Enter idle state (after reception and transmission completes).
*
* Returned Value:
* Zero on success.
*
****************************************************************************/
int cc1101_idle(FAR struct cc1101_dev_s *dev);
int cc1101_register(FAR const char *path, FAR struct cc1101_dev_s *dev);
void cc1101_isr_process(FAR void *arg);
int cc1101_isr(int irq, FAR void *context, FAR void *arg);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __INCLUDE_NUTTX_WIRELESS_CC1101_H */