Note:

We're currently migrating material in this wiki to the zephyrproject.org documentation site or to the new Zephyr GitHub wiki

TI CC2520

From Zephyr Project Wiki
Jump to: navigation, search

Introduction

CC2520 is a IEEE 802.15.4 PHY chip designed and manufactured by Texas Instruments.

CC2520 product page

As a PHY device, CC2520 does not provide the MAC layer for 802.15.4 and requires the OS to do so.

Zephyr provides an IEEE 802.15.4 Soft MAC layer which can properly drive CC2520.


Hardware setup

CC2520 is a GPIO and SPI driven chip. Where GPIOs are used to get interruptions, or reset/enable the chip, and SPI to command the chip: configure it, set its network addresses, transmit frames, receive frames...

CC2520 daughter board

The most common way to test CC2520 is through TI's official kit: CC2520 Evaluation Module Kit

To help wiring EMKs boards it is advised to use TI's EM adapter: EM adapter


Host board

Any Zephyr Supported Boards can be used to wire CC2520 as long as it exposes 4 wire SPI controller and enough GPIOs. Currently a minimum of 6 exposed GPIOs are needed.

Chosen host board should also have working GPIO and SPI drivers.


Wiring

If we consider using EM adapter board, one will notice the pin names as: RESET, GPIO 3, MISO, SCLK etc...

BEWARE: These are not all 1:1 with CC2520 pin outs.

Here is a correspondence table:

CC2520 Pin outs <-> EM adapter board
CC2520 pin EM adapter pin
AVDD_* VDD
AGND GND
VREG_EN GPIO A (GPIO 0 by default)
RESETn RESET
GPIO 0 (clock out) GPIO 4
GPIO 1 (fifo) RX
GPIO 2 (fifop) TX
GPIO 3 (cca) GPIO B (GPIO 2 by default)
GPIO 4 (sfd) GPIO 3
GPIO 5 (can be grounded) GPIO 5
SCLK SCLK
SO MISO
SI MOSI
CSn CS

Depending on the host board you are using, you may need to use pull-up resistors for the GPIOs.

EM adapter and the CC2520 EMK plugged in can be powered 2 ways:

  • 3.3 input on VDD, with one jumber set to VDD LP to EM
  • usb cable, with 2 jumbers set: VDD LP/From DC and VDD EM/From DC

See TI's reference manual on EM boosterpack adapter for more information


Software setup

There is one important file you will need to follow in Zephyr tree: File include/drivers/ieee802154/cc2520.h

There it is all about configuring the GPIOs depending on your host board.

You will have to implement cc2520_configure_gpios() which will return a table of struct cc2520_gpio_configuration of size CC2520_GPIO_IDX_MAX and strictly ordered as in enum cc2520_gpio_index.

cc2520_configure_gpios() will have the role to get the right gpio controller instance for each pin, configure the pin and fill in the result table for the corresponding index: the pin number and the gpio controller instance.

Pins have to follow this configuration:

  • GPIO_DIR_OUT for pins related to VREG_EN and RESET
  • GPIO_DIR_IN for pins related to FIFO and CCA
  • GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE | GPIO_INT_ACTIVE_HIGH | GPIO_INT_DEBOUNCE for pins related to SFD and FIFOP

(note that, depending on host gpio controller, it might be better to use GPIO_INT_LEVEL)


Use case: CC2520 on Arduino 101

Wiring

EM adapter pin Arduino 101
VDD 3.3
GND GND
MISO IO 12
MOSI IO 11
SCLK IO 13
CS IO 10 (Pull-down resistor needed)
GPIO A IO 8
RESET IO 7
RX IO 4 (Pull-up resistor needed)
TX IO 3 (Pull-up resistor needed)
GPIO B IO 2 (Pull-up resistor needed)
GPIO 3 IO 5 (Pull-up resistor needed)
GPIO 5 (optional) GND


Note that CS will require a pull-down resistor. This is due to the fact that CS will be emulated through a GPIO line as embedded DW SPI controller has issues with handling its CS line.

Values from 4.7k to 10k ohms seem to work.

Software setup

Here is a corresponding implementation for cc2520_configure_gpios():

#include <ieee802154/cc2520.h>
#include <gpio.h>

#define CC2520_GPIO_DEV_NAME CONFIG_GPIO_QMSI_0_NAME

#define CC2520_GPIO_VREG_EN	16  /* PIN 50, IO8 */
#define CC2520_GPIO_RESET	20  /* PIN 54, IO7 */
#define CC2520_GPIO_FIFO	19  /* PIN 53, IO4 */
#define CC2520_GPIO_CCA		18  /* PIN 52, IO2 */
#define CC2520_GPIO_SFD		15  /* PIN 49, IO5 */
#define CC2520_GPIO_FIFOP	17  /* PIN 51, IO3 */

static struct cc2520_gpio_configuration cc2520_gpios[CC2520_GPIO_IDX_MAX] = {
	{ .dev = NULL, .pin = CC2520_GPIO_VREG_EN, },
	{ .dev = NULL, .pin = CC2520_GPIO_RESET, },
	{ .dev = NULL, .pin = CC2520_GPIO_FIFO, },
	{ .dev = NULL, .pin = CC2520_GPIO_CCA, },
	{ .dev = NULL, .pin = CC2520_GPIO_SFD, },
	{ .dev = NULL, .pin = CC2520_GPIO_FIFOP, },
};

struct cc2520_gpio_configuration *cc2520_configure_gpios(void)
{
	struct device *gpio;
	int i;

	gpio = device_get_binding(CC2520_GPIO_DEV_NAME);
	if (!gpio) {
		return NULL;
	}

	for (i = 0; i < CC2520_GPIO_IDX_MAX; i++) {
		int flags;

		if (i >= 0 && i < CC2520_GPIO_IDX_FIFO) {
			flags = GPIO_DIR_OUT;
		} else if (i >= CC2520_GPIO_IDX_FIFO &&
			   i < CC2520_GPIO_IDX_SFD) {
			flags = GPIO_DIR_IN;
		} else {
			flags = (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
				 GPIO_INT_ACTIVE_HIGH | GPIO_INT_DEBOUNCE);
		}

		gpio_pin_configure(gpio, cc2520_gpios[i].pin, flags);
		cc2520_gpios[i].dev = gpio;
	}

	return cc2520_gpios;
}

And the necessary prj.conf content:

CONFIG_GPIO=y
CONFIG_SPI=y
CONFIG_SPI_0=n
CONFIG_SPI_1=y
CONFIG_SPI_CS_GPIO=y
CONFIG_SPI_1_CS_GPIO_PORT="GPIO_0"
CONFIG_SPI_1_CS_GPIO_PIN=0

CONFIG_TI_CC2520=y
CONFIG_TI_CC2520_AUTO_ACK=y
CONFIG_SYS_LOG_TI_CC2520_LEVEL=1
CONFIG_TI_CC2520_SPI_DRV_NAME="SPI_1"
CONFIG_TI_CC2520_SPI_FREQ=4
CONFIG_TI_CC2520_SPI_SLAVE=1


With all this, you should get ready to integrate Arduino 101 and CC2520EMK+EM apapter boards to a working setup with native net stack and it's IEEE 802.15.4 Soft MAC.


Console output (optional)

Just wire a USB FTDI adapter to relevant Arduino 101 pins: GND, RX (IO 0) and TX (IO 1).


Use case: CC2520 on NXP FRDM-K64F

Connecting TI CC2520 to NXP FRDM K64F board

Wiring

FRDM provides many gpios, but to keep it simple from software configuration point of view we will be using ones from 1 gpio controller. These will be the PTCx

Nothing prevents you for using other gpio pins, but then you will have to make your software setup aware of it (gpio controller, pins, and of course pinmuxing)

For a board layout, to help wiring up, please have a look at Layout page 17

EM adapter board <-> FRDM-K64F
EM adapter pin FRDM-K64F pin
VDD P3V3-4
GND GND-14
SCLK PTD1
CS PTD0
MISO PTD3
MOSI PTD2
GPIO A (CC2520 VREG_EN) PTC12
RESET (CC2520 RESET) PTC3
RX (CC2520 FIFO) PTC2
GPIO B (CC2520 CCA) PTC17
GPIO 3 (CC2520 SFD) PTC16
TX (CC2520 FIFOP) PTC4

Software setup

Here is a corresponding implementation for cc2520_configure_gpios(), it is the same as for a101, but with right GPIO controller name and relevant pins of course.

Note the difference however: Some pins are not muxed the way we need to. Thus we must configure those, _after_ the board's pinmux has been initialisedh

#include <kernel.h>
#include <device.h>
#include <init.h>
#include <pinmux.h>
#include <pinmux/pinmux.h>
#include <pinmux/k64/pinmux.h>

#include <ieee802154/cc2520.h>
#include <gpio.h>

#define CC2520_GPIO_DEV_NAME CONFIG_GPIO_K64_C_DEV_NAME

#define CC2520_GPIO_VREG_EN	12  /* PTC12 */
#define CC2520_GPIO_RESET	3   /* PTC3 */
#define CC2520_GPIO_FIFO	2   /* PTC2 */
#define CC2520_GPIO_CCA		17  /* PTC17 */
#define CC2520_GPIO_SFD		16  /* PTC16 */
#define CC2520_GPIO_FIFOP	4   /* PTC4 */

static struct cc2520_gpio_configuration cc2520_gpios[CC2520_GPIO_IDX_MAX] = {
	{ .dev = NULL, .pin = CC2520_GPIO_VREG_EN, },
	{ .dev = NULL, .pin = CC2520_GPIO_RESET, },
	{ .dev = NULL, .pin = CC2520_GPIO_FIFO, },
	{ .dev = NULL, .pin = CC2520_GPIO_CCA, },
	{ .dev = NULL, .pin = CC2520_GPIO_SFD, },
	{ .dev = NULL, .pin = CC2520_GPIO_FIFOP, },
};

/* CONFIG_PINMUX_INIT_PRIORITY + 1 ! */
#define CC2520_PINMUX_PRIORITY 46

/* PTC<2/3/4> are by default set on GPIO function */
static const struct pin_config cc2520_mux_config[] = {
	{ K64_PIN_PTC12, K64_PINMUX_FUNC_GPIO },
	{ K64_PIN_PTC16, K64_PINMUX_FUNC_GPIO },
	{ K64_PIN_PTC17, K64_PINMUX_FUNC_GPIO },
};

struct cc2520_gpio_configuration *cc2520_configure_gpios(void)
{
	struct device *gpio;
	int i;

	gpio = device_get_binding(CC2520_GPIO_DEV_NAME);
	if (!gpio) {
		return NULL;
	}

	for (i = 0; i < CC2520_GPIO_IDX_MAX; i++) {
		int flags;

		if (i >= 0 && i < CC2520_GPIO_IDX_FIFO) {
			flags = GPIO_DIR_OUT;
		} else if (i < CC2520_GPIO_IDX_SFD) {
			flags = GPIO_DIR_IN;
		} else {
			flags = (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
				 GPIO_INT_ACTIVE_HIGH | GPIO_INT_DEBOUNCE);
		}

		gpio_pin_configure(gpio, cc2520_gpios[i].pin, flags);
		cc2520_gpios[i].dev = gpio;
	}

	return cc2520_gpios;
}

static int fdrm_k64f_cc2520_pinmux_setup(struct device *dev)
{
	int i;

	ARG_UNUSED(dev);

	for (i = 0; i < ARRAY_SIZE(cc2520_mux_config); i++) {
		_fsl_k64_set_pin(cc2520_mux_config[i].pin_num,
				 cc2520_mux_config[i].mode);
	}

	return 0;
}

SYS_INIT(fdrm_k64f_cc2520_pinmux_setup, POST_KERNEL, CC2520_PINMUX_PRIORITY);


And the prj.conf necessary Kconfig options:

CONFIG_GPIO=y
CONFIG_SPI=y
CONFIG_SPI_0=y

CONFIG_TI_CC2520=y
CONFIG_TI_CC2520_AUTO_ACK=y
CONFIG_SYS_LOG_TI_CC2520_LEVEL=1
CONFIG_TI_CC2520_SPI_DRV_NAME="SPI_0"
CONFIG_TI_CC2520_SPI_FREQ=4000000
CONFIG_TI_CC2520_SPI_SLAVE=0

Use case: CC2520 on Hexiwear

Connecting TI CC2520 to Hexiwear Docking Station

Wiring

EM adapter board <-> FRDM-K64F
EM adapter pin Hexiwear Docking Station pin
VDD 3.3V
GND GND
SCLK PTC5/SCK
CS PTC4/CS
MISO PTC7/MISO
MOSI PTC6/MOSI
GPIO A (CC2520 VREG_EN) PTB11
RESET (CC2520 RESET) PTB2
RX (CC2520 FIFO) PTD2
GPIO B (CC2520 CCA) PTD3
GPIO 3 (CC2520 SFD) PTD8
TX (CC2520 FIFOP) PTD9