Skip to content

Commit

Permalink
wip: cc2500 implementation and test app
Browse files Browse the repository at this point in the history
  • Loading branch information
everedero committed Mar 5, 2024
1 parent 5d72b22 commit 83e7e7e
Show file tree
Hide file tree
Showing 9 changed files with 584 additions and 6 deletions.
14 changes: 14 additions & 0 deletions ccapp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#-------------------------------------------------------------------------------
# Zephyr Example Application
#
# Copyright (c) 2021 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
set(SYSCALL_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../include")

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})

project(app LANGUAGES C)

target_sources(app PRIVATE src/main.c)
15 changes: 15 additions & 0 deletions ccapp/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright (c) 2021 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
#
# This file is the application Kconfig entry point. All application Kconfig
# options can be defined here or included via other application Kconfig files.
# You can browse these options using the west targets menuconfig (terminal) or
# guiconfig (GUI).

menu "Zephyr"
source "Kconfig.zephyr"
endmenu

module = APP
module-str = APP
source "subsys/logging/Kconfig.template.log_config"
249 changes: 249 additions & 0 deletions ccapp/README.md

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions ccapp/VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
VERSION_MAJOR = 1
VERSION_MINOR = 0
PATCHLEVEL = 0
VERSION_TWEAK = 0
EXTRAVERSION =
23 changes: 23 additions & 0 deletions ccapp/boards/nucleo_f756zg.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2024 Eve Redero
* SPDX-License-Identifier: Apache-2.0
*/

&spi1 {
pinctrl-0 = <&spi1_sck_pb3 &spi1_miso_pb4 &spi1_mosi_pb5>;
pinctrl-names = "default";
cs-gpios = <&gpioa 4 GPIO_ACTIVE_LOW>;
clock-frequency = <8000000>; // Max 8 Mbps for SPI
status = "okay";

radio0: propy_radio@0 {
reg = <0>;
compatible = "ti,cc2500";
status = "okay";
spi-max-frequency = <500000>; // This really sets frequency
/* From 0x07 to 0x2E */
conf-array = [0A 04 01 00 0A 00 5D 13 B1
2D 3B 73 22 F8 00 07 30 18 1D 1C C7 00 B0 87 6B
F8 B6 10 EA 0A 00 11 41 00 59 7F 3F 88 31 0B];
};
};
14 changes: 14 additions & 0 deletions ccapp/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) 2021 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
#
# This file contains selected Kconfig options for the application.

CONFIG_SPI=y
CONFIG_CC2500=y
CONFIG_CC2500_TRIGGER=y

# logging
CONFIG_LOG=y
CONFIG_APP_LOG_LEVEL_DBG=y
CONFIG_CC2500_LOG_LEVEL_DBG=y
CONFIG_LOG_MODE_IMMEDIATE=y
15 changes: 15 additions & 0 deletions ccapp/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This file is provided so that the application can be compiled using Twister,
# the Zephyr testing tool. In this file, multiple combinations can be specified,
# so that you can easily test all of them locally or in CI.
sample:
description: Example application
name: example-application
common:
build_only: true
integration_platforms:
- nucleo_f756zg
tests:
app.default: {}
app.debug:
extra_overlay_confs:
- debug.conf
41 changes: 41 additions & 0 deletions ccapp/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2024 Eve Redero
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/kernel.h>
#include <zephyr/devicetree.h>

#include <app/drivers/propy_radio.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(main, CONFIG_APP_LOG_LEVEL);
#if !DT_NODE_EXISTS(DT_NODELABEL(radio0))
#error "whoops, node label radio0 not found"
#endif


int main(void)
{
static const struct device *cc2500 = DEVICE_DT_GET(DT_NODELABEL(radio0));
uint8_t data_len = 7;
uint8_t buffer[] = {0x01, 0x00, 0xa5, 0x28, 0x28, 0x00, 0x00};
int i = 0;

if (!device_is_ready(cc2500)) {
LOG_ERR("Sensor not ready");
return 0;
}
LOG_INF("Device ready");
for (i=0; i<20; i++) {
propy_radio_write(cc2500, buffer, data_len);
k_sleep(K_MSEC(20));
}
/*
while (!propy_radio_write(cc2500, buffer, data_len))
{
k_sleep(K_MSEC(10));
}*/

return 0;
}

214 changes: 208 additions & 6 deletions drivers/cc2500/cc2500.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
#include <app/drivers/propy_radio.h>
#include "cc2500_defines.h"

/* Max data fifo len */
#define SPI_MAX_MSG_LEN 64
#define SPI_MAX_REG_LEN 5
#define SPI_MSG_QUEUE_LEN 10

LOG_MODULE_REGISTER(cc2500, CONFIG_CC2500_LOG_LEVEL);

Expand Down Expand Up @@ -111,6 +110,124 @@ uint8_t cc2500_read_register(const struct device *dev, uint8_t reg)
return rx_data[1];
}

uint8_t cc2500_read_status(const struct device *dev)
{
const struct cc2500_config *config = dev->config;
uint8_t tx_data[2];
uint8_t rx_data[2];
int ret;
const struct spi_buf tx_buf[1] = {
{
.buf = tx_data,
.len = 2
}
};
const struct spi_buf rx_buf[1] = {
{
.buf = (void *)rx_data,
.len = 2
}
};
struct spi_buf_set tx = {
.buffers = tx_buf,
.count = 1
};
const struct spi_buf_set rx = {
.buffers = rx_buf,
.count = 1
};

// 5 lower bits for address, the 6th is 0 for read and 1 for write
tx_data[0] = ( READ_SINGLE | ( RW_MASK & 0x00 ) );
tx_data[1] = 0x00;

ret = spi_transceive_dt(&config->spi, &tx, &rx);

if (ret) {
LOG_ERR("Error transceive %d", ret);
return 0;
}

// status is 1st byte of receive buffer
return rx_data[0];
}

uint8_t cc2500_write_register_len(const struct device *dev, uint8_t reg, const uint8_t* data, uint8_t len)
{
const struct cc2500_config *config = dev->config;
uint8_t tx_data[SPI_MAX_MSG_LEN + 1] = {0};
uint8_t rx_data = 0;
int ret;
const struct spi_buf tx_buf[1] = {
{
.buf = tx_data,
.len = (len + 1)
}
};
const struct spi_buf rx_buf[1] = {
{
.buf = &rx_data,
.len = 1
}
};
struct spi_buf_set tx = {
.buffers = tx_buf,
.count = 1
};
const struct spi_buf_set rx = {
.buffers = rx_buf,
.count = 1
};

tx_data[0] = ( WRITE_BURST | ( RW_MASK & reg ) );
memcpy(&tx_data[1], data, len);

ret = spi_transceive_dt(&config->spi, &tx, &rx);
if (ret) {
LOG_ERR("Error transceive %d", ret);
return 0;
}
return rx_data;
}

uint8_t cc2500_cmd_register(const struct device *dev, uint8_t cmd)
{
const struct cc2500_config *config = dev->config;
int ret;
uint8_t tx_data[1];
uint8_t rx_data[1];
const struct spi_buf tx_buf[1] = {
{
.buf = tx_data,
.len = 1
}
};
const struct spi_buf rx_buf[1] = {
{
.buf = rx_data,
.len = 1
}
};
struct spi_buf_set tx = {
.buffers = tx_buf,
.count = 1
};
const struct spi_buf_set rx = {
.buffers = rx_buf,
.count = 1
};

tx_data[0] = cmd;

ret = spi_transceive_dt(&config->spi, &tx, &rx);
if (ret) {
LOG_ERR("Error transceive %d\n", ret);
return 0;
}

return rx_data[0];
}

static int cc2500_set_config_registers(const struct device *dev)
{
int ret = 0;
Expand All @@ -128,19 +245,77 @@ static int cc2500_set_config_registers(const struct device *dev)
return ret;
}

/* API functions */
/* Private driver function */
static uint8_t cc2500_reset(const struct device *dev)
{
return(cc2500_cmd_register(dev, SRES));
}

static uint8_t cc2500_flush_rx(const struct device *dev)
{
return(cc2500_cmd_register(dev, SFRX));
}

static uint8_t cc2500_flush_tx(const struct device *dev)
{
return(cc2500_cmd_register(dev, SFTX));
}

static uint8_t cc2500_idle(const struct device *dev)
{
return(cc2500_cmd_register(dev, SIDLE));
}

static uint8_t cc2500_set_rx(const struct device *dev)
{
return(cc2500_cmd_register(dev, SRX));
}

static uint8_t cc2500_set_tx(const struct device *dev)
{
return(cc2500_cmd_register(dev, STX));
}

static uint8_t cc2500_set_pkt_len(const struct device *dev, int len)
{
return(cc2500_write_register(dev, PKTLEN, len));
}

static void cc2500_write_register_burst(const struct device *dev, uint8_t reg, const uint8_t* data, uint8_t len)
{
/* Packet length +1 because we count the reg byte */
cc2500_set_pkt_len(dev, len+1);
cc2500_write_register_len(dev, reg, data, len);
}

/* API functions */
static int cc2500_read(const struct device *dev, uint8_t *buffer, uint8_t data_len)
{
int ret = 0;
struct cc2500_data *data = dev->data;

return ret;
}

static int cc2500_write(const struct device *dev, uint8_t *buffer, uint8_t data_len)
{
int ret = 0;
struct cc2500_data *data = dev->data;
int status = 0;

cc2500_idle(dev);
cc2500_write_register_burst(dev, TXFIFO, buffer, data_len);
cc2500_set_tx(dev);
status = cc2500_read_status(dev);
LOG_DBG("Status: 0x%x", status);
k_msleep(1);
status = cc2500_read_status(dev);
LOG_DBG("Status: 0x%x", status);

cc2500_flush_tx(dev);
status = cc2500_idle(dev);
LOG_DBG("Status idle: 0x%x", status);
cc2500_set_rx(dev);
status = cc2500_idle(dev);
LOG_DBG("Status idle: 0x%x", status);
return ret;
}

Expand All @@ -153,8 +328,11 @@ static const struct propy_radio_api cc2500_api = {
/* Init */
static int cc2500_init(const struct device *dev)
{
uint8_t pa_data[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const struct cc2500_config *config = dev->config;
struct cc2500_data *data = dev->data;
uint8_t reg_value;
int i;
int ret;

if (!spi_is_ready_dt(&config->spi)) {
Expand All @@ -169,9 +347,33 @@ static int cc2500_init(const struct device *dev)
LOG_ERR("Could not configure CS GPIO (%d)", ret);
return ret;
}

cc2500_reset(dev);
cc2500_set_config_registers(dev);

cc2500_write_register_burst(dev, PATABLE, pa_data, 8);

reg_value = cc2500_read_register(dev, FREQ0);
LOG_DBG("Freq 0: %d", reg_value);

cc2500_write_register(dev, IOCFG2, 0x5C);
cc2500_write_register(dev, IOCFG0, 0x5B);

cc2500_flush_rx(dev);
cc2500_flush_tx(dev);
cc2500_idle(dev);

cc2500_set_rx(dev);

/* Single read */
reg_value = cc2500_read_register(dev, FSCAL1);
LOG_DBG("FS Cal1: %d", reg_value);

for (i=0; i<30; i++) {
reg_value = cc2500_read_register(dev, RSSI);
LOG_DBG("RSSI: %d", reg_value);
k_msleep(1);
}

return 0;
}

Expand Down

0 comments on commit 83e7e7e

Please sign in to comment.