1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

drivers/at86rf231: rework and clean-up

- moved all board specific code to low-level driver calls
- moved some functions from the board dir into at86rf231.c
- added doxygen headers
This commit is contained in:
Hauke Petersen 2014-09-29 20:34:38 +02:00
parent ae066f60d8
commit 4b815582d7
8 changed files with 208 additions and 90 deletions

View File

@ -1,5 +1,4 @@
/*
* at86rf231.c - Implementation of at86rf231 functions.
* Copyright (C) 2013 Alaeddine Weslati <alaeddine.weslati@inria.fr>
*
* This file is subject to the terms and conditions of the GNU Lesser
@ -7,15 +6,12 @@
* directory for more details.
*/
#include "kernel_types.h"
#include "transceiver.h"
/**
* @ingroup drivers_at86rf231
* @{
*
* @file at86rf231.c
* @brief Driver implementation for at86rf231 chip
* @file
* @brief Driver implementation of the AT86RF231 device driver
*
* @author Alaeddine Weslati <alaeddine.weslati@inria.fr>
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
@ -24,8 +20,13 @@
*/
#include "at86rf231.h"
#include "at86rf231_arch.h"
#include "at86rf231_spi.h"
#include "board.h"
#include "periph/gpio.h"
#include "periph/spi.h"
#include "kernel_types.h"
#include "transceiver.h"
#include "vtimer.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
@ -37,6 +38,11 @@ static uint64_t radio_address_long;
uint8_t driver_state;
uint8_t at86rf231_get_status(void);
void at86rf231_gpio_spi_interrupts_init(void);
void at86rf231_reset(void);
void at86rf231_init(kernel_pid_t tpid)
{
transceiver_pid = tpid;
@ -71,7 +77,8 @@ void at86rf231_init(kernel_pid_t tpid)
void at86rf231_switch_to_rx(void)
{
at86rf231_disable_interrupts();
gpio_irq_disable(AT86RF231_INT);
// Send a FORCE TRX OFF command
at86rf231_reg_write(AT86RF231_REG__TRX_STATE, AT86RF231_TRX_STATE__FORCE_TRX_OFF);
@ -82,7 +89,7 @@ void at86rf231_switch_to_rx(void)
at86rf231_reg_read(AT86RF231_REG__IRQ_STATUS);
// Enable IRQ interrupt
at86rf231_enable_interrupts();
gpio_irq_enable(AT86RF231_INT);
// Start RX
at86rf231_reg_write(AT86RF231_REG__TRX_STATE, AT86RF231_TRX_STATE__RX_ON);
@ -104,8 +111,10 @@ void at86rf231_switch_to_rx(void)
while ((status & AT86RF231_TRX_STATUS_MASK__TRX_STATUS) != AT86RF231_TRX_STATUS__RX_ON);
}
void at86rf231_rx_irq(void)
void at86rf231_rx_irq(void *arg)
{
(void)arg;
/* check if we are in sending state */
if (driver_state == AT_DRIVER_STATE_SENDING) {
/* Read IRQ to clear it */
@ -202,3 +211,51 @@ void at86rf231_set_monitor(uint8_t mode)
(void) mode;
// TODO
}
void at86rf231_gpio_spi_interrupts_init(void)
{
/* SPI init */
spi_init_master(AT86RF231_SPI, SPI_CONF_FIRST_RISING, SPI_SPEED_5MHZ);
/* IRQ0 */
gpio_init_int(AT86RF231_INT, GPIO_NOPULL, GPIO_RISING, at86rf231_rx_irq, NULL);
/* CS */
gpio_init_out(AT86RF231_CS, GPIO_NOPULL);
/* SLEEP */
gpio_init_out(AT86RF231_SLEEP, GPIO_NOPULL);
/* RESET */
gpio_init_out(AT86RF231_RESET, GPIO_NOPULL);
}
void at86rf231_reset(void)
{
/* force reset */
gpio_clear(AT86RF231_RESET);
/* put pins to default values */
gpio_set(AT86RF231_CS);
gpio_clear(AT86RF231_SLEEP);
/* additional waiting to comply to min rst pulse width */
uint8_t delay = 50;
while (delay--){}
gpio_set(AT86RF231_RESET);
/* Send a FORCE TRX OFF command */
at86rf231_reg_write(AT86RF231_REG__TRX_STATE, AT86RF231_TRX_STATE__FORCE_TRX_OFF);
/* busy wait for TRX_OFF state */
uint8_t status;
uint8_t max_wait = 100;
do {
status = at86rf231_get_status();
if (!--max_wait) {
printf("at86rf231 : ERROR : could not enter TRX_OFF mode\n");
break;
}
} while ((status & AT86RF231_TRX_STATUS_MASK__TRX_STATUS)
!= AT86RF231_TRX_STATUS__TRX_OFF);
}

View File

@ -6,8 +6,20 @@
* directory for more details.
*/
/**
* @ingroup drivers_at86rf231
* @{
*
* @file
* @brief RX related functionality for the AT86RF231 device driver
*
* @author Alaeddine Weslati <alaeddine.weslati@inria.fr>
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*
* @}
*/
#include "at86rf231.h"
#include "at86rf231_arch.h"
#include "at86rf231_spi.h"
#include "kernel_types.h"

View File

@ -6,68 +6,72 @@
* directory for more details.
*/
/**
* @ingroup drivers_at86rf231
* @{
*
* @file
* @brief Register access functions for the AT86RF231 device driver
*
* @author Alaeddine Weslati <alaeddine.weslati@inria.fr>
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*
* @}
*/
#include "at86rf231_spi.h"
#include "at86rf231_arch.h"
#include "at86rf231.h"
#include "board.h"
#include "periph/spi.h"
#include "periph/gpio.h"
void at86rf231_reg_write(uint8_t addr, uint8_t value)
{
// Start the SPI transfer
at86rf231_spi_select();
// Send first byte being the command and address
at86rf231_spi_transfer_byte(AT86RF231_ACCESS_REG | AT86RF231_ACCESS_WRITE | addr);
// Send value
at86rf231_spi_transfer_byte(value);
// End the SPI transfer
at86rf231_spi_unselect();
/* Start the SPI transfer */
gpio_clear(AT86RF231_CS);
/* write to register */
spi_transfer_reg(AT86RF231_SPI, AT86RF231_ACCESS_REG | AT86RF231_ACCESS_WRITE | addr, value, 0);
/* End the SPI transfer */
gpio_set(AT86RF231_CS);
}
uint8_t at86rf231_reg_read(uint8_t addr)
{
uint8_t value;
char value;
// Start the SPI transfer
at86rf231_spi_select();
// Send first byte being the command and address
at86rf231_spi_transfer_byte(AT86RF231_ACCESS_REG | AT86RF231_ACCESS_READ | addr);
// Send value
value = at86rf231_spi_transfer_byte(0);
// End the SPI transfer
at86rf231_spi_unselect();
return value;
/* Start the SPI transfer */
gpio_clear(AT86RF231_CS);
/* read from register */
spi_transfer_reg(AT86RF231_SPI, AT86RF231_ACCESS_REG | AT86RF231_ACCESS_READ | addr, 0, &value);
/* End the SPI transfer */
gpio_set(AT86RF231_CS);
return (uint8_t)value;
}
void at86rf231_read_fifo(uint8_t *data, radio_packet_length_t length)
{
// Start the SPI transfer
at86rf231_spi_select();
// Send Frame Buffer Write access
at86rf231_spi_transfer_byte(AT86RF231_ACCESS_FRAMEBUFFER | AT86RF231_ACCESS_READ);
at86rf231_spi_transfer(0, data, length);
// End the SPI transfer
at86rf231_spi_unselect();
/* Start the SPI transfer */
gpio_clear(AT86RF231_CS);
/* Read a number of bytes from the devices frame buffer */
spi_transfer_regs(AT86RF231_SPI, AT86RF231_ACCESS_FRAMEBUFFER | AT86RF231_ACCESS_READ,
0, (char*)data, length);
/* End the SPI transfer */
gpio_set(AT86RF231_CS);
}
void at86rf231_write_fifo(const uint8_t *data, radio_packet_length_t length)
{
// Start the SPI transfer
at86rf231_spi_select();
// Send Frame Buffer Write access
at86rf231_spi_transfer_byte(AT86RF231_ACCESS_FRAMEBUFFER | AT86RF231_ACCESS_WRITE);
at86rf231_spi_transfer(data, 0, length);
// End the SPI transfer
at86rf231_spi_unselect();
/* Start the SPI transfer */
gpio_clear(AT86RF231_CS);
/* Send Frame Buffer Write access */
spi_transfer_regs(AT86RF231_SPI, AT86RF231_ACCESS_FRAMEBUFFER | AT86RF231_ACCESS_WRITE,
(char*)data, 0, length);
/* End the SPI transfer */
gpio_set(AT86RF231_CS);
}
uint8_t at86rf231_get_status(void)
{
return at86rf231_reg_read(AT86RF231_REG__TRX_STATUS)
& AT86RF231_TRX_STATUS_MASK__TRX_STATUS;
}

View File

@ -6,9 +6,22 @@
* directory for more details.
*/
/**
* @ingroup drivers_at86rf231
* @{
*
* @file
* @brief RX related functionality for the AT86RF231 device driver
*
* @author Alaeddine Weslati <alaeddine.weslati@inria.fr>
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*
* @}
*/
#include "at86rf231.h"
#include "at86rf231_arch.h"
#include "at86rf231_spi.h"
#include "vtimer.h"
#define ENABLE_DEBUG (0)
#include "debug.h"

View File

@ -1,22 +0,0 @@
#ifndef AT86RF231_ARCH_H_
#define AT86RF231_ARCH_H_
#include <stdint.h>
#include "vtimer.h"
void at86rf231_gpio_spi_interrupts_init(void);
void at86rf231_reset(void);
uint8_t at86rf231_get_status(void);
void at86rf231_spi_select(void);
void at86rf231_spi_unselect(void);
void at86rf231_spi_transfer(const uint8_t *data_out, uint8_t *data_in, radio_packet_length_t length);
uint8_t at86rf231_spi_transfer_byte(uint8_t byte);
void at86rf231_init_interrupts(void);
void at86rf231_enable_interrupts(void);
void at86rf231_disable_interrupts(void);
#endif

View File

@ -1,3 +1,22 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup drivers_at86rf231
* @{
*
* @file
* @brief Register access function definitions for the AT86RF231 device driver
*
* @author Alaeddine Weslati <alaeddine.weslati@inria.fr>
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*/
#ifndef AT86RF231_SPI_H_
#define AT86RF231_SPI_H_
@ -10,4 +29,8 @@ void at86rf231_reg_write(uint8_t addr, uint8_t value);
void at86rf231_read_fifo(uint8_t *data, radio_packet_length_t length);
void at86rf231_write_fifo(const uint8_t *data, radio_packet_length_t length);
#endif
uint8_t at86rf231_get_status(void);
#endif /* AT86RF231_SPI_H_ */
/** @} */

View File

@ -6,6 +6,19 @@
* directory for more details.
*/
/**
* @defgroup drivers_at86rf231
* @ingroup drivers
* @brief Device driver for the Atmel AT86RF231 radio
* @{
*
* @file
* @brief Interface definition for the AT86RF231 device driver
*
* @author Alaeddine Weslati <alaeddine.weslati@inria.fr>
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*/
#ifndef AT86RF231_H_
#define AT86RF231_H_
@ -13,21 +26,20 @@
#include <stdint.h>
#include "kernel_types.h"
#include "board.h"
#include "radio/types.h"
#include "ieee802154_frame.h"
#include "at86rf231/at86rf231_settings.h"
#include "periph/gpio.h"
#define AT86RF231_MAX_PKT_LENGTH 127
#define AT86RF231_MAX_DATA_LENGTH 118
#define AT86RF231_MAX_PKT_LENGTH 127
#define AT86RF231_MAX_DATA_LENGTH 118
/**
* Structure to represent a at86rf231 packet.
*/
typedef struct __attribute__((packed))
typedef struct __attribute__((packed)) /* TODO: do we need the packed here? it leads to an
unaligned pointer -> trouble for M0 systems... */
{
/* @{ */
uint8_t length; /** < the length of the frame of the frame including fcs*/
@ -53,10 +65,10 @@ extern volatile kernel_pid_t transceiver_pid;
extern uint8_t driver_state;
void at86rf231_init(kernel_pid_t tpid);
//void at86rf231_reset(void);
/* void at86rf231_reset(void); */
void at86rf231_rx(void);
void at86rf231_rx_handler(void);
void at86rf231_rx_irq(void);
void at86rf231_rx_irq(void *arg);
int16_t at86rf231_send(at86rf231_packet_t *packet);
@ -84,4 +96,5 @@ enum {
extern at86rf231_packet_t at86rf231_rx_buffer[AT86RF231_RX_BUF_SIZE];
#endif
#endif /* AT86RF231_H_ */
/** @} */

View File

@ -1,3 +1,21 @@
/*
* Copyright (C) 2014 INRIA
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup drivers_at86rf231
* @{
*
* @file
* @brief Register and command definitions for the AT86RF231 radio
*
* @author Alaeddine Weslati <alaeddine.weslati@inria.fr>
*/
#ifndef AT86AT86RF231_SETTINGS_H
#define AT86AT86RF231_SETTINGS_H